-
1 Mar 2009 1:20 PM #1
Dirty Stores and Clean EditorGrids Fields
Dirty Stores and Clean EditorGrids Fields
Hi,
The EditorGrid tracks edits when users make changes to individual fields, you can see a little red spot in the top right.
These changes are stored in the store/record in the modified object.
In cases where a store record is updated the EditorGrid will also refresh the row the UI using the editorGrid.refreshRow method.
That refreshRow method creates a new row without a red spot in the top right.
The store still has dirty records which is good however the UI doesn't represent the dirty records.
Looks like a bug, but haven't seen anything on it, has anyone noticed this?
J
-
1 Mar 2009 2:00 PM #2
Looks like it should account for dirty cells will need to look into this more.
Code:doRender : function(cs, rs, ds, startRow, colCount, stripe){ var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1; var tstyle = 'width:'+this.getTotalWidth()+';'; var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r; for(var j = 0, len = rs.length; j < len; j++){ r = rs[j]; cb = []; var rowIndex = (j+startRow); for(var i = 0; i < colCount; i++){ c = cs[i]; p.id = c.id; p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : ''); p.attr = p.cellAttr = ""; p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds); p.style = c.style; if(p.value == undefined || p.value === "") p.value = "Â "; if(r.dirty && typeof r.modified[c.name] !== 'undefined'){ p.css += ' x-grid3-dirty-cell'; } cb[cb.length] = ct.apply(p); } var alt = []; if(stripe && ((rowIndex+1) % 2 == 0)){ alt[0] = "x-grid3-row-alt"; } if(r.dirty){ alt[1] = " x-grid3-dirty-row"; } rp.cols = colCount; if(this.getRowClass){ alt[2] = this.getRowClass(r, rowIndex, rp, ds); } rp.alt = alt.join(" "); rp.cells = cb.join(""); buf[buf.length] = rt.apply(rp); } return buf.join("");
-
1 Mar 2009 6:25 PM #3
Ahh I figured it out, ExtJS is dropping the modified object /edited information every time you begin a new edit.....
Is this expected behavior for ExtJS, possibly a bug?
M app is uses an editorGrid with a bound form, the form and the editorGrid share the same source. When the form is updated it triggers a beginEdit via form.updateRecord(record)
Before - extjs will drop all previous edits when you begin a new edit
Possible solution - keep all edits until they are committedCode:Ext.data.Record.prototype = { ..... beginEdit : function(){ this.editing = true; this.modified = {}; },
Anyone think this is a bug? Or should I just override the behavior for my application?Code:beginEdit : function(){ this.editing = true; if(!this.modified){ this.modified = {}; } },
-
2 Mar 2009 6:30 AM #4
Might be considered a bug, but to advance it you should make a working showcase to illustrate. Maybe use one of the editor grid demos as a base to illustrate your point?
MJ
API Search || Ext 3: docs-demo-upgrade guide || User Extension Repository
Frequently Asked Questions: FAQs
Tutorial: Grid (php/mysql/json) , Application Design and Structure || Extensions: MetaGrid, MessageWindow
-
2 Mar 2009 11:58 AM #5
Will endeavor to put up a working example in the next couple of days.
Tried to throw something together using one of the examples this morning but having a bit of trouble even getting it together. It requires a panel, form, grid.
I'm developing using Saki's big application model, so have split everything out.
Will come up with something easy and simple, maybe just post the split out bits.
-
2 Mar 2009 12:23 PM #6
MJ
API Search || Ext 3: docs-demo-upgrade guide || User Extension Repository
Frequently Asked Questions: FAQs
Tutorial: Grid (php/mysql/json) , Application Design and Structure || Extensions: MetaGrid, MessageWindow
-
2 Mar 2009 1:01 PM #7
Ok here's the sample,
viewport - container for editorgrid(plant sample) & form(modified simpleform sample)
you'll need the plants.xml from the plants sample too
http://extjs.com/deploy/dev/examples/grid/plants.xml
The form & grid share a store, so the idea is that the form is a helper for the editorgrid.
Try changing values on the grid, you'll notice the little red change identifiers in the cells.
Then go put a value in the form and hit save, by hitting the 'Update Shared Store' button the form attempts to update the specific record in the store
This updates the store with the field light value and drops all the other modified changes.Code:Ext.getCmp('myform').getForm().updateRecord(record);
Then the editorgrid refreshes itself because the store is updated.
It drops the red dots in the corners, because at the begin of a store edit the modified object is recreated.
Code:Ext.ns('SampleApp.ViewPort'); var fm = Ext.form; SampleApp.ViewPort.Sample = Ext.extend(Ext.Viewport,{ title: 'Sample Grid n Bound Form edit issue', layout: 'border', border:true , constructor: function(config) { Ext.apply(this,{ defaults: { collapsible: false, split: true, border:true }, items:[{ region:'east', layout:'fit', width: 300, items:[config.form] },{ region:'center', layout:'fit', items:[config.grid] }], }); SampleApp.ViewPort.Sample.superclass.constructor.apply(this,arguments); }, initComponent:function() { SampleApp.ViewPort.Sample.superclass.initComponent.apply(this,arguments); }, onRender:function() { SampleApp.ViewPort.Sample.superclass.onRender.apply(this,arguments); }, }); Ext.grid.CheckColumn = function(config){ Ext.apply(this, config); if(!this.id){ this.id = Ext.id(); } this.renderer = this.renderer.createDelegate(this); }; Ext.grid.CheckColumn.prototype ={ init : function(grid){ this.grid = grid; this.grid.on('render', function(){ var view = this.grid.getView(); view.mainBody.on('mousedown', this.onMouseDown, this); }, this); }, onMouseDown : function(e, t){ if(t.className && t.className.indexOf('x-grid3-cc-'+this.id) != -1){ e.stopEvent(); var index = this.grid.getView().findRowIndex(t); var record = this.grid.store.getAt(index); record.set(this.dataIndex, !record.data[this.dataIndex]); } }, renderer : function(v, p, record){ p.css += ' x-grid3-check-col-td'; return '<div class="x-grid3-check-col'+(v?'-on':'')+' x-grid3-cc-'+this.id+'"> </div>'; } }; Ext.onReady(function(){ Ext.ns('SampleApp', 'SampleApp.form', 'SampleApp.data'); Ext.QuickTips.init(); Ext.BLANK_IMAGE_URL = './ext-2.1/resources/images/default/s.gif'; function formatDate(value){ return value ? value.dateFormat('M d, Y') : ''; }; // shorthand alias var fm = Ext.form; // custom column plugin example var checkColumn = new Ext.grid.CheckColumn({ header: "Indoor?", dataIndex: 'indoor', width: 55 }); // the column model has information about grid columns // dataIndex maps the column to the specific data field in // the data store (created below) var cm = new Ext.grid.ColumnModel([{ id:'common', header: "Common Name", dataIndex: 'common', width: 220, editor: new fm.TextField({ allowBlank: false }) },{ header: "Price", dataIndex: 'price', width: 70, align: 'right', renderer: 'usMoney', editor: new fm.NumberField({ allowBlank: false, allowNegative: false, maxValue: 100000 }) },{ header: "Available", dataIndex: 'availDate', width: 95, renderer: formatDate, editor: new fm.DateField({ format: 'm/d/y', minValue: '01/01/06', disabledDays: [0, 6], disabledDaysText: 'Plants are not available on the weekends' }) }, checkColumn ]); // by default columns are sortable cm.defaultSortable = true; // this could be inline, but we want to define the Plant record // type so we can add records dynamically var Plant = Ext.data.Record.create([ // the "name" below matches the tag name to read, except "availDate" // which is mapped to the tag "availability" {name: 'common', type: 'string'}, {name: 'botanical', type: 'string'}, {name: 'light'}, {name: 'price', type: 'float'}, // automatic date conversions {name: 'availDate', mapping: 'availability', type: 'date', dateFormat: 'm/d/Y'}, {name: 'indoor', type: 'bool'} ]); // create the Data Store var store = new Ext.data.Store({ // load using HTTP url: 'plants.xml', // the return will be XML, so lets set up a reader reader: new Ext.data.XmlReader({ // records will have a "plant" tag record: 'plant' }, Plant), sortInfo:{field:'common', direction:'ASC'} }); // create the editor grid var grid = new Ext.grid.EditorGridPanel({ id:'eg', store: store, cm: cm, width:600, height:300, autoExpandColumn:'common', title:'Edit Plants?', frame:true, plugins:checkColumn, clicksToEdit:1, tbar: [{ text: 'Add Plant', handler : function(){ var p = new Plant({ common: 'New Plant 1', light: 'Mostly Shade', price: 0, availDate: (new Date()).clearTime(), indoor: false }); grid.stopEditing(); store.insert(0, p); grid.startEditing(0, 0); } }] }); // trigger the data store load store.load(); var form = new Ext.FormPanel({ id:'myform', labelWidth: 75, // label settings here cascade unless overridden frame:true, title: 'Simple Form', bodyStyle:'padding:5px 5px 0', width: 350, defaults: {width: 230}, defaultType: 'textfield', items: [{ fieldLabel: 'light', name: 'light', allowBlank:false }], buttons: [{ text: 'Update Shared Store', handler:function(){ eg = Ext.getCmp('eg'); egStore = eg.getStore(); var egsm = eg.getSelectionModel(); cellIndx = egsm.getSelectedCell(); //alert('update timeform row' + cellIndx[0]); if(cellIndx){ record = egStore.getAt(cellIndx[0]); Ext.getCmp('myform').getForm().updateRecord(record); } }, scope:this }] }); var sampleApp = new SampleApp.ViewPort.Sample({grid:grid,form:form}); sampleApp.show(); });


Reply With Quote