-
26 May 2011 12:18 PM #1
Grid cell update POSTs whole grid?
Grid cell update POSTs whole grid?
I have a grid set to cell editing mode. It autoLoads data, and when I click on an editable cell to edit, the resultant action is a create() which posts all 20 rows with all fields to the server? Why?
Code:Ext.onReady(function() { Ext.BLANK_IMAGE_URL = '/images/extjs4/s.gif'; Ext.tip.QuickTipManager.init(); //Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider')); Ext.define('VendorError', { extend: 'Ext.data.Model', fields: [ {name: 'UnexpSrvID', type: 'int'}, {name: 'VendorID', type: 'int'}, {name: 'VendorName', type: 'string'}, {name: 'VndActID', type: 'int'}, {name: 'VndActNb', type: 'string'}, {name: 'InvoiceID', type: 'int'}, {name: 'VInvNb', type: 'string'}, {name: 'VInvRcptDt', type: 'date', dateFormat: 'Y-m-d' }, {name: 'InvDate', type: 'date', dateFormat: 'Y-m-d' }, {name: 'CodeSpecifier', type: 'string'}, {name: 'Recurrence', type: 'string'}, {name: 'ClientID', type: 'int'}, {name: 'ClientName', type: 'string'}, {name: 'LocID', type: 'int'}, {name: 'LocName', type: 'string'}, {name: 'RecentLocStatus', type: 'string'}, {name: 'RecentLocStatusDate', type: 'date', dateFormat: 'Y-m-d' }, {name: 'UnexpCost', type: 'float'}, {name: 'ConfirmedAmt', type: 'float'}, {name: 'StaffID', type: 'int'}, {name: 'NetworkID', type: 'string'}, {name: 'UnexpStatCode', type: 'string'} ] }); var store = Ext.create('Ext.data.Store', { model: 'VendorError', autoLoad: true, autoSync: true, pageSize: 20, remoteSort: true, proxy: { type: 'ajax', simpleSortMode: true, api: { read: '/internal/viewVERext_json.asp', create: '/internal/viewVERext_create.asp', update: '/internal/viewVERext_update.asp', destroy: '/internal/viewVERext_destroy.asp', }, reader: { type: 'json', totalPorperty: 'total', successProperty: 'success', messageProperty: 'message', root: 'data' }, writer: { type: 'json', writeAllFields: false, root: 'data' }, listeners: { exception: function(proxy, response, operation){ Ext.MessageBox.show({ title: 'REMOTE EXCEPTION', msg: operation.getError(), icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK }); } } }//, //listeners: { // write: function(proxy, operation){ // if (operation.action == 'destroy') { // main.child('#form').setActiveRecord(null); // } // Ext.example.msg(operation.action, operation.resultSet.message); // } //} }); // create the Grid var grid = Ext.create('Ext.grid.Panel', { store: store, //stateful: true, //stateId: 'stateGrid', columns: [ { text : 'Vendor', dataIndex: 'VendorName', flex : 1 }, { text : 'Account', dataIndex: 'VndActNb' }, { text : 'Invoice', dataIndex: 'VInvNb' }, { text : 'Invoiced', dataIndex: 'InvDate', xtype : 'datecolumn', align : 'center' }, { text : 'Receipted', dataIndex: 'VInvRcptDt', xtype : 'datecolumn', align : 'center' }, { text : 'Description', dataIndex: 'CodeSpecifier' }, { text : 'Client', dataIndex: 'ClientName' }, { text : 'Location', dataIndex: 'LocName' }, { text : 'LStatus', dataIndex: 'RecentLocStatus', align : 'center' }, { text : 'Credit', dataIndex: 'UnexpCost', tdCls : 'colyellow', renderer : Ext.util.Format.usMoney, align : 'right', field : { xtype:'textfield', allowBlank:false } }, { text : 'Confirmed', dataIndex: 'ConfirmedAmt', tdCls : 'colyellow', renderer : Ext.util.Format.usMoney, align : 'right', field : { xtype:'textfield', allowBlank:false } }, { text : 'Recurrence', dataIndex: 'Recurrence', tdCls : 'colyellow', align : 'center' }, { text : 'CStatus', dataIndex: 'UnexpStatCode', tdCls : 'colyellow', align : 'center' }, { text : 'Owner', dataIndex: 'NetworkID', tdCls : 'colyellow', field : { xtype : 'combobox', typeAhead: true, triggerAction: 'all', selectOnTab: true, store: [ <%=staff_grid%> ], lazyRender: true } } ], layout: 'fit', height: 500, renderTo: 'theGrid', selType: 'cellmodel', plugins: [ Ext.create('Ext.grid.plugin.CellEditing', { clicksToEdit: 1 }) ], dockedItems: [ { xtype: 'pagingtoolbar', store: store, dock: 'bottom', displayInfo: true }, { xtype: 'toolbar', dock: 'top' } ], viewConfig: { stripeRows: true } }); Ext.EventManager.onWindowResize(grid.doLayout, grid); });
-
27 May 2011 7:12 AM #2
Thinking it was cell-based editing, I switched it over to row-based editing. Still happens. With a fresh data load, after first edit, the entire grid is posted to the create operation. I guess it thinks they are all dirty records? How could I confirm this behavior?
Last edited by alphadogg; 27 May 2011 at 7:31 AM. Reason: typos
-
27 May 2011 7:40 AM #3
Any way to hook into a grid post-load event of the right type and mark all records not dirty?
-
27 May 2011 8:10 AM #4
try moving proxy settings from store to model
-
27 May 2011 9:14 AM #5
I tried moving it and it still posts via create. Is this a bug? Is there a public list of known issues on ExtJS4?
Code:Ext.define('VendorError', { extend: 'Ext.data.Model', fields: [ {name: 'UnexpSrvID', type: 'int'}, {name: 'VendorID', type: 'int'}, {name: 'VendorName', type: 'string'}, {name: 'VndActID', type: 'int'}, {name: 'VndActNb', type: 'string'}, {name: 'InvoiceID', type: 'int'}, {name: 'VInvNb', type: 'string'}, {name: 'VInvRcptDt', type: 'date', dateFormat: 'Y-m-d' }, {name: 'InvDate', type: 'date', dateFormat: 'Y-m-d' }, {name: 'CodeSpecifier', type: 'string'}, {name: 'Recurrence', type: 'string'}, {name: 'ClientID', type: 'int'}, {name: 'ClientName', type: 'string'}, {name: 'LocID', type: 'int'}, {name: 'LocName', type: 'string'}, {name: 'RecentLocStatus', type: 'string'}, {name: 'RecentLocStatusDate', type: 'date', dateFormat: 'Y-m-d' }, {name: 'UnexpCost', type: 'float'}, {name: 'ConfirmedAmt', type: 'float'}, {name: 'StaffID', type: 'int'}, {name: 'NetworkID', type: 'string'}, {name: 'UnexpStatCode', type: 'string'} ], proxy: { type: 'ajax', simpleSortMode: true, api: { read: '/internal/viewVERext_json.asp', create: '/internal/viewVERext_create.asp', update: '/internal/viewVERext_update.asp', destroy: '/internal/viewVERext_destroy.asp' }, reader: { type: 'json', totalProperty: 'total', successProperty: 'success', messageProperty: 'message', root: 'data' }, writer: { type: 'json', writeAllFields: false, allowSingle: false, root: 'data' }, listeners: { exception: function(proxy, response, operation){ Ext.MessageBox.show({ title: 'REMOTE EXCEPTION', msg: operation.getError(), icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK }); } } } });
-
27 May 2011 10:02 AM #6
If I add:
to the store listeners, I get it triggered when I load the grid when the page loads, but when I edit a cell I get nothing. It goes on to create all the records, and doesn't seem to have noticed the edit.Code:datachanged: function() { var report = ""; store.each( function(rec) { report = report + rec.dirty + '/'; } ) alert(report); }
-
27 May 2011 11:49 PM #7
I think your models need to have an "id" field of type int. And existing records that get populated need to have a unique id value. I'm not a 100% sure, but I think that's how the stores work to determine crud actions. If there's no id value, or if id value is 0, it assumes its a new record and when it syncs, it needs to do a create action.
When records have a valid unique id value, then it calls the update or destroy actions appropriately based on what's done with the grid's editor.
And the unique value for id is important, otherwise the grid ends up only showing the last record loaded with that particular id value.
-
31 May 2011 12:09 PM #8
If you were next to me, I'd hug you. Maybe embarrassing, but conventions be damned!

That did it. When I changed the "UnexpSrvId" field in the model to "id", it all worked as expected.
Wow, I know Sencha docs kinda suck, but that is a horrible, horrible lapse in the API! I spent hours trying to figure this non-obvious issue out, costing my company hundreds of dollars...
The "idProperty" field needs to be highlighted and emphasized as it relates to CRUDing of the model.
-
31 May 2011 9:47 PM #9
Awesome :-) Glad that helped! I agree that when using the store.sync() method, knowing that the assumed "id" field drives CRUD actions is fairly important! It's in the API... but like you said, it's far from being highlighted. I found it by reading the source for the sync() method: http://docs.sencha.com/ext-js/4-0/so...re-method-sync
And you'll see that it uses its getNewRecords(), getUpdatedRecords(), getRemovedRecords()... and the API description for getNewRecords() describes its use of the "id" field.
Fun...
-
5 Jul 2011 2:59 AM #10
I had the same problem, note the line:
type: 'ajax',
Should be :
type: 'rest'
"RestProxy is a specialization of the AjaxProxy which simply maps the four actions (create, read, update and destroy) to RESTful HTTP verbs. For example, let's set up a Model with an inline RestProxy"
http://docs.sencha.com/ext-js/4-0/#/...ata.proxy.Rest


Reply With Quote