PDA

View Full Version : Learning EXT JS Editable Grid Error



StevenInc
25 Jul 2009, 6:15 PM
I am further along in recreating the lessons of editable Grid in Chapter 6.
I have been successful with the update and delete methods in the data grid. But Inserting is a problem:

Specifically: The insert grid.getStore().insert() does work, But when I attempt update one of the new cells, The update sends back an EXT JS generated ID instead of the one I read back from the database insert query.

Here is the code:

The data store:


var users = Ext.data.Record.create([
'ID',
'COVERTHUMB',
'TITLE',
'DIRECTOR',
{name: 'RELEASED', type: 'date'},
'GENRE',
'GENREID',
'TAGLINE',
{name: 'PRICE', type: 'float'},
{name: 'AVAILABLE', type: 'bool'}
]);



// create the Data Store
var store = new Ext.data.JsonStore({
root:'ROWS',
id:'ID',
url:'getMovies.cfc',
remoteSort:true,
baseParams:{method: 'getAllMovies',returnFormat: 'JSON',start: '1',limit: '50'},
fields:users,
listeners: {
load:{fn: testStore},
loadexception: {fn: loadFailedReport}
}
});

And this is the insert routine:



{
text: 'Add Movie (First)',
icon: 'images/table_add.png',
cls: 'x-btn-text-icon',
handler: function() {


var conn = new Ext.data.Connection();
conn.request({
url: 'crud_movies.cfc',
params: {method: 'insertMovie',title:'New Movie'},
success: function(resp,opt) {
var insert_id = Ext.util.JSON.decode(resp.responseText).ROWS[0].INSERT_ID;
grid.getStore().insert(0, new users({ID:insert_id,TITLE:'New Movie',DIRECTOR:'',GENREID:0,TAGLINE:''}));
},
failure: function(resp,opt) {
Ext.Msg.alert('Error','Unable to add movie');
}
});//handler
}
}
The insertMovie method to my server successfully Inserts Into the table and returns the new ID (int) The ID is also successfully passed back in the responseText.

In fact the correct ID appears in the ID column in the new row.

The problem is when the update method is called on any of the cells in the new row(s)
The ID that is passed is client side generated. for example:


UPDATE chapter6_movies
SET TITLE = 'New Movie2'
WHERE ID = ext-record-4
The update code and the grid looks like this:



var grid = new Ext.grid.EditorGridPanel({
renderTo: document.body,
frame:true,
title: 'Movie Database',
height:200,
width:520,
clicksToEdit: 1,
store: store,
columns: [
{header: "ID", dataIndex: 'ID'},
{header: "Title", dataIndex: 'TITLE', editor: title_edit},
{header: "Director", dataIndex: 'DIRECTOR', editor: director_edit},
{header: "Released", dataIndex: 'RELEASED', renderer: Ext.util.Format.dateRenderer('m/d/y'), editor:release_edit },
{header: "Genre", dataIndex: 'GENREID', editor:genre_edit, renderer: getGenreNameByID},
{header: "Tagline", dataIndex: 'TAGLINE', editor: tagline_edit}
],

listeners: {
afteredit: function(e){
var conn = new Ext.data.Connection();
conn.request({
url: 'crud_movies.cfc',
params: {
method: 'updateMovieByID',
id: e.record.id,
field: e.field,
value: e.value,
row: e.row
},
success: function(resp,opt) {
e.record.commit();
},
failure: function(resp,opt) {
e.record.reject();
Ext.Msg.alert('Database Error', 'Please call the Sweedish Bekini team for help.');
}
});
Thank you

Animal
25 Jul 2009, 10:49 PM
http://extjs.com/deploy/dev/docs/?class=Ext.data.Record&member=Record

Pass your ID.

StevenInc
26 Jul 2009, 2:53 AM
I thought I was already doing that here:



var insert_id = Ext.util.JSON.decode(resp.responseText).ROWS[0].INSERT_ID;
grid.getStore().insert(0, new users({ID:insert_id,TITLE:'New Movie',DIRECTOR:'',GENREID:0,TAGLINE:''}));ID was established as my ID in the data store.



var store = new Ext.data.JsonStore({
root:'ROWS',
id:'ID',
url:'getMovies.cfc',
remoteSort:true,
baseParams:{method: 'getAllMovies',returnFormat: 'JSON',start: '1',limit: '50'},
fields:users,
listeners: {
load:{fn: testStore},
loadexception: {fn: loadFailedReport}
}
});
What am I missing?

Animal, Thank you for your reply. I appreciate it.

steffenk
26 Jul 2009, 3:09 AM
You mix up id's used in your Example.

in store property is called: idProperty

further you should debug your code in event afteredit to see what's in the fields.

Also have a look to the example how it's done there, it's more simple than you did.

StevenInc
26 Jul 2009, 3:24 AM
steffenk, I did a search in the API for idProperty and I can't find any reference to it.
Do you have a link?
Also I read the editable grid source could in the example and that example seems to use phantom id's so it is not very helpful in addressing my problem.

Thanks for your reply.

steffenk
26 Jul 2009, 3:28 AM
Here is the link:
http://extjs.com/deploy/dev/docs/?class=Ext.data.JsonStore

You should use the API all the time, it helps a lot and there is all in. It also took me some time in the beginning to read it right.

And id stuff changed in 3.0 so the tutorials might not be actual.

StevenInc
26 Jul 2009, 3:32 AM
Wow, I didn't realize the changes about 3.0 and the id changes.
I am following the book learning EXT JS.

Thanks again for your help.

steffenk
26 Jul 2009, 4:18 AM
Have a look to the sticky in this forum, there are all the important changes in version 3.

Also Firebug is one of the most important tool. If something doesn't work as expected it's a tool for debug, inspect etc.

mjlecomte
26 Jul 2009, 8:46 AM
Read the docs Animal linked carefully:
http://extjs.com/deploy/dev/docs/?class=Ext.data.Record&member=Record

Note the 2nd argument is the id for the record!

Don't confuse that with a field within a record coincidentally having a name "id".

Take note of the example here:
http://extjs.com/deploy/dev/docs/?class=Ext.data.Record&member=create

Take note of the store.insert() method docs, the method you are using.
http://extjs.com/deploy/dev/docs/?class=Ext.data.Store&member=insert

It links to store.add(), which then links to recordType() which has an example using.....store.insert()!

StevenInc
26 Jul 2009, 6:28 PM
Thank you to everyone who assisted me with this problem.
I solved the problem by changing my ID to MOVIEID and adding

idProperty:'MOVIEID',To the Ext.data.JsonStore

I also simplified the code and removed the second data store that also did not have an id specified.

I will post the final code as soon as I have a chance to clean it up.

Thanks again.

VinylFox
27 Jul 2009, 8:23 AM
Did you receive an errata sheet with your book, or look online at the errata? Have you downloaded the example code from the publishers web site, or are you retyping from the book?

Please let me know where you ran into problems (be specific) so I can fix them.

StevenInc
1 Aug 2009, 4:45 AM
Shea, thank you for links. I do appreciate it.
My comment really stems from the php examples that reference the live data base code.
As there is no SQL downloads I recreated the simple database tables and attempted to execute the code.

additionally
The code in chapter seven seems to be missing the top bar when it is executed
Executing the code in Chapter 8 is especially difficult for me right now.

I am pleased that you have reached out to me here on the forum, I must confess that I am a little frustrated because all of my attempts to contact an author through the publisher have been in vain.

That said I would be pleased to share with you the problems that I encounter as I attempt to run the examples on various platforms. However I don't think this thread is the best place for it. If you start a new thread, I will participate.

Thank you.

StevenInc
1 Aug 2009, 5:13 AM
I am posting the code because I think it can help others that are looking to implement the grid editor on a coldfusion platform.

The main problem with using coldfusion with EXT-JS is the native JSON output from coldusion is not compatible with the EXT-JS Data Stores. I know there are various readers to massage the data on the client side, but this solution seems slow and cumbersome to me.

After reading Kumar Shah Blog at www.coldfusion-ria.com (http://www.coldfusion-ria.com) I rewrote his snippet into a cfc that converts the coldfusion queryset to JSON that is properly formatted for EXT JS. On my lap top computer the overhead is 6-8 ms. So on an enterprise server it can be as little as 2ms.

I have also read about Ray's Camden's ToJson cfc at: http://tojson.riaforge.org/
I haven't had a chance to take a look at it, but if Ray wrote it...it must be good.



/*!
* Ext JS Library 3.0.0
* Copyright(c) 2006-2009 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/

Ext.onReady(function(){
Ext.QuickTips.init(); // to display button quicktips


var users = Ext.data.Record.create([
{name: 'MOVIEID', type: 'int'},
'ROW_NUMBER',
'COVERTHUMB',
'TITLE',
'DIRECTOR',
{name: 'RELEASED', type: 'date'},
'GENRE',
'GENREID',
'TAGLINE',
{name: 'PRICE', type: 'float'},
{name: 'AVAILABLE', type: 'bool'}
],);


var store =new Ext.data.JsonStore({
totalProperty:'DATASET',
root:'ROWS',
idProperty:'MOVIEID',
url:'getMovies.cfc',
remoteSort:true,
baseParams:{method:'getAllMovies',returnFormat:'JSON', start:0, limit:5},
fields:users,
listeners: {
load:{fn: testStore},
loadexception: {fn: loadFailedReport}
}
});



// create another data store that loads the distinct genre names for use in the drop down
var distinctGenre = new Ext.data.JsonStore({
root:'ROWS',
url:'getMovies.cfc',
remoteSort:true,
baseParams:{method: 'getDistinctGenre', returnFormat: 'JSON',start: '1',limit: '50'},
fields: ['GENREID', 'GENRE'],
listeners: {
load:{fn: testStore},
loadexception: {fn: loadFailedReport}
}
});

distinctGenre.load();
store.load();



// match the genre ID from the "store" datastore to the genre name in the "distinctGenre" data store.
function getGenreNameByID(val){
return distinctGenre.queryBy(function(rec){
if (rec.data.GENREID== val){
return true;
}else{
return false;
}
}).itemAt(0).data.GENRE;
}



//This function will be called on a succesful load, it can be used for debugging or perform on load events.
function testStore(st,recs,opts){
console.info('store getTotalCount = ', store.getTotalCount());
}

function loadFailedReport() {
console.info('Load Failed count = ', store.getCount());
}



//form elements for edit mode in grid
var title_edit = new Ext.form.TextField();
var director_edit = new Ext.form.TextField();
var tagline_edit = new Ext.form.TextField({maxLength: 45});
var release_edit = new Ext.form.DateField({format: 'm/d/Y'});

var genre_edit = new Ext.form.ComboBox({
typeAhead: true,
triggerAction: 'all',
mode: 'local',
store: distinctGenre,
displayField:'GENRE',
valueField: 'GENREID'
});






var grid = new Ext.grid.EditorGridPanel({
renderTo: document.body,
frame:true,
title: 'Movie Database',
height:250,
width:520,
clicksToEdit: 1,
store: store,
columns: [
{header: "MOVIEID", dataIndex: 'MOVIEID'},
{header: "Title", dataIndex: 'TITLE', editor: title_edit},
{header: "Director", dataIndex: 'DIRECTOR', editor: director_edit},
{header: "Released", dataIndex: 'RELEASED', renderer: Ext.util.Format.dateRenderer('m/d/y'), editor:release_edit },
{header: "Genre", dataIndex: 'GENREID', renderer:getGenreNameByID, editor:genre_edit},
{header: "Tagline", dataIndex: 'TAGLINE', editor: tagline_edit}
],

listeners: {
//update data cell
afteredit: function(e)
{
var conn = new Ext.data.Connection();
conn.request({
url: 'crud_movies.cfc',
params: {method: 'updateMovieByID', id: e.record.id, field: e.field, value: e.value, row: e.row},
success: function(resp,opt) {// Transport Layer
var updateStatus = Ext.util.JSON.decode(resp.responseText).SUCCESS;

if (updateStatus==1){
e.record.commit();
}
else{
e.record.reject();
Ext.Msg.alert('Database Error', 'Update Failed');
};

},
//handle an ajax transport layer error
failure: function(resp,opt) {
Ext.Msg.alert('Communication Error', 'The ID is:'+e.record.id);
}
});
}//afterEdit
},//listeners

sm: new Ext.grid.RowSelectionModel({
singleSelect: true
}),


keys: [
{
key: 46,
fn: function(key,e){
var sm = grid.getSelectionModel();
var sel = sm.getSelected();
if (sm.hasSelection()){
Ext.Msg.show({
title: 'Remove Movie',
buttons: Ext.MessageBox.YESNOCANCEL,
msg: 'Remove '+sel.data.TITLE+'?',
fn: function(btn){
if (btn == 'yes'){
grid.getStore().remove(sel);
}//button = yes
}//function button
});//Msg.show
}//if (sm.hasSelection()
},

ctrl:false,
stopEvent:true
}
],

tbar: [{
text: 'Add Movie (First)',
icon: 'images/table_add.png',
cls: 'x-btn-text-icon',
handler: function() {

var conn = new Ext.data.Connection();
conn.request({
url: 'crud_movies.cfc',
params: {method: 'insertMovie',title:'New Movie'},
success: function(resp,opt) {
var insert_id = Ext.util.JSON.decode(resp.responseText).INSERT_ID;
Ext.Msg.alert('[title]', '['+insert_id+']');
var e=new users ({MOVIEID:insert_id,TITLE:'New Movie',DIRECTOR:'New Director',GENREID:0,TAGLINE:'New Tagline'},'MOVIEID');
grid.getStore().insert(0, e);
},
failure: function(resp,opt) {
Ext.Msg.alert('Error','Unable to add movie');
}
});
}//handler
},{
text: 'Add Movie (Last)',
icon: 'images/table_add.png',
cls: 'x-btn-text-icon',
handler: function() {

var conn = new Ext.data.Connection();
conn.request({
url: 'crud_movies.cfc',
params: {method: 'insertMovie',title:'New Movie'},
success: function(resp,opt) {
var insert_id = Ext.util.JSON.decode(resp.responseText).INSERT_ID;
Ext.Msg.alert('[title]', '['+insert_id+']');
var e=new users ({MOVIEID:insert_id,TITLE:'New Movie',DIRECTOR:'New Director',GENREID:0,TAGLINE:'New Tagline'},'MOVIEID');
grid.getStore().insert(grid.getStore().getCount()-1, e);
grid.startEditing(grid.getStore().getCount()-1,0);
},
failure: function(resp,opt) {
Ext.Msg.alert('Error','Unable to add movie');
}
});//handler

}


},
//remove button
{
text: 'Remove Movie',
icon: 'images/table_delete.png',
cls: 'x-btn-text-icon',

handler: function() {
var sm = grid.getSelectionModel();
var sel = sm.getSelected();
if (sm.hasSelection())
{
Ext.Msg.show({
title: 'Remove Movie',
buttons: Ext.MessageBox.YESNOCANCEL,
msg: 'Remove '+sel.data.TITLE+'?',
fn: function(btn){
if (btn == 'yes'){


var conn = new Ext.data.Connection();
conn.request({
url: 'crud_movies.cfc',
params: {
method: 'delete',
id: sel.data.MOVIEID
},
success: function(resp,opt) {
grid.getStore().remove(sel);
},
failure: function(resp,opt) {
Ext.Msg.alert('Error','Unable to delete movie');
}
});//conn
}
}
}
);//Msg.Show
}//has Selection
else{
Ext.Msg.alert('Error', 'Please select a row before clicking on remove.');
}
}//handler
}],
//bbar: [new Ext.PagingToolbar({
//store: store})]


bbar: [new Ext.PagingToolbar({
pageSize: 5,
store: store,
displayInfo: true,
displayMsg: 'Displaying Movie Records {0} - {1} of {2}',
emptyMsg: "No Records to display"
})]


});//grid





});//onReady

StevenInc
1 Aug 2009, 5:15 AM
The first part I create the record set object the the movies, then I create the client side store for both the movies and the distinct movie genres. The store are all created from a cfc that make a call to the data base.

StevenInc
1 Aug 2009, 5:19 AM
Here are the cfc's that I used in my example:

getMovies CFC:



<cfcomponent output="false">
<!---get all movies--->
<cffunction name="getAllMovies" access="remote" output="false" returntype="any" returnformat="json">
<cfargument name="start" type="numeric" required="yes">
<cfargument name="limit" type="numeric" required="yes">

<cfset dbStatus = "true">
<cftry>
<cfquery name="getAllMovies" datasource="learningEXTJS">
SELECT [movieID]
,[coverthumb]
,[title]
,[director]
,[genreID]
,[genre]
,[tagline]
,[price]
,[available]
,[released]
FROM (SELECT row_number() over (order by movieID)as row_number,movieID, coverthumb, title, director, genreID, genre, tagline, price, available, released
FROM chapter6_movies) as mySQL
ORDER BY movieID
</cfquery>


<cfcatch type="database">
<cfset dbStatus = "false">
</cfcatch>
</cftry>

<cfif dbStatus EQ "true">
<cfinvoke component="CF_EXTJS" method="qry2json" returnvariable="extjs_jsonVar">
<cfinvokeargument name="querySet" value="#getAllMovies#">
<cfinvokeargument name="start" value="#arguments.start#">
<cfinvokeargument name="limit" value="#arguments.limit#">
</cfinvoke>
<cfelse>
<cfset extjs_jsonVar= {SUCCESS=0}>
</cfif>


<cfreturn extjs_jsonVar />
</cffunction>

<!---get distinct column name--->
<cffunction name="getDistinctColumnsByName" access="remote" output="false" returntype="any" returnformat="json">
<cfargument name="colName" type="string" required="false" />
<cfset var output = "" />
<cfset var q = "" />

<cftry>
<cfquery name="getDistinctColumnsByName" datasource="learningEXTJS">
SELECT distinct #arguments.colName#
FROM chapter6_movies
</cfquery>

<cfcatch type="database">
<cfset q="Data Base Read Error">
</cfcatch>
</cftry>

<cfinvoke component="CF_EXTJS" method="qry2json" returnvariable="extjs_jsonVar">
<cfinvokeargument name="querySet" value="#getDistinctColumnsByName#">
</cfinvoke>

<cfreturn extjs_jsonVar />
</cffunction>

<!---get distinct genre names and ID--->
<cffunction name="getDistinctGenre" access="remote" output="false" returntype="any" returnformat="json">
<cfset var output = "" />
<cfset var q = "" />

<cftry>
<cfquery name="getDistinctColumnsByName" datasource="learningEXTJS">
SELECT distinct genreID,genre
FROM chapter6_movies
</cfquery>

<cfcatch type="database">
<cfset q="Data Base Read Error">
</cfcatch>
</cftry>

<cfinvoke component="CF_EXTJS" method="qry2jsonNoPaging" returnvariable="extjs_jsonVar">
<cfinvokeargument name="querySet" value="#getDistinctColumnsByName#">
</cfinvoke>

<cfreturn extjs_jsonVar />
</cffunction>

</cfcomponent>


crud_movie CFC:





<cfcomponent output="false">
<!--- Update --->
<cffunction name="updateMovieByID" access="remote" output="false" returntype="any" returnformat="json">
<cfargument name="id" type="any">
<cfargument name="field" type="string">
<cfargument name="value" type="string">
<cfargument name="row" type="any">

<cfset var output = "" />
<cfset var q = "" />



<cfset foo= {SUCCESS=1}>
<cftry>

<cfif field EQ "RELEASED"> <!---format for dateTime update--->
<cfset arguments.value = CreateODBCDate(value)>
<cfquery name="updMovieByID" datasource="learningEXTJS" result="thisResults">
UPDATE chapter6_movies
SET #arguments.field# = #arguments.value#
WHERE MOVIEID = #arguments.id#
</cfquery>
<cfelse>
<cfquery name="updMovieByID" datasource="learningEXTJS" result="thisResults">
UPDATE chapter6_movies
SET #arguments.field# = '#arguments.value#'
WHERE MOVIEID = #arguments.id#
</cfquery>
</cfif>


<cfcatch type="Any">
<cfset foo= {SUCCESS=0}>
</cfcatch>
</cftry>

<cfreturn foo>
<!--- <cfparam name="updMovieByID.recordcount" default="Rollback">
<cfscript>
q = QueryNew("results");
QueryAddRow(q,1);
QuerySetCell(q,"results","#updMovieByID.recordcount#",1);
</cfscript>

<cfinvoke component="CF_EXTJS" method="qry2json" returnvariable="extjs_jsonVar">
<cfinvokeargument name="querySet" value="#q#">
</cfinvoke>

<cfreturn extjs_jsonVar /> --->
</cffunction>

<!---delete--->
<cffunction name="delete" access="remote" output="false" returntype="any" returnformat="json">
<cfargument name="id" type="any">

<cfquery name="deleteMovieById" datasource="learningEXTJS" result="thisResults">
Delete chapter6_movies
WHERE MOVIEID = #arguments.id#
</cfquery>

<cfset foo= {SUCCESS=thisResults.recordCount}>


<cfreturn foo />
</cffunction>

<!---insert--->
<cffunction name="insertMovie" access="remote" output="false" returntype="any" returnformat="json">
<cfquery name="insertMovie" datasource="learningEXTJS" result="thisResults">
INSERT INTO [chapter6_movies]
([title])
VALUES
('New_Movie')

SELECT @@IDENTITY AS 'newIdentity';
</cfquery>

<cfset newIdentityID = insertMovie.newIdentity>
<cfset foo = {insert_id=newIdentityID}>

<cfreturn foo />
</cffunction>

<!---get distinct column name--->
<cffunction name="getDistinctColumnsByName" access="remote" output="false" returntype="any" returnformat="json">
<cfargument name="colName" type="string" required="false" />
<cfset var output = "" />
<cfset var q = "" />

<cftry>
<cfquery name="getDistinctColumnsByName" datasource="learningEXTJS">
SELECT distinct #arguments.colName#
FROM chapter6_movies
</cfquery>

<cfcatch type="database">
<cfset q="Data Base Read Error">
</cfcatch>
</cftry>

<cfinvoke component="CF_EXTJS" method="qry2json" returnvariable="extjs_jsonVar">
<cfinvokeargument name="querySet" value="#getDistinctColumnsByName#">
</cfinvoke>

<cfreturn extjs_jsonVar />
</cffunction>

<!---get distinct genre names and ID--->
<cffunction name="getDistinctGenre" access="remote" output="false" returntype="any" returnformat="json">
<cfset var output = "" />
<cfset var q = "" />

<cftry>
<cfquery name="getDistinctColumnsByName" datasource="learningEXTJS">

SELECT distinct genreID,genre
FROM chapter6_movies
</cfquery>

<cfcatch type="database">
<cfset q="Data Base Read Error">
</cfcatch>
</cftry>

<cfinvoke component="CF_EXTJS" method="qry2json" returnvariable="extjs_jsonVar">
<cfinvokeargument name="querySet" value="#getDistinctColumnsByName#">
</cfinvoke>

<cfreturn extjs_jsonVar />
</cffunction>

</cfcomponent>
My Coldfusion queryset to Json cfc (CF_EXTJS)



<!--- We loop through the query and create our JSON return set. The ExtJS JSON return has to be in the format like:
{
results: 2, // Reader's configured totalProperty
rows: [ // Reader's configured root
{ id: 1, firstname: 'Bill', occupation: 'Gardener' }, // a row object
{ id: 2, firstname: 'Ben' , occupation: 'Horticulturalist' } // another row object
]
}
This means that the data is returned as an array of objects (in our case structures). So we build that array.
--->

<cfcomponent>
<cffunction name="qry2jsonNoPaging" access="public" returntype="any">
<cfargument name="querySet" type="query" required="yes">
<cfargument name="recordCount" type="any" default="">


<cfset thisQueryName = arguments.querySet>
<cfset i = 1>

<cfset thisColumnList = querySet.columnList><!---get a list of all the column names from the query--->
<cfloop query="querySet"><!---loop through each row in the record set--->
<cfset stcUsers = StructNew()><!---create an empty struct (clears for each loop)--->
<cfloop index="columnName" list="#thisColumnList#" delimiters=","><!---populate the struct with the data in the row--->
<cfset "stcUsers.#columnName#" = evaluate("querySet."&columnName)>
</cfloop>
<cfset arrUsers[i] = stcUsers><!---load the row data stuct into an array--->
<cfset i = i + 1><!---increment the array counter--->
</cfloop>

<!--- Format the JSON for EXT JS --->
<cfset stcReturn = {rows=arrUsers,dataset=arguments.recordCount}>
<cfreturn stcReturn>

</cffunction>


<cffunction name="qry2json" access="public" returntype="any">
<cfargument name="querySet" type="query" required="yes">
<cfargument name="start" type="numeric" required="Yes">
<cfargument name="limit" type="numeric" required="yes">

<cfscript>
var endRow = '';
var startRow = '';
var output = '';
var q = '';
startRow = start+1;
endRow = (start+limit)-1;
</cfscript>


<cfset endRow = (startRow + arguments.limit)-1>
<cfset i = 1>

<cfset thisColumnList = querySet.columnList><!---get a list of all the column names from the query--->
<cfloop query="querySet" startrow="#startRow#" endrow="#endRow#"><!---loop through each row in the record set--->
<cfset stcUsers = StructNew()><!---create an empty struct (clears for each loop)--->
<cfloop index="columnName" list="#thisColumnList#" delimiters=","><!---populate the struct with the data in the row--->
<cfset "stcUsers.#columnName#" = evaluate("querySet."&columnName)>
</cfloop>
<cfset arrUsers[i] = stcUsers><!---load the row data stuct into an array--->
<cfset i = i + 1><!---increment the array counter--->
</cfloop>

<!--- Format the JSON for EXT JS --->
<cfset stcReturn = {rows=arrUsers,dataset=querySet.RecordCount}>
<cfreturn stcReturn>

</cffunction>
</cfcomponent>

StevenInc
1 Aug 2009, 5:33 AM
The most difficult part for me was handling the unique ID when inserting a new record in the data store. (Thank you to vg steffen and MJ Lecomte for pointing me in the right direction.
Also much thanks to Animal who has answered so many of my questions)

When I can across this in the documentation, It solved my problems.




// create Record instance
var myNewRecord = new TopicRecord(
{
title: 'Do my job please',
author: 'noobie',
totalPosts: 1,
lastPost: new Date(),
lastPoster: 'Animal',
excerpt: 'No way dude!',
signature: ''
},
id // optionally specify the id of the record otherwise {@link #Record.id one is auto-assigned}
);Once I added the comma and id reference here:


var e=new users ({MOVIEID:insert_id,TITLE:'New Movie',DIRECTOR:'New Director',GENREID:0,TAGLINE:'New Tagline'},'MOVIEID');
grid.getStore().insert(0, e);
Then I was able to piece everything else together.

Thanks to everyone for their help.

I would be pleased to answer any questions about my code.

VinylFox
3 Aug 2009, 11:17 AM
As there is no SQL downloads I recreated the simple database tables and attempted to execute the code.

Im not sure why you don't have the SQL file, but it is available on the Google Code site I have placed all the book code on. Check my signature for the link.


I am pleased that you have reached out to me here on the forum, I must confess that I am a little frustrated because all of my attempts to contact an author through the publisher have been in vain.

Well that sucks man...I have not received any notice from my publisher that you tried to contact me. Its not the first time I have been let down by them, so im not surprised. You would think for their 2nd best selling book they would pay more attention. *sigh*


That said I would be pleased to share with you the problems that I encounter as I attempt to run the examples on various platforms. However I don't think this thread is the best place for it. If you start a new thread, I will participate.

I don't want to muddy up the ExtJS forums with this kinda stuff - these forums are for their products and not mine, so if you can just email me directly we can start a discussion to fix some of these things. PM me and ill give you my email.