-
22 Mar 2011 10:57 AM #61
Setting selection status from external data...
Setting selection status from external data...
Joeri, first... nicely done, thank you for the plug-in, it's working beautifully.
In my application I instantiate a grid with the RowSelectionPaging plug-in in an Ext.Window (data store is connected to MySQL via an Ajax proxy).
Once the user has paged and selected their data and clicked 'save', I read the selectionPaging.getSelections() array of objects and store their selections in a MySQL table via an Ajax call, and then destroy the grid/window.
What I now need to do is on subsequent instantiations set the selected flag for those records already selected and I don't see a public method within the RowSelectionPaging plug-in to permit me to do this. Perhaps this isn't a plug-in specific question but a more general question of the CheckboxSelectionModel. A healthy pointer would be much appreciated...
-
23 Mar 2011 12:06 AM #62
You're right that this isn't supported. To implement a setSelections is pretty straightforward (untested code, you may need to debug it):
You would have to call that after the plugins are initialized, perhaps in the 'render' event handler.Code:// selection = array of Record setSelections: function(selection) { this.selections = [].concat(selection); this.selected = {}; for (var i = 0; i < this.selections.length; i++) { this.selected[this.selections[i].id] = true; } }
-
23 Mar 2011 10:29 AM #63
Hi there! Have you tested this plugin with my SmartCheckBoxSelectionModel by chance? This seems to fill in a missing feature I've wanted to add for a long time. Not sure if you're still actively developing this or not, but I figured it couldn't hurt to ask!
Noah
Senior Web Developer
NBA.com
-
24 Mar 2011 1:32 AM #64
No, haven't tested it in that combination. You're welcome to try for yourself.
I plan to revisit this plugin for Ext JS 4, when we do our migration later this year.
-
24 Mar 2011 4:35 AM #65
Thoughts on handling a pre-load of checked items...
Thoughts on handling a pre-load of checked items...
So, I've successfully modified the RowSelectionPaging plugin to support the idea of pre-loading selections.
I wanted a widget that reduced the number of form controls instantiated at any given time in the DOM and this plug-in fit the bill perfectly.
However, I also needed to pre-select certain elements from the initial database read. In addition, since this control is not RESTful, we needed to track selections & unselections so the user could either 'save selections' or 'cancel'.
The solution was to add another collection to the plug-in - I called them unselected and unselections - that are maintained in a similar manner to the selected/selections collections.
This allowed me to keep track of un-select actions on database-pre-selected items when moving from page to page. With that nailed down, I just needed to add the pre-selection method to the class. This pre-selection method relies on a specific data element called 'selected' in the data store.Code:// add the following just before the 'grid.on('... in the init: this.unselections = []; // array of unselected records this.unselected = {}; // hash mapping record id to unselected state this.selectDbItems(); // pre-select any items from an initial database read
You have to change the onViewRefresh method to deal with tracking any unselected data that might have been brought in from the database during a paging action as well as changing the selModel.selectRows call because you now care about preserving selections. So, records in the selected/selections collections plus records in the data with a 'selected' value of 1 (hacki-ness, sorry) but not in the unslected/unselections collecctions (phew!)...
You have to add un-selection management to onRowSelect and onRowDeselect...Code:// private onViewRefresh: function() { this.ignoreSelectionChanges = true; // explicitly refresh the selection model this.grid.selModel.onRefresh(); // selection changed from view updates, restore full selection var ds = this.grid.getStore(); var newSel = []; for (var i = ds.getCount() - 1; i >= 0; i--) { if (this.selected[ds.getAt(i).id] || (ds.getAt(i).data.selected=='1' && !this.unselected[ds.getAt(i).id]) ) { newSel.push(i); } } this.ignoreSelectionChanges = false; // we now care about preserving selections - second parm = true this.grid.selModel.selectRows(newSel, true); }, // end onViewRefresh
And you have to add the following to both the onSelectionClear and clearSelections methods...Code:// private onRowSelect: function(sm, i, rec) { if (! this.ignoreSelectionChanges) { if (!this.selected[rec.id]) { this.selections.push(rec); this.selected[rec.id] = true; // un-selected management if(this.unselected[rec.id]) { for (var i = this.unselections.length - 1; i >= 0; i--) { if (this.unselections[i].id == rec.id) { this.unselections.splice(i, 1); this.unselected[rec.id] = false; break; } } } } } }, // end onRowSelect // private onRowDeselect: function(sm, i, rec) { if (!this.ignoreSelectionChanges) { // unselected management this.unselections.push(rec); this.unselected[rec.id] = true; if (this.selected[rec.id]) { for (var i = this.selections.length - 1; i >= 0; i--) { if (this.selections[i].id == rec.id) { this.selections.splice(i, 1); this.selected[rec.id] = false; break; } } } } }, // end onRowDeselect
Finally, I used a method similar to the 'selectAll; method which forces the data store to retrieve all records in order to parse the ones that have been selected (thus the hacki-ness of this solution as it requires a known column to use as a marker, as well as a full database read which has the risk of causing a pregnant pause on instantiation)Code:this.unselections = []; this.unselected = {};
Code:/** * Selects all the rows in the grid, including those on other pages * and updates the internal selection model - pruning (splice) the * records that don't belong. * * large data sets could cause slow instantiation */ selectDbItems: function() { var ds = this.grid.getStore(); ds.suspendEvents(); ds.load({ params: {start: 0, limit: ds.getTotalCount() }, callback: function() { this.selections = ds.data.items.slice(0); this.selected = {}; for (var i = this.selections.length - 1; i >= 0; i--) { if(this.selections[i].data.selected=='1') { this.selected[this.selections[i].id] = true; } else { this.selections.splice(i, 1); } }; ds.resumeEvents(); }, scope: this }); } // end selectDbItemsLast edited by Zaphod Beeblebrox; 24 Mar 2011 at 5:24 AM. Reason: missed something
-
15 Aug 2011 11:16 PM #66
hi , first of all thanks for this nice plug in .
i was successfully using your plug in in extjs 3 , but while up grading to extjs 4 i am facing the same problem of selection paging , have u revisit this plugin for Ext JS 4 ?.
please reply .
thanks and regards
-
16 Aug 2011 5:23 AM #67
I haven't had time to implement Ext JS 4 support yet, and am not sure when I will get around to it.
Sorry that I can't offer you anything better than that.
-
17 Aug 2011 3:04 AM #68
i am able to update your plugin compatible with extjs 4 , but facing some problem , u might help me with that ,
Code :
i guess suspendEvents() function is not working properly .HTML Code:selectionPaging = function(config) { Ext.apply(this, config); }; Ext.extend(selectionPaging, Ext.util.Observable, { init: function(grid) { this.grid = grid; this.selections = []; // array of selected records this.selected = {}; // hash mapping record id to selected state this.ignoreSelectionChanges = ''; grid.on('render', function() { // attach an interceptor for the selModel's onRefresh handler this.grid.view.un('refresh', this.grid.selModel.refresh, this.grid.selModel); this.grid.view.on('refresh', this.onViewRefresh, this ); this.grid.view.headerCt.on('headerclick', this.onHeaderClick, this); // add a handler to detect when the user changes the selection this.grid.selModel.on('select', this.onRowSelect, this ); this.grid.selModel.on('select', this.onRowSelect, this ); this.grid.selModel.on('deselect', this.onRowDeselect, this); this.grid.dockedItems.items[1].on('beforechange', this.pageChange, this ); // not sure about this , looking for another way }, this); }, // private onViewRefresh: function() { this.ignoreSelectionChanges = true; // explicitly refresh the selection model this.grid.selModel.refresh(); // selection changed from view updates, restore full selection var ds = this.grid.getStore(); for (var i = ds.getCount() - 1; i >= 0; i--) { if (this.selected[ds.getAt(i).internalId]) { this.grid.selModel.select(i,true,false); } } this.ignoreSelectionChanges = false; }, // end onViewRefresh pageChange: function() { this.ignoreSelectionChanges = true; }, // private onSelectionClear: function() { if (! this.ignoreSelectionChanges) { // selection cleared by user // also called internally when the selection replaces the old selection this.selections = []; this.selected = {}; } }, // end onSelectionClear // private onRowSelect: function(sm,rec,i,o) { if (! this.ignoreSelectionChanges) { if (!this.selected[rec.internalId]) { this.selections.push(rec); this.selected[rec.internalId] = true; } } }, // end onRowSelect onHeaderClick: function(headerCt, header, e) { if (header.isCheckerHd) { e.stopEvent(); var isChecked = header.el.hasCls(Ext.baseCSSPrefix + 'grid-hd-checker-on'); if (isChecked) { // We have to supress the event or it will scrollTo the change this.clearSelections(); } else { // We have to supress the event or it will scrollTo the change this.selectAll(); } } }, // private onRowDeselect: function(sm,rec,i,o){ if (!this.ignoreSelectionChanges) { if (this.selected[rec.internalId]) { for (var i = this.selections.length - 1; i >= 0; i--) { if (this.selections[i].internalId == rec.internalId) { this.selections.splice(i, 1); this.selected[rec.internalId] = false; break; } } } } }, // end onRowDeselect /** * Clears selections across all pages */ clearSelections: function() { this.selections = []; this.selected = {}; this.grid.selModel.deselectAll(); this.onViewRefresh(); }, // end clearSelections /** * Returns the selected records for all pages * @return {Array} Array of selected records */ getSelection: function() { return [].concat(this.selections); }, // end getSelections /** * Selects all the rows in the grid, including those on other pages * Be very careful using this on very large datasets */ selectAll: function() { var ds = this.grid.getStore(); ds.suspendEvents(); ds.load({ //problem is , when i load this store (ds), the store of grid take this new store and reload the data start: 0, limit: ds.getTotalCount() , callback: function() { this.selections = ds.data.items.slice(0); this.selected = {}; for (var i = this.selections.length - 1; i >= 0; i--) { this.selected[this.selections[i].internalId] = true; }; ds.resumeEvents(); this.onViewRefresh(); }, scope: this }); } });
therefore with load of ds in selectAll() , grid renders tha new data .
plz do reply .
thanks and regards
-
17 Aug 2011 11:28 PM #69
I don't know what to advise to you without downloading a copy of Ext 4 and porting it over myself.
I will get around to it at some point, but not soon.
-
18 Aug 2011 4:13 AM #70
Thanks for your concern . For now , i am able to get rid of that error by cloning the grid store
and filling ' selection ' array by loading this cloned store .



Reply With Quote