ColdFusion MX to DataSet to DataGrid..?
|
|
Thread rating:  |
Rowan - 02 Nov 2003 22:45 GMT Good day,
I have been struggling with this for some time now.. I would like to call a CFC, bind the results to a DataSet and then use the DataSet to populate a DataGrid,
I now how to bind the record set directly to the DataGrid, but this includes all the fields that are returned by the CFC. Instead of writing a different CFC for each of the of views I would like to use, I was hoping to use data binding and only bind the fields I wish to use from the DataSet..
Is this possible, and if so, how would it be done?
Ned01 - 04 Nov 2003 15:03 GMT Yes, it can be done. I took the following approach with Flash 2004 pro. ...
1. Use Flash remoting to access remote CFCs..
2. Create datagrid and dataset on the client form.
3. Within the dataset component inspector, add schema entries for each recordset field you want to view. Be careful -- references are case sensitive.
4. Within the dataset component inspector, bind the dataset.dataProvider to the the grid.dataProvider. and the dataset.selectedIndex to the grid.selectedIndex.
5. Using Actionscript, set up your grid attributes -- set grid.columnNames equal to the exact same fields you itemized in step 3. You can also set other properties such as grid.headerText and grid.width.
Since I was doing this for several record sets, I implemented a gridDataSet class which I instantiated for each grid.... This makes it easy to define and to control the datagrid ...
Object instantiation code... ===================
// set up BGGds dataset and the dataGrid on the BGG form... var BGGdef_ar:Array = new Array(); BGGdef_ar.columns = ["bgProdPlat", "intBGGoalID", "strBGGoalName", "strBGGoalComment"]; BGGdef_ar.headers = ["Product Programs", "ID", "Goal", "Description or Comment"]; BGGdef_ar.widths = [150, 25, 100, 275]; var BGGDataSet = new gridDataSet(BGG, BGG_ds, BGGdef_ar);
Class definition... ============
// DataGridSupport Class v0.2 -- uses actionscript 2.0 // by Ned Asam, October 2003 // // This class facilitates the use of data grids with Flash remoting // and Cold Fusion CFCs.
class gridDataSet { var DataForm:Object; // target form var DG:Object; // target datagrid var DGds:Object; // target dataset var DGdef:Array; // defines grid columns var DGdelta:Array; // var DGedit_ysn:Boolean = false; var DGqry_rs:RecordSet; // Data captured from query function gridDataSet(curForm, curDGds, curDGdef) { this.DGedit_ysn = false; this.DataForm = curForm; this.DG = DataForm.Data_grid; this.DGds = curDGds; this.DGdef = curDGdef; this.DG.editable = false; this.DG.sortableColumns = false; this.DG.columnNames = this.DGdef.columns; for (var i = 0; i<this.DGdef.columns.length; i++) { this.DG.getColumnAt(i).headerText = DGdef.headers; this.DG.getColumnAt(i).width = DGdef.widths; } } function setDataSet(qryRecordSet) { this.DGqry_rs = qryRecordSet; this.DGds.dataProvider = this.DGqry_rs; } function setEditMode() { this.DGedit_ysn = true; this.DG.editable = true; this.DataForm.EditAbort_btn.label = "Abort"; this.DataForm.NewUpdate_btn.label = "Update"; this.DataForm.Delete_btn._visible = true; this.DataForm.Delete_btn.enabled = true; } function clearEditMode() { this.DGedit_ysn = false; this.DG.editable = false; this.DataForm.EditAbort_btn.label = "Edit"; this.DataForm.NewUpdate_btn.label = "New"; this.DataForm.Delete_btn._visible = false; this.DataForm.Delete_btn.enabled = false; } // ... other functions... }
The constructor function defines the datagrid at the time it is instantiated, and the setDataSet(qryRecordSet) is called from the cfc query _Result function.
I hope this helps... Let me know if you discover andy improvements...
I am now working on a way to do the cfc updates without dealing with XML...
Regards,
Ned
Rowan - 04 Nov 2003 17:38 GMT Hmmm, I am still having a tough time with this... And I think it has to do with your step three...
3. Within the dataset component inspector, add schema entries for each recordset field you want to view. Be careful -- references are case sensitive.
By default, when I drag a DataSet component onto my stage, and inspect the Schema for for it, the dataProvider option is set to Array and I can only enter one of the field name being returned. If I set it to complex, then I can enter all the field names... Is this correct?
Furthermore, when things to appear in the DG, there is an extra column on the left, called _ID_ .... all set to zero ( 0 ). What is this?
Lastly, how do I use the CLASS code that is contained in your example? Where is it placed within my AS?
I have also made a few assumptions based on your code:
1) Your dataGrid component is called DG 2) Your DataSet component is called DGds 3) These items are on a form ( screen ) called BGG
Thanks for your help...
Ned01 - 04 Nov 2003 19:03 GMT Rowan,
You are getting close.
Regarding item 3, use the large + sign and add the desired fields at the top level (not under the dataprovider structure). Don't change the data type of the dataProvider. I know this is counter intuitive, but this is the way I obseved it working in other examples. It works fine in my application.
Then set up the datagrid mapping and datagrid.columnNames (steps 4 and 5). You can do this with inline code in frame 1, level 1. You should see the desired field names as headers.
Then set the headerText, column width etc. and you are all set.
If you want to implement a class, as I did, the class definition would be saved in a ".as" file which you would have to import into your application. Then you can instantiate as many objects as you need. This is all documented in the user guide under the section on OOP in Action Script 2.
By the way, your assumptions are correct...
Good Luck..
Ned
Rowan Prior - 05 Nov 2003 00:51 GMT As the Macromedia site is playing up, I am replying here....
Well, I finally have it working, but there is a problem. Please check out the attached URL to see what I mean .. You don't need a username or password to enter the site, simply press the login button...
http://greatplains.novations.com/Novations.html
The problem I am seeing is with the two dataGrid components. When I select an item in the left Datagrid by clicking it, all the other items are selected when you mouse over them. This is not what I was expecting nor what I wanted.
The right dataGrid on the other hand demonstrates another problem.. You can't select anything...
Do you know what is causing these problems?
> Rowan, > > You are getting close. > > Regarding item 3, use the large + sign and add the desired fields at the top level (not under the dataprovider structure). Don't change the data type of the dataProvider. I know this is counter intuitive, but this is the way I obseved it working in other examples. It works fine in my application.
> Then set up the datagrid mapping and datagrid.columnNames (steps 4 and 5). You can do this with inline code in frame 1, level 1. You should see the desired field names as headers.
> Then set the headerText, column width etc. and you are all set. > > If you want to implement a class, as I did, the class definition would be saved in a ".as" file which you would have to import into your application. Then you can instantiate as many objects as you need. This is all documented in the user guide under the section on OOP in Action Script 2.
> By the way, your assumptions are correct... > > Good Luck.. > > Ned Ned01 - 05 Nov 2003 03:58 GMT Good, You are getting closer. Make sure the dataset mapping parameters are set for what you really want. Possibly, set the dataset.dataprovider as out, and the selectedIndex as in/out. You are on the right track...
Regards,
Ned
Rowan - 06 Nov 2003 02:10 GMT Well, it is with good news that I announce that I finally have this working!
Take a look at the end result .. well, not quiet the end as it is only 20% complete.. but this is part of it!
http://greatplains.novations.com/Novations.html
Thanks for all your help...
Rowan - 06 Nov 2003 16:02 GMT Oops, it guess if you want to see my site, you will need a username and password .. well, for now, you can use 'admin' with no password ... your comments and feedback are most welcome...
Referring URLs http://greatplains.novations.com/Novations.html
weeble - 16 Feb 2004 09:51 GMT Hi Rowan Just taken a look at your site and it's very similar t one that I'm trying to produce at the moment I wonder if you could give me some hint as to how you tied the loading progress bar to the loading of the data file.
I've been unable to fathom this bit
Mik
Rowan - 16 Feb 2004 19:10 GMT Okay.. here is a simple example
Place this AS on the first frame of your movie
#include "NetServices.as
theWatch = new Object() theWatch.modelChanged = function(info) trace("The Event is : "+info.eventName) if(info.eventName == "allRows") pBar.setProgress(_root.totalItems, _root.totalItems) _level0.InvProgress.text = "Done" trace("all rows Done"); unloadMovie("_root.pBar") myDataSet.dataProvider = _root.Global_recordSet }else{ // We are still receiving data .. _root.InvProgress.text = "Receiving " + info.firstRow + " of " + _root.totalItems pBar.setProgress(info.lastRow, _root.totalItems) }
Add_ProgressBar = function() _level0.attachMovie("ProgressBar","pBar", 9999) pBar.labelPlacement="bottom" pBar.mode="manual" pBar._x = 100 pBar._y = 100 pBar._width = 300 pBar.setMaximum(_root.totalItems) pBar.setDisplayText(false) }
getData = function() }
getData.prototype.onResult = function(myResults) // Assign the returned recordset to a global variabl _root.Global_recordSet = myResults _root.totalItems = Global_recordSet.getLength()-1 Add_ProgressBar() _root.Global_recordSet.addView(theWatch) _root.Global_recordSet.setDeliveryMode("fetchall") trace("We have some data") }
// Start everything going ... You will need to change this code to reflect your setup .. // gateway service, cfc name etc.... trace("Setting up connection") NetServices.setDefaultGatewayUrl("Your flash gateway service here") gatewayConnection = NetServices.createGatewayConnection() trace("Making call") getDataServerCall = gatewayConnection.getService("cfc.example", new getData()) getDataServerCall.getData()
Then, follow this 1) Drag the Progress Bar component onto the stage and delete i -- this adds it to your library so it can be attached via A 2) Drag the DataSet component onto the stag -- name it myDataSet ( or change the name to your liking, just remeber to change the above code! 3) Drag the dataGrid component onto the stag -- name it myDataGri 4) Click on the dataSet component ( the one on the stage ), to select i Using the Component inspector, add the fields that are being returned from the CFC using the BIG + butto Make sure they match 100% .. case, spelling etc... 5) Click on the dataGrid ( the one the stage ), to select i Using the Component Inspector, click BINDINGS and bind the dataProvider of the dataGrid to the dataProvider of the dataSet.
Thats it! I hope you get it working...
Rowan - 16 Feb 2004 19:29 GMT I guess I should have also included the CFC .. as there is one very important peice of information contained within the CFC
You have to download your records in pages. Otherwise the example will not work
<cfcomponent <cfset FLASH.pagesize = 10> <!--- THIS IS VERY IMPORTANT --- <cffunction name="getData" access="remote" returntype="query" <cfquery name="ReturnData" datasource="NOJHA" SELECT dbo.RM00101.CUSTNMBR, dbo.RM00101.CUSTNAME, dbo.RM00101.CNTCPRS FROM dbo.RM00101 Order By dbo.RM00101.CUSTNMB </cfquery <cfreturn ReturnData </cffunction </cfcomponent
weeble - 16 Feb 2004 20:25 GMT Wow! Thanks for this Rowan, there's more to it than I anticipated. I'll try to adapt it tomorrow and let you know how I get on. Thanks... mike
weeble - 22 Feb 2004 19:04 GMT Hi Rowan, Just a quick update. I've spent several hours analysing your code and I understand the majority of it. However, when I come to translating it to my own example I get a problem with your line: <getDataServerCall = gatewayConnection.getService("cfc.example", new getData());> It stops my code from working properly.... i.e. I get no records passed into my resordset. I think the problem is with the responder "new getData()" -- I've also not seen this way of assigning a responder object in any other examples I've looked at. But, I'll persevere, after all it works very well on your page.
Thanks.... mike
|
|
|