PDA

View Full Version : Smoothest Way To Capture Changed Grid Rows Using CellEditing



rkanemeier
5 Sep 2013, 11:45 AM
Using ExtJS 4.0.7, I have a grid, with the CellEditing plugin, which uses a store that is receiving data via a back end program.. The grid has 4 columns that are un-editable, and 4 columns that are editable (CellEditing). The user should be allowed to edit as many cells as they'd like, and when they click a save button, those changed rows should be committed to a database.

What is the "smoothest" way to handle communicating those changes to a back-end program?

Currently, I'm using the "edit" listener on the grid, and pushing records to a global array every time a cell is changed. When the save button is clicked, I call a function that loops through the array and makes an ajax call that updates each record in the database file. However, since I have 4 columns that are editable in each row, that means I'm pushing up to 4 records into the array for each row in the grid. This is where I'm drawing a blank. How do I grab changed "rows" instead of changed "cells" and push just the changed rows to the array?

eric.cook
5 Sep 2013, 12:16 PM
I've had great success using a MixedCollection.



Ext.define('App.RecordCollection', {
extend: 'Ext.util.MixedCollection',

allowFunctions: false,

// Prevents changing getKey via constructor
constructor: function () {
this.callParent();
},

getKey: function (record) {
return record.getId() || null;
},

addRecord: function (record) {
if (record && !this.contains(record)) {
this.add(record);
}
}
});


In your edit event listener, you can simply call addRecord and it will do the work for you. Saving records is easy because you still get the MixedCollection's each, eachKey, and getRange methods.

Stores have a getUpdatedRecords method, but I seem to recall having issues with it.

rkanemeier
5 Sep 2013, 2:23 PM
Eric,

Thanks for your response. That seems to be a more fluid/natural solution, however, a tad more advanced than I can take on right now.

What I ended up doing was checking for dirty records when I pressed the save button.



items: [{
text: 'Save',
disabled: true,
iconCls: 'save',
handler: function(btn) {
btn.disable();

for (var i = 0; i < myGrid.store.data.items.length; i++) {
var record = myGrid.store.data.items[i];
if (record.dirty) {
saveRecords(record);
}
}


myDataStore.load();
}



My saveRecords function extracts the params from the record and performs an ajax call to a back-end program that updates the record in the database. I actually found this solution on another site, and I would reference it, but I've been distracted since then and closed out browser.

eric.cook
6 Sep 2013, 5:29 AM
It's really not that advanced. I'll walk you through it.

First, drop the code I provided above into whatever file you're working on. Replace the "App" namespace with whatever namespace you're using (I'll keep using "App" to make things simple).

Next, you'll need to instantiate the RecordCollection. Easy.


App.recordsToSave = Ext.create('App.RecordCollection');


Add an event handler to your CellEditing plugin to listen for the edit (http://docs.sencha.com/extjs/4.1.0/#!/api/Ext.grid.plugin.CellEditing-event-edit) event. When the user successfully edits a cell, we'll add the record to our collection.


Ext.create('Ext.grid.Panel', {
/* other configuration */
plugins: [{
ptype: 'cellediting',
listeners: {
edit: function (editor, e) {
App.recordsToSave(e.record);
}
}
}],
/* other configuration */
});


And lastly, loop over the records when the user clicks the "Save" button.


items: [{
text: "Save",
disabled: true,
iconCls: "save",
handler: function (btn) {
btn.disable();
App.recordsToSave.each(function (record) {
if (record.dirty) {
saveRecords(record);
}
});
App.recordsToSave.clear();
myDataStore.load();
}
}]