Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsGeneralPHPASPPerlColdFusionFlashHTML, CSS, ScriptsBrowsers

Webmaster Forum / Flash / Flash Remoting / February 2004



Tip: Looking for answers? Try searching our database.

ColdFusion MX to DataSet to DataGrid..?

Thread view: 
Enable EMail Alerts  Start New Thread
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
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.