PDA

View Full Version : Ext.data.CFQueryReader v1.2



CutterBl
29 Jul 2009, 2:02 PM
The CFQueryReader (http://extjs.com/forum/showthread.php?t=53271) custom data reader, used for interpretting Adobe ColdFusion's JSON response of a query object, has been updated to support ExtJs 3.x. There is still backwards compatibility for Ext 2.x, and the download includes a small example using Aaron Conran's DirectCFM (http://extjs.com/forum/showthread.php?t=67983) + CFQueryReader + Ext.Direct.

The CFQueryReader project is available for download on RIAForge (http://cfqueryreader.riaforge.org).

azadisaryev
7 Nov 2009, 12:54 AM
any particular reason why cfqueryreader would fail to load data into the grid on windows server 2008?

it works fine on win xp, but on 2k8 the grid appears without any data...
using cfjsonreader instead of cfqueryreader makes the data show up in the grid on 2k8 just fine.

any ideas?

[UPDATE 16-Nov-2009]
apparently, nothing to do with 2k8 server - cfqueryreader does not work with ext js 3.0.3 (yet).

Azadi

zlesko
16 Nov 2009, 5:32 AM
Has anyone tried CFQueryReader with the newest version of Ext, 3.0.3? Had this working great with v3.0.0 and now the stores are not being populated.

Thanks for any ideas...

azadisaryev
16 Nov 2009, 6:26 AM
right you are - it does not work at all...
i guess that was why my friend could not make it work on his win 2k8 server... i was still using ver 3.0.0 when trying to help him solve the issue and kept telling him "it works just fine for me"!

[UPDATE: my friend got his data into the grid when he switched to using cfjsonreader instead of cfqueryreader.]

hmm... strange thing, though: the ext js download i was using said it was 3.0.3, but the files inside were from 3.0.0!

Azadi

CutterBl
17 Nov 2009, 10:14 AM
The recent 3.0.3 update appeared to break CFQueryReader. Detailed analysis, refactor, and testing revealed that an internal method [getJsonAccessor()] of the Ext.data.JsonReader class had been changed [now createAccessor()]. Changes have been made to CFQueryReader to allow for either, dependent upon which is available.

CutterBl
17 Nov 2009, 10:16 AM
BTW, that latest update can be downloaded from the CFQueryReader (http://cfqueryreader.riaforge.org) project page on RIAForge.

azadisaryev
17 Nov 2009, 4:35 PM
Thanks, Steve!

zlesko
17 Nov 2009, 5:22 PM
Thanks! Don't you just love when they do that...

PatJ
8 May 2010, 10:48 PM
BTW, that latest update can be downloaded from the CFQueryReader (http://cfqueryreader.riaforge.org) project page on RIAForge.

I see there haven't been many posts here recently, but I'm new to ExtJS and I've been gutting it out for the past couple of weeks. I have a nice UI built but am having difficulty getting data from CF into the various Ext components - namely the grid (the forms will be next). I have read all the posts here about CFQueryReader and have tried to implement a small test but can't seem to get data loaded. I'm also somewhat new to Firebug and am having difficulty finding information on the JSON data. I know my CFC is working because I have seen the JSON data by calling the method directly through the URL line on the browser and placing a "console.info" call tells me there is no data in the store.

I hate to admit it but I'm also new to message forums so I apologize if I'm not putting things in the right place. Any help in this area is certainly appreciated and would help me in moving along with our project. I'm sure the fix is simple - I keep thinking it is the URL path - but I have tried a full http:\\ specification as well and still no results. I'm posting my code below - I wasn't able to upload the file. Hopefully someone can enlighten me!!

Thanks,
Pat

CFQueryReader v1.2
ExtJS v.3.2.1
CF8


var myDataModel = [
{ name: 'Title Number', mapping: 'TitleID'},
{ name: 'Title', mapping: 'TITLE' }
];

var myCFReader = new Ext.data.CFQueryReader({id:'TitleID'},myDataModel);

var store = new Ext.data.Store({
url: '/myroot/cfc/test.cfc',
baseParams: { method: 'gettitles', returnformat: 'JSON'},
fields: myDataModel,
reader: myCFReader,
sortInfo:{field:'TitleID', direction:'ASC'}
});

console.info('Store count = ', store.getCount());

CutterBl
10 May 2010, 5:04 AM
Can you paste in a copy of your JSON return? On the Console tab in Firebug you should see a line where the Ajax request is being made. You can expand that line item (the plus sign icon on the left) and be able to view the response on one of the tabs.

A few things I notice, looking at your example scripts:
You don't need the 'fields' config option in your Store, as it is already defined in your reader
If you're using the latest version of CFQueryReader, you don't have to capitalize your 'mapping' options
You have a space in 'Title Number'. You can use spaces in 'header' configs on ColumnModels, but not in your field config. This is technically an 'id' for the field within a Record object.

PatJ
10 May 2010, 11:47 AM
Thanks for responding. I made the changes you suggested. Results are the same. I looked at the JSON output again and I noticed that there are several NULL fields attached to the end of it. I didn't notice that before. I'm not able to use the file upload manager, possibly because I'm behind a firewall? Anyway, I am pasting all three files: test.cfm, test.cfc, and test3.js for your review:


---------------------------------------------------
JSON output from test2.cfm

{"TOTALROWCOUNT":12,"QUERY":{"COLUMNS":["WADID","TITLE"],"DATA":[[45000,"Adding instrumentations to monitor flowrate, temperatures and KW readings of the new 700 HP compressor "],[45001,"Remove tombstone & install new wall receptacle"],[45002,"Upgrade Refrigerant Storage Systems "],[45003,"E267 Install Burglar Bars on West Wendow outside of fence "],[45004,"Install Backup Generator for Child Care Center "],[45005,"Perform design for Third Street\/P. Lot C-3 paving "],[45006,"Install Electrical Power EOC - Room 3118 "],[45007,"Clean and Touch-Up Paint Chamber A 40 Ft Door"],[45009,"Conference Room Upgrade "],[45010,"Install Sound Soak & Chairs Rails on Walls of Video Lab and Classroomss"],[45011,"Add 20 AMP power to B1\/378 for redundant router installation "],[47072,"ReRoof Building 48 "],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null],[null,null]]}}

Here is the output from Firebug:

Store count = 0
b is null



---------------------------------------------------
test2.cfm

<html>
<head>
<title>test page 2</title>
<cfinclude template="_css_jslibs.cfm">
<script type="text/javascript" src="ext/CFQueryReader/js/custom/CFQueryReader.js"></script>
<script type="text/javascript" src="ext/examples/ux/PanelResizer.js"></script>
<script type="text/javascript" src="ext/examples/ux/SlidingPager.js"></script>
<script type="text/javascript" src="js/ext/test3.js"></script>
</head>
<body>
<cfoutput>
<cfinvoke component="cfcs.test" method="getwads" returnVariable="wadlist" page="1" pagesize="50" />

#SerializeJSON(wadlist)#
<div id="gridtest"></div>
</cfoutput>
</body>
</html>

---------------------------------------------------
NOTE: the _css_jslibs.cfm file noted above includes the other ExtJS libraries:
<link href="css/wadapp.css" rel="stylesheet" type="text/css" />
<link href="css/wadmenu.css" rel="stylesheet" type="text/css" />

<script src="js/common.js" type="text/javascript"></script>
<script src="js/sort_it.js" type="text/javascript"></script>
<script src="js/xpath.js" type="text/javascript"></script>
<!--- ExtJS calls --->
<!--- these are required to be in the library as provided, do not re-locate --->
<!-- CSS base library -->
<link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css" />
<!-- overrides to CSS base library --->
<link rel="stylesheet" type="text/css" href="ext/examples/ux/css/Portal.css" />
<link rel="stylesheet" type="text/css" href="ext/examples/menu/menus.css" />
<link rel="stylesheet" type="text/css" href="ext/examples/shared/examples.css" />
<!--- <link rel="stylesheet" type="text/css" href="css/ext/tabs-example.css" /> --->
<!-- ExtJS library: base/adapter -->
<script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>
<!-- ExtJS library: all widgets -->
<script type="text/javascript" src="ext/ext-all.js"></script>

<!-- overrides to base library -->
<!-- extensions -->
<script type="text/javascript" src="ext/examples/ux/Portal.js"></script>
<script type="text/javascript" src="ext/examples/ux/PortalColumn.js"></script>
<script type="text/javascript" src="ext/examples/ux/Portlet.js"></script>
<script type="text/javascript" src="ext/examples/shared/examples.js"></script>
<!--- <script type="text/javascript" src="ext/examples/ux/TableGrid.js"></script> --->
---------------------------------------------------

test.cfc

<cfcomponent>
<cffunction name="getwads" access="remote" output="false" returntype="any" returnformat="JSON">
<cfargument name="page" type="numeric" required="yes">
<cfargument name="pageSize" type="numeric" required="yes">
<cfargument name="gridsortcolumn" type="string" required="no" default="">
<cfargument name="gridsortdir" type="string" required="no" default="">

<cfquery name="getwads" datasource="#request.dsn#">
SELECT wadid, title
FROM db_wad
</cfquery>

<cfreturn QueryConvertForGrid(getwads, page, pageSize) />
<!--- <cfreturn getwads /> --->
</cffunction>

</cfcomponent>
---------------------------------------------------

test3.js

Ext.onReady(function(){
var myDataModel = [
{ name: 'WADID', mapping: 'wadID', type: 'int' },
{ name: 'TITLE', mapping: 'Title', type: 'string' }
];
var myCFReader = new Ext.data.CFQueryReader({id:'WADID'},myDataModel);
var store = new Ext.data.Store({
totalProperty: 'DATASET',
root:'ROWS',
proxy:new Ext.data.HttpProxy({
method:'POST',
url:'../../cfcs/test.cfc?method=getwads' (http://www.extjs.com/forum/'../../cfcs/test.cfc?method=getwads')
}),
id:'WADID',
successProperty: 'SUCCESS',
remoteSort:true,
baseParams: { returnformat: 'JSON', start: '1', limit: '50'},
reader: myCFReader
});

console.info('Store count = ', store.getCount());

var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{id:'WADID',header: "WAD Number", width: 160, sortable: true, dataIndex: 'wadid'},
{header: "Title", width: 75, sortable: true, dataIndex: 'title'}
],
stripeRows: true,
autoExpandColumn: 'title',
height:320,
width:600,
frame:true,
title:'Sliding Pager',

plugins: new Ext.ux.PanelResizer({
minHeight: 100
}),

bbar: new Ext.PagingToolbar({
pageSize: 10,
store: store,
displayInfo: true,

plugins: new Ext.ux.SlidingPager()
})
});

grid.render('mygrid');

store.load();

});

CutterBl
11 May 2010, 7:35 AM
Your JSON return is your problem. It expects your id field to be an int value, and bombs when finding those records with a 'null' value. Somehow you'll have to filter (at the SQL level) to only return records with value:


SELECT wadid,
title
FROM db_wad
WHERE wadid IS NOT NULL

PatJ
14 May 2010, 11:51 AM
Thanks for the response. After I posted the last message I realized the additional NULLS were coming from "baseParams: { returnformat: 'JSON', start: '1', limit: '50'},". I didn't have 50 records only 12 (at the time). So I changed "start" to "page" and "limit" to "pageSize" which is the argument names in the cfc and changed the pageSize value to 5. We now have 15 records and the JSON return looks like this - returning the 5 records instead of all 15:

{"TOTALROWCOUNT":15,"QUERY":{"COLUMNS":["WADID","TITLE"],"DATA":[[45000,"Adding instrumentations to monitor flowrate, temperatures and KW readings of the new 700 HP compressor "],[45001,"Remove tombstone & install new wall receptacle"],[45002,"Upgrade Refrigerant Storage Systems "],[45003,"E267 Install Burglar Bars on West Wendow outside of fence "],[45004,"Install Backup Generator for Child Care Center "]]}}

The wadid field from the database is an "int" value. The store still does not load. I know the error I'm receiving is from the grid because there are no records in the store. I removed the call to the grid and I have no errors now - just store count = 0. I was also under the impression from reading CF documentation that you shouldn't have to send the "page" and "pageSize" parameters that these values are determined behind the scenes. I get the same "store count = 0" when I change the cfc to return a straight query using baseParams: { returnformat: 'JSON'},

I may have to abandon the ExtJS framework idea for our application because another issue that I wasn't thinking about when I started down this path is whether the application as I've developed it so far is 508 compatible. I'm waiting for some folks to do a test run on it and see where I stand.

If you can see any other issue as to why the store is not loading I'd appreciate some feedback!
Thanks,
Pat

CutterBl
14 May 2010, 12:43 PM
508 compliance requires some additional coding on your part ARIA support. See the "Accessibility" Demos on the Samples & Demos (http://www.extjs.com/deploy/dev/examples/) page.

I'm also trying to rectify your Store and Reader configuration with the data you're showing in your JSON return, and they don't jive. First, you identify your totalProperty as "DATASET", but you're JSON return shows it as "TOTALROWCOUNT". Second, you identify your root as "ROWS", when the root in your JSON return is "QUERY" (which should be automatically recognized without defining the root attribute with CFQueryReader). Finally, the case of your dataIndex attributes, in your ColumnModel, must match up with the name attributes of your field definition list, so if the 'name' of the field is defined as "WADID", then the 'dataIndex' of that column should also be "WADID".

Side Note: Unless that cfc is on another server you should be able to use just the 'url' attribute of the store, without defining a proxy.

CutterBl
14 May 2010, 12:46 PM
Oh yeah, and you shouldn't put your paging stuff in the baseParams, but rather within the load() method itself:


store.load({params:{start:0, limit:25}});

You'll have to change the argument names in the cfc function, as Ext will automatically use these param names for the paging stuff.

PatJ
19 May 2010, 6:58 AM
Thanks for the input. I apologize for being so clueless about this but I have tried everything I can and I just can't seem to get this to work. At this point I have no clue what I'm doing. Maybe I've read too many online forums and I'm just totally confused. I'm working this issue on my own time and I need to move on if I can't get it working. I've tried to simplify it down even more - maybe too simple? I keep thinking the URL path is the problem - it simply can't find my CFC, although I've tried moving the JS file to the root level and changing the URL path. Here is my file structure:
Root level> test2.cfm
Root level > cfcs > test.cfc
Root level > js > ext > test3.js
I placed comments in the test3.js file shown below. At this point I simply want to see some data in the store via Firebug, so I removed the call to the grid. Is there some place in Firebug to determine if the CFC is actually called. I've looked everywhere in Firebug and can't seem to find anything that is related to what I'm looking for. How do I know the CFQueryReader is functioning properly? How do I know that it found my CFC? I hate to give up but must move on.
Thanks,
Pat
<< test2.cfm >>
<html>
<head>
<title>test page 2</title>
<cfinclude template="_css_jslibs.cfm">
<script type="text/javascript" src="ext/CFQueryReader/js/custom/CFQueryReader.js"></script>
<script type="text/javascript" src="ext/examples/ux/PanelResizer.js"></script>
<script type="text/javascript" src="ext/examples/ux/SlidingPager.js"></script>
<script type="text/javascript" src="ext/src/widgets/grid/ColumnModel.js"></script>
<script type="text/javascript" src="test3.js"></script>
</head>
<body>
<cfoutput>

</cfoutput>
</body>
</html>
<< test.cfc >> I have both query and grid return functions, I've tried using both.
<cfcomponent>
<cffunction name="getwads" access="remote" output="true" returntype="any" returnformat="JSON">
<cfargument name="page" type="numeric" required="yes">
<cfargument name="pageSize" type="numeric" required="yes">
<cfargument name="gridsortcolumn" type="string" required="no" default="">
<cfargument name="gridsortdirection" type="string" required="no" default="">
<cfquery name="getwads" datasource="#request.dsn#">
SELECT wadid, title
FROM db_wad
</cfquery>

<cfreturn QueryConvertForGrid(getwads, page, pageSize) />
</cffunction>

<cffunction name="getwads2" access="remote" output="true" returntype="any" returnformat="JSON">
<cfquery name="getwads" datasource="#request.dsn#">
SELECT wadid, title
FROM db_wad
</cfquery>
<cfreturn getwads />
</cffunction>

</cfcomponent>
<< test3.js >>
Ext.onReady(function(){
var myDataModel = [
{name: 'WADID', mapping: 'WADID'},
{name: 'TITLE', mapping: 'TITLE'}
];
var myCFReader = new Ext.data.CFQueryReader({id:'WADID'},myDataModel);
var store = new Ext.data.Store({
totalProperty: 'TOTALROWCOUNT',
root: 'QUERY',
// these comments are not in the actual test3.js file
// the url is currently defined from the root, if defined from the js directory
// it would be '../../cfcs/test.cfc?method=getwads'
url:'cfcs/test.cfc?method=getwads' (http://www.extjs.com/forum/'cfcs/test.cfc?method=getwads'),
id:'WADID',
successProperty: 'SUCCESS',
remoteSort:true,
baseParams: { returnformat: 'JSON'},
reader: myCFReader
});
store.load({params:{page:1, pageSize:16}});
console.info('Store count = ', store.getCount());

});
Lastly here is the JSON output for both functions in test.cfc; I used the following program to display this:
<html>
<head>
<title>Test 1</title>
<cfinclude template="_css_jslibsCF.cfm">
</head>
<body>
<cfoutput>
<cfinvoke component="cfcs.test" method="getwads" returnVariable="wadlist" page="1" pageSize="16" />
#SerializeJSON(wadlist)#
<br /><br />
<cfinvoke component="cfcs.test" method="getwads2" returnVariable="wadlist" />
#SerializeJSON(wadlist)#
</cfoutput>
</body>
</html>
JSON output for the above program >>
{"TOTALROWCOUNT":16,"QUERY":{"COLUMNS":["WADID","TITLE"],"DATA":[[45000,"Adding instrumentations to monitor flowrate, temperatures and KW readings of the new 700 HP compressor "],[45001,"Remove tombstone & install new wall receptacle"],[45002,"Upgrade Refrigerant Storage Systems "],[45003,"E267 Install Burglar Bars on West Wendow outside of fence "],[45004,"Install Backup Generator for Child Care Center "],[45005,"Perform design for Third Street\/P. Lot C-3 paving "],[45006,"Install Electrical Power EOC - Room 3118 "],[45007,"Clean and Touch-Up Paint Chamber A 40 Ft Door"],[45009,"Conference Room Upgrade "],[45010,"Install Sound Soak & Chairs Rails on Walls of Video Lab and Classroomss"],[45011,"Add 20 AMP power to B1\/378 for redundant router installation "],[47072,"ReRoof Building 48 "],[47073,""],[47074,""],[47075,""],[47076,""]]}}
{"COLUMNS":["WADID","TITLE"],"DATA":[[45000,"Adding instrumentations to monitor flowrate, temperatures and KW readings of the new 700 HP compressor "],[45001,"Remove tombstone & install new wall receptacle"],[45002,"Upgrade Refrigerant Storage Systems "],[45003,"E267 Install Burglar Bars on West Wendow outside of fence "],[45004,"Install Backup Generator for Child Care Center "],[45005,"Perform design for Third Street\/P. Lot C-3 paving "],[45006,"Install Electrical Power EOC - Room 3118 "],[45007,"Clean and Touch-Up Paint Chamber A 40 Ft Door"],[45009,"Conference Room Upgrade "],[45010,"Install Sound Soak & Chairs Rails on Walls of Video Lab and Classroomss"],[45011,"Add 20 AMP power to B1\/378 for redundant router installation "],[47072,"ReRoof Building 48 "],[47073,""],[47074,""],[47075,""],[47076,""]]}

PatJ
19 May 2010, 9:20 AM
I have just discovered in Firebug the "XHR" tab and have viewed the POST "test.cfc" response and I see the properly formatted JSON output. This is the JSON directly from Firebug:

{"TOTALROWCOUNT":16,"QUERY":{"COLUMNS":["WADID","TITLE"],"DATA":[[45000,"Adding instrumentations to monitor flowrate, temperatures and KW readings of the new 700 HP compressor "],[45001,"Remove tombstone & install new wall receptacle"],[45002,"Upgrade Refrigerant Storage Systems "],[45003,"E267 Install Burglar Bars on West Wendow outside of fence "],[45004,"Install Backup Generator for Child Care Center "],[45005,"Perform design for Third Street\/P. Lot C-3 paving "],[45006,"Install Electrical Power EOC - Room 3118 "],[45007,"Clean and Touch-Up Paint Chamber A 40 Ft Door"],[45009,"Conference Room Upgrade "],[45010,"Install Sound Soak & Chairs Rails on Walls of Video Lab and Classroomss"],[45011,"Add 20 AMP power to B1\/378 for redundant router installation "],[47072,"ReRoof Building 48 "],[47073,""],[47074,""],[47075,""],[47076,""]]}}

This is params info directly from Firebug (from the POST tab):
page=1&pageSize=16&returnformat=JSON

I guess this tells me that test3.js is finding and executing the CFC properly. I guess the question now is why isn't it loading into the store? I feel like I'm so close!!

PatJ
21 May 2010, 9:11 AM
I have it working now. It took an "autoLoad: true" inside the store to make it work. I don't know why trying to load the store outside the declaration doesn't work. Here is the store definition that works:
var store = new Ext.data.Store({
totalProperty: 'TOTALROWCOUNT',
root: 'QUERY',
url:'cfcs/test.cfc?method=getwads' (http://www.extjs.com/forum/'cfcs/test.cfc?method=getwads'),
id:'WADID',
successProperty: 'SUCCESS',
remoteSort:false,
baseParams: { returnformat: 'JSON'},
reader: myCFReader,
autoLoad: true,
id:'myStore',
listeners: {
load: function(store, records, options) {
console.info('store load, arguments:',arguments);
console.info('Store count = ',store.getCount());
}
}
});
Adding the listners helped me see what was happening. I found this code in digging around different forums. Maybe at some point someone can offer an explanation as to why loading the store outside the store definition didn't work. Thanks for the help!
Pat