PDA

View Full Version : How can I use row editing with my grid??



chris24300
8 May 2011, 8:50 AM
I've found links to the row editing plugin but they were on extjs.com and no longer found, I figured 4 has it built in now so I can't use the code from the example..

I don't want to have pop ups asking to edit/add rows. Any help is appreciated!

kendoctor
8 May 2011, 5:17 PM
/*! * Ext JS Library 3.3.1 * Copyright(c) 2006-2010 Sencha Inc. * [email protected] * http://www.sencha.com/license */ Ext.onReady(function(){ Ext.QuickTips.init(); var Employee = Ext.data.Record.create([{ name: 'name', type: 'string' }, { name: 'email', type: 'string' }, { name: 'start', type: 'date', dateFormat: 'n/j/Y' },{ name: 'salary', type: 'float' },{ name: 'active', type: 'bool' }]); // hideous function to generate employee data var genData = function(){ var data = []; var s = new Date(2007, 0, 1); var now = new Date(), i = -1; while(s.getTime() < now.getTime()){ var ecount = Ext.ux.getRandomInt(0, 3); for(var i = 0; i < ecount; i++){ var name = Ext.ux.generateName(); data.push({ start : s.clearTime(true).add(Date.DAY, Ext.ux.getRandomInt(0, 27)), name : name, email: name.toLowerCase().replace(' ', '.') + '@exttest.com', active: true, salary: Math.floor(Ext.ux.getRandomInt(35000, 85000)/1000)*1000 }); } s = s.add(Date.MONTH, 1); } return data; } var store = new Ext.data.GroupingStore({ reader: new Ext.data.JsonReader({fields: Employee}), data: genData(), sortInfo: {field: 'start', direction: 'ASC'} }); var editor = new Ext.ux.grid.RowEditor({ saveText: 'Update' }); var grid = new Ext.grid.GridPanel({ store: store, width: 600, region:'center', margins: '0 5 5 5', autoExpandColumn: 'name', plugins: [editor], view: new Ext.grid.GroupingView({ markDirty: false }), tbar: [{ iconCls: 'icon-user-add', text: 'Add Employee', handler: function(){ var e = new Employee({ name: 'New Guy', email: '[email protected]', start: (new Date()).clearTime(), salary: 50000, active: true }); editor.stopEditing(); store.insert(0, e); grid.getView().refresh(); grid.getSelectionModel().selectRow(0); editor.startEditing(0); } },{ ref: '../removeBtn', iconCls: 'icon-user-delete', text: 'Remove Employee', disabled: true, handler: function(){ editor.stopEditing(); var s = grid.getSelectionModel().getSelections(); for(var i = 0, r; r = s[i]; i++){ store.remove(r); } } }], columns: [ new Ext.grid.RowNumberer(), { id: 'name', header: 'First Name', dataIndex: 'name', width: 220, sortable: true, editor: { xtype: 'textfield', allowBlank: false } },{ header: 'Email', dataIndex: 'email', width: 150, sortable: true, editor: { xtype: 'textfield', allowBlank: false, vtype: 'email' } },{ xtype: 'datecolumn', header: 'Start Date', dataIndex: 'start', format: 'm/d/Y', width: 100, sortable: true, groupRenderer: Ext.util.Format.dateRenderer('M y'), editor: { xtype: 'datefield', allowBlank: false, minValue: '01/01/2006', minText: 'Can\'t have a start date before the company existed!', maxValue: (new Date()).format('m/d/Y') } },{ xtype: 'numbercolumn', header: 'Salary', dataIndex: 'salary', format: '$0,0.00', width: 100, sortable: true, editor: { xtype: 'numberfield', allowBlank: false, minValue: 1, maxValue: 150000 } },{ xtype: 'booleancolumn', header: 'Active', dataIndex: 'active', align: 'center', width: 50, trueText: 'Yes', falseText: 'No', editor: { xtype: 'checkbox' } }] }); var cstore = new Ext.data.JsonStore({ fields:['month', 'employees', 'salary'], data:[], refreshData: function(){ var o = {}, data = []; var s = new Date(2007, 0, 1); var now = new Date(), i = -1; while(s.getTime() < now.getTime()){ var m = { month: s.format('M y'), employees: 0, salary: 0, index: ++i } data.push(m); o[m.month] = m; s = s.add(Date.MONTH, 1); } store.each(function(r){ var m = o[r.data.start.format('M y')]; for(var i = m.index, mo; mo = data[i]; i++){ mo.employees += 10000; mo.salary += r.data.salary; } }); this.loadData(data); } }); cstore.refreshData(); store.on('add', cstore.refreshData, cstore); store.on('remove', cstore.refreshData, cstore); store.on('update', cstore.refreshData, cstore); var chart = new Ext.Panel({ width:600, height:200, layout:'fit', margins: '5 5 0', region: 'north', split: true, minHeight: 100, maxHeight: 500, items: { xtype: 'columnchart', store: cstore, url:'../../resources/charts.swf', xField: 'month', yAxis: new Ext.chart.NumericAxis({ displayName: 'Employees', labelRenderer : Ext.util.Format.numberRenderer('0,0') }), tipRenderer : function(chart, record, index, series){ if(series.yField == 'salary'){ return Ext.util.Format.number(record.data.salary, '$0,0') + ' total salary in ' + record.data.month; }else{ return Ext.util.Format.number(Math.floor(record.data.employees/10000), '0,0') + ' total employees in ' + record.data.month; } }, // style chart so it looks pretty chartStyle: { padding: 10, animationEnabled: true, font: { name: 'Tahoma', color: 0x444444, size: 11 }, dataTip: { padding: 5, border: { color: 0x99bbe8, size:1 }, background: { color: 0xDAE7F6, alpha: .9 }, font: { name: 'Tahoma', color: 0x15428B, size: 10, bold: true } }, xAxis: { color: 0x69aBc8, majorTicks: {color: 0x69aBc8, length: 4}, minorTicks: {color: 0x69aBc8, length: 2}, majorGridLines: {size: 1, color: 0xeeeeee} }, yAxis: { color: 0x69aBc8, majorTicks: {color: 0x69aBc8, length: 4}, minorTicks: {color: 0x69aBc8, length: 2}, majorGridLines: {size: 1, color: 0xdfe8f6} } }, series: [{ type: 'column', displayName: 'Salary', yField: 'salary', style: { image:'../chart/bar.gif', mode: 'stretch', color:0x99BBE8 } }] } }); var layout = new Ext.Panel({ title: 'Employee Salary by Month', layout: 'border', layoutConfig: { columns: 1 }, width:600, height: 600, items: [chart, grid] }); layout.render(Ext.getBody()); grid.getSelectionModel().on('selectionchange', function(sm){ grid.removeBtn.setDisabled(sm.getCount() < 1); }); });



/*! * Ext JS Library 3.3.1 * Copyright(c) 2006-2010 Sencha Inc. * [email protected] * http://www.sencha.com/license */ Ext.ns('Ext.ux.grid'); /** * @class Ext.ux.grid.RowEditor * @extends Ext.Panel * Plugin (ptype = 'roweditor') that adds the ability to rapidly edit full rows in a grid. * A validation mode may be enabled which uses AnchorTips to notify the user of all * validation errors at once. * * @ptype roweditor */ Ext.ux.grid.RowEditor = Ext.extend(Ext.Panel, { floating: true, shadow: false, layout: 'hbox', cls: 'x-small-editor', buttonAlign: 'center', baseCls: 'x-row-editor', elements: 'header,footer,body', frameWidth: 5, buttonPad: 3, clicksToEdit: 'auto', monitorValid: true, focusDelay: 250, errorSummary: true, saveText: 'Save', cancelText: 'Cancel', commitChangesText: 'You need to commit or cancel your changes', errorText: 'Errors', defaults: { normalWidth: true }, initComponent: function(){ Ext.ux.grid.RowEditor.superclass.initComponent.call(this); this.addEvents( /** * @event beforeedit * Fired before the row editor is activated. * If the listener returns <tt>false</tt> the editor will not be activated. * @param {Ext.ux.grid.RowEditor} roweditor This object * @param {Number} rowIndex The rowIndex of the row just edited */ 'beforeedit', /** * @event canceledit * Fired when the editor is cancelled. * @param {Ext.ux.grid.RowEditor} roweditor This object * @param {Boolean} forced True if the cancel button is pressed, false is the editor was invalid. */ 'canceledit', /** * @event validateedit * Fired after a row is edited and passes validation. * If the listener returns <tt>false</tt> changes to the record will not be set. * @param {Ext.ux.grid.RowEditor} roweditor This object * @param {Object} changes Object with changes made to the record. * @param {Ext.data.Record} r The Record that was edited. * @param {Number} rowIndex The rowIndex of the row just edited */ 'validateedit', /** * @event afteredit * Fired after a row is edited and passes validation. This event is fired * after the store's update event is fired with this edit. * @param {Ext.ux.grid.RowEditor} roweditor This object * @param {Object} changes Object with changes made to the record. * @param {Ext.data.Record} r The Record that was edited. * @param {Number} rowIndex The rowIndex of the row just edited */ 'afteredit' ); }, init: function(grid){ this.grid = grid; this.ownerCt = grid; if(this.clicksToEdit === 2){ grid.on('rowdblclick', this.onRowDblClick, this); }else{ grid.on('rowclick', this.onRowClick, this); if(Ext.isIE){ grid.on('rowdblclick', this.onRowDblClick, this); } } // stopEditing without saving when a record is removed from Store. grid.getStore().on('remove', function() { this.stopEditing(false); },this); grid.on({ scope: this, keydown: this.onGridKey, columnresize: this.verifyLayout, columnmove: this.refreshFields, reconfigure: this.refreshFields, beforedestroy : this.beforedestroy, destroy : this.destroy, bodyscroll: { buffer: 250, fn: this.positionButtons } }); grid.getColumnModel().on('hiddenchange', this.verifyLayout, this, {delay:1}); grid.getView().on('refresh', this.stopEditing.createDelegate(this, [])); }, beforedestroy: function() { this.stopMonitoring(); this.grid.getStore().un('remove', this.onStoreRemove, this); this.stopEditing(false); Ext.destroy(this.btns, this.tooltip); }, refreshFields: function(){ this.initFields(); this.verifyLayout(); }, isDirty: function(){ var dirty; this.items.each(function(f){ if(String(this.values[f.id]) !== String(f.getValue())){ dirty = true; return false; } }, this); return dirty; }, startEditing: function(rowIndex, doFocus){ if(this.editing && this.isDirty()){ this.showTooltip(this.commitChangesText); return; } if(Ext.isObject(rowIndex)){ rowIndex = this.grid.getStore().indexOf(rowIndex); } if(this.fireEvent('beforeedit', this, rowIndex) !== false){ this.editing = true; var g = this.grid, view = g.getView(), row = view.getRow(rowIndex), record = g.store.getAt(rowIndex); this.record = record; this.rowIndex = rowIndex; this.values = {}; if(!this.rendered){ this.render(view.getEditorParent()); } var w = Ext.fly(row).getWidth(); this.setSize(w); if(!this.initialized){ this.initFields(); } var cm = g.getColumnModel(), fields = this.items.items, f, val; for(var i = 0, len = cm.getColumnCount(); i < len; i++){ val = this.preEditValue(record, cm.getDataIndex(i)); f = fields[i]; f.setValue(val); this.values[f.id] = Ext.isEmpty(val) ? '' : val; } this.verifyLayout(true); if(!this.isVisible()){ this.setPagePosition(Ext.fly(row).getXY()); } else{ this.el.setXY(Ext.fly(row).getXY(), {duration:0.15}); } if(!this.isVisible()){ this.show().doLayout(); } if(doFocus !== false){ this.doFocus.defer(this.focusDelay, this); } } }, stopEditing : function(saveChanges){ this.editing = false; if(!this.isVisible()){ return; } if(saveChanges === false || !this.isValid()){ this.hide(); this.fireEvent('canceledit', this, saveChanges === false); return; } var changes = {}, r = this.record, hasChange = false, cm = this.grid.colModel, fields = this.items.items; for(var i = 0, len = cm.getColumnCount(); i < len; i++){ if(!cm.isHidden(i)){ var dindex = cm.getDataIndex(i); if(!Ext.isEmpty(dindex)){ var oldValue = r.data[dindex], value = this.postEditValue(fields[i].getValue(), oldValue, r, dindex); if(String(oldValue) !== String(value)){ changes[dindex] = value; hasChange = true; } } } } if(hasChange && this.fireEvent('validateedit', this, changes, r, this.rowIndex) !== false){ r.beginEdit(); Ext.iterate(changes, function(name, value){ r.set(name, value); }); r.endEdit(); this.fireEvent('afteredit', this, changes, r, this.rowIndex); } this.hide(); }, verifyLayout: function(force){ if(this.el && (this.isVisible() || force === true)){ var row = this.grid.getView().getRow(this.rowIndex); this.setSize(Ext.fly(row).getWidth(), Ext.isIE ? Ext.fly(row).getHeight() + 9 : undefined); var cm = this.grid.colModel, fields = this.items.items; for(var i = 0, len = cm.getColumnCount(); i < len; i++){ if(!cm.isHidden(i)){ var adjust = 0; if(i === (len - 1)){ adjust += 3; // outer padding } else{ adjust += 1; } fields[i].show(); fields[i].setWidth(cm.getColumnWidth(i) - adjust); } else{ fields[i].hide(); } } this.doLayout(); this.positionButtons(); } }, slideHide : function(){ this.hide(); }, initFields: function(){ var cm = this.grid.getColumnModel(), pm = Ext.layout.ContainerLayout.prototype.parseMargins; this.removeAll(false); for(var i = 0, len = cm.getColumnCount(); i < len; i++){ var c = cm.getColumnAt(i), ed = c.getEditor(); if(!ed){ ed = c.displayEditor || new Ext.form.DisplayField(); } if(i == 0){ ed.margins = pm('0 1 2 1'); } else if(i == len - 1){ ed.margins = pm('0 0 2 1'); } else{ if (Ext.isIE) { ed.margins = pm('0 0 2 0'); } else { ed.margins = pm('0 1 2 0'); } } ed.setWidth(cm.getColumnWidth(i)); ed.column = c; if(ed.ownerCt !== this){ ed.on('focus', this.ensureVisible, this); ed.on('specialkey', this.onKey, this); } this.insert(i, ed); } this.initialized = true; }, onKey: function(f, e){ if(e.getKey() === e.ENTER){ this.stopEditing(true); e.stopPropagation(); } }, onGridKey: function(e){ if(e.getKey() === e.ENTER && !this.isVisible()){ var r = this.grid.getSelectionModel().getSelected(); if(r){ var index = this.grid.store.indexOf(r); this.startEditing(index); e.stopPropagation(); } } }, ensureVisible: function(editor){ if(this.isVisible()){ this.grid.getView().ensureVisible(this.rowIndex, this.grid.colModel.getIndexById(editor.column.id), true); } }, onRowClick: function(g, rowIndex, e){ if(this.clicksToEdit == 'auto'){ var li = this.lastClickIndex; this.lastClickIndex = rowIndex; if(li != rowIndex && !this.isVisible()){ return; } } this.startEditing(rowIndex, false); this.doFocus.defer(this.focusDelay, this, [e.getPoint()]); }, onRowDblClick: function(g, rowIndex, e){ this.startEditing(rowIndex, false); this.doFocus.defer(this.focusDelay, this, [e.getPoint()]); }, onRender: function(){ Ext.ux.grid.RowEditor.superclass.onRender.apply(this, arguments); this.el.swallowEvent(['keydown', 'keyup', 'keypress']); this.btns = new Ext.Panel({ baseCls: 'x-plain', cls: 'x-btns', elements:'body', layout: 'table', width: (this.minButtonWidth * 2) + (this.frameWidth * 2) + (this.buttonPad * 4), // width must be specified for IE items: [{ ref: 'saveBtn', itemId: 'saveBtn', xtype: 'button', text: this.saveText, width: this.minButtonWidth, handler: this.stopEditing.createDelegate(this, [true]) }, { xtype: 'button', text: this.cancelText, width: this.minButtonWidth, handler: this.stopEditing.createDelegate(this, [false]) }] }); this.btns.render(this.bwrap); }, afterRender: function(){ Ext.ux.grid.RowEditor.superclass.afterRender.apply(this, arguments); this.positionButtons(); if(this.monitorValid){ this.startMonitoring(); } }, onShow: function(){ if(this.monitorValid){ this.startMonitoring(); } Ext.ux.grid.RowEditor.superclass.onShow.apply(this, arguments); }, onHide: function(){ Ext.ux.grid.RowEditor.superclass.onHide.apply(this, arguments); this.stopMonitoring(); this.grid.getView().focusRow(this.rowIndex); }, positionButtons: function(){ if(this.btns){ var g = this.grid, h = this.el.dom.clientHeight, view = g.getView(), scroll = view.scroller.dom.scrollLeft, bw = this.btns.getWidth(), width = Math.min(g.getWidth(), g.getColumnModel().getTotalWidth()); this.btns.el.shift({left: (width/2)-(bw/2)+scroll, top: h - 2, stopFx: true, duration:0.2}); } }, // private preEditValue : function(r, field){ var value = r.data[field]; return this.autoEncode && typeof value === 'string' ? Ext.util.Format.htmlDecode(value) : value; }, // private postEditValue : function(value, originalValue, r, field){ return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value; }, doFocus: function(pt){ if(this.isVisible()){ var index = 0, cm = this.grid.getColumnModel(), c; if(pt){ index = this.getTargetColumnIndex(pt); } for(var i = index||0, len = cm.getColumnCount(); i < len; i++){ c = cm.getColumnAt(i); if(!c.hidden && c.getEditor()){ c.getEditor().focus(); break; } } } }, getTargetColumnIndex: function(pt){ var grid = this.grid, v = grid.view, x = pt.left, cms = grid.colModel.config, i = 0, match = false; for(var len = cms.length, c; c = cms[i]; i++){ if(!c.hidden){ if(Ext.fly(v.getHeaderCell(i)).getRegion().right >= x){ match = i; break; } } } return match; }, startMonitoring : function(){ if(!this.bound && this.monitorValid){ this.bound = true; Ext.TaskMgr.start({ run : this.bindHandler, interval : this.monitorPoll || 200, scope: this }); } }, stopMonitoring : function(){ this.bound = false; if(this.tooltip){ this.tooltip.hide(); } }, isValid: function(){ var valid = true; this.items.each(function(f){ if(!f.isValid(true)){ valid = false; return false; } }); return valid; }, // private bindHandler : function(){ if(!this.bound){ return false; // stops binding } var valid = this.isValid(); if(!valid && this.errorSummary){ this.showTooltip(this.getErrorText().join('')); } this.btns.saveBtn.setDisabled(!valid); this.fireEvent('validation', this, valid); }, lastVisibleColumn : function() { var i = this.items.getCount() - 1, c; for(; i >= 0; i--) { c = this.items.items[i]; if (!c.hidden) { return c; } } }, showTooltip: function(msg){ var t = this.tooltip; if(!t){ t = this.tooltip = new Ext.ToolTip({ maxWidth: 600, cls: 'errorTip', width: 300, title: this.errorText, autoHide: false, anchor: 'left', anchorToTarget: true, mouseOffset: [40,0] }); } var v = this.grid.getView(), top = parseInt(this.el.dom.style.top, 10), scroll = v.scroller.dom.scrollTop, h = this.el.getHeight(); if(top + h >= scroll){ t.initTarget(this.lastVisibleColumn().getEl()); if(!t.rendered){ t.show(); t.hide(); } t.body.update(msg); t.doAutoWidth(20); t.show(); }else if(t.rendered){ t.hide(); } }, getErrorText: function(){ var data = ['<ul>']; this.items.each(function(f){ if(!f.isValid(true)){ data.push('<li>', f.getActiveError(), '</li>'); } }); data.push('</ul>'); return data; } }); Ext.preg('roweditor', Ext.ux.grid.RowEditor);

9 May 2011, 5:05 AM
/*! * Ext JS Library 3.3.1 * Copyright(c) 2006-2010 Sencha Inc. * [email protected] * http://www.sencha.com/license */ Ext.onReady(function(){ Ext.QuickTips.init(); var Employee = Ext.data.Record.create([{ name: 'name', type: 'string' }, { name: 'email', type: 'string' }, { name: 'start', type: 'date', dateFormat: 'n/j/Y' },{ name: 'salary', type: 'float' },{ name: 'active', type: 'bool' }]); // hideous function to generate employee data var genData = function(){ var data = []; var s = new Date(2007, 0, 1); var now = new Date(), i = -1; while(s.getTime() < now.getTime()){ var ecount = Ext.ux.getRandomInt(0, 3); for(var i = 0; i < ecount; i++){ var name = Ext.ux.generateName(); data.push({ start : s.clearTime(true).add(Date.DAY, Ext.ux.getRandomInt(0, 27)), name : name, email: name.toLowerCase().replace(' ', '.') + '@exttest.com', active: true, salary: Math.floor(Ext.ux.getRandomInt(35000, 85000)/1000)*1000 }); } s = s.add(Date.MONTH, 1); } return data; } var store = new Ext.data.GroupingStore({ reader: new Ext.data.JsonReader({fields: Employee}), data: genData(), sortInfo: {field: 'start', direction: 'ASC'} }); var editor = new Ext.ux.grid.RowEditor({ saveText: 'Update' }); var grid = new Ext.grid.GridPanel({ store: store, width: 600, region:'center', margins: '0 5 5 5', autoExpandColumn: 'name', plugins: [editor], view: new Ext.grid.GroupingView({ markDirty: false }), tbar: [{ iconCls: 'icon-user-add', text: 'Add Employee', handler: function(){ var e = new Employee({ name: 'New Guy', email: '[email protected]', start: (new Date()).clearTime(), salary: 50000, active: true }); editor.stopEditing(); store.insert(0, e); grid.getView().refresh(); grid.getSelectionModel().selectRow(0); editor.startEditing(0); } },{ ref: '../removeBtn', iconCls: 'icon-user-delete', text: 'Remove Employee', disabled: true, handler: function(){ editor.stopEditing(); var s = grid.getSelectionModel().getSelections(); for(var i = 0, r; r = s[i]; i++){ store.remove(r); } } }], columns: [ new Ext.grid.RowNumberer(), { id: 'name', header: 'First Name', dataIndex: 'name', width: 220, sortable: true, editor: { xtype: 'textfield', allowBlank: false } },{ header: 'Email', dataIndex: 'email', width: 150, sortable: true, editor: { xtype: 'textfield', allowBlank: false, vtype: 'email' } },{ xtype: 'datecolumn', header: 'Start Date', dataIndex: 'start', format: 'm/d/Y', width: 100, sortable: true, groupRenderer: Ext.util.Format.dateRenderer('M y'), editor: { xtype: 'datefield', allowBlank: false, minValue: '01/01/2006', minText: 'Can\'t have a start date before the company existed!', maxValue: (new Date()).format('m/d/Y') } },{ xtype: 'numbercolumn', header: 'Salary', dataIndex: 'salary', format: '$0,0.00', width: 100, sortable: true, editor: { xtype: 'numberfield', allowBlank: false, minValue: 1, maxValue: 150000 } },{ xtype: 'booleancolumn', header: 'Active', dataIndex: 'active', align: 'center', width: 50, trueText: 'Yes', falseText: 'No', editor: { xtype: 'checkbox' } }] }); var cstore = new Ext.data.JsonStore({ fields:['month', 'employees', 'salary'], data:[], refreshData: function(){ var o = {}, data = []; var s = new Date(2007, 0, 1); var now = new Date(), i = -1; while(s.getTime() < now.getTime()){ var m = { month: s.format('M y'), employees: 0, salary: 0, index: ++i } data.push(m); o[m.month] = m; s = s.add(Date.MONTH, 1); } store.each(function(r){ var m = o[r.data.start.format('M y')]; for(var i = m.index, mo; mo = data[i]; i++){ mo.employees += 10000; mo.salary += r.data.salary; } }); this.loadData(data); } }); cstore.refreshData(); store.on('add', cstore.refreshData, cstore); store.on('remove', cstore.refreshData, cstore); store.on('update', cstore.refreshData, cstore); var chart = new Ext.Panel({ width:600, height:200, layout:'fit', margins: '5 5 0', region: 'north', split: true, minHeight: 100, maxHeight: 500, items: { xtype: 'columnchart', store: cstore, url:'../../resources/charts.swf', xField: 'month', yAxis: new Ext.chart.NumericAxis({ displayName: 'Employees', labelRenderer : Ext.util.Format.numberRenderer('0,0') }), tipRenderer : function(chart, record, index, series){ if(series.yField == 'salary'){ return Ext.util.Format.number(record.data.salary, '$0,0') + ' total salary in ' + record.data.month; }else{ return Ext.util.Format.number(Math.floor(record.data.employees/10000), '0,0') + ' total employees in ' + record.data.month; } }, // style chart so it looks pretty chartStyle: { padding: 10, animationEnabled: true, font: { name: 'Tahoma', color: 0x444444, size: 11 }, dataTip: { padding: 5, border: { color: 0x99bbe8, size:1 }, background: { color: 0xDAE7F6, alpha: .9 }, font: { name: 'Tahoma', color: 0x15428B, size: 10, bold: true } }, xAxis: { color: 0x69aBc8, majorTicks: {color: 0x69aBc8, length: 4}, minorTicks: {color: 0x69aBc8, length: 2}, majorGridLines: {size: 1, color: 0xeeeeee} }, yAxis: { color: 0x69aBc8, majorTicks: {color: 0x69aBc8, length: 4}, minorTicks: {color: 0x69aBc8, length: 2}, majorGridLines: {size: 1, color: 0xdfe8f6} } }, series: [{ type: 'column', displayName: 'Salary', yField: 'salary', style: { image:'../chart/bar.gif', mode: 'stretch', color:0x99BBE8 } }] } }); var layout = new Ext.Panel({ title: 'Employee Salary by Month', layout: 'border', layoutConfig: { columns: 1 }, width:600, height: 600, items: [chart, grid] }); layout.render(Ext.getBody()); grid.getSelectionModel().on('selectionchange', function(sm){ grid.removeBtn.setDisabled(sm.getCount() < 1); }); });



/*! * Ext JS Library 3.3.1 * Copyright(c) 2006-2010 Sencha Inc. * [email protected] * http://www.sencha.com/license */ Ext.ns('Ext.ux.grid'); /** * @class Ext.ux.grid.RowEditor * @extends Ext.Panel * Plugin (ptype = 'roweditor') that adds the ability to rapidly edit full rows in a grid. * A validation mode may be enabled which uses AnchorTips to notify the user of all * validation errors at once. * * @ptype roweditor */ Ext.ux.grid.RowEditor = Ext.extend(Ext.Panel, { floating: true, shadow: false, layout: 'hbox', cls: 'x-small-editor', buttonAlign: 'center', baseCls: 'x-row-editor', elements: 'header,footer,body', frameWidth: 5, buttonPad: 3, clicksToEdit: 'auto', monitorValid: true, focusDelay: 250, errorSummary: true, saveText: 'Save', cancelText: 'Cancel', commitChangesText: 'You need to commit or cancel your changes', errorText: 'Errors', defaults: { normalWidth: true }, initComponent: function(){ Ext.ux.grid.RowEditor.superclass.initComponent.call(this); this.addEvents( /** * @event beforeedit * Fired before the row editor is activated. * If the listener returns <tt>false</tt> the editor will not be activated. * @param {Ext.ux.grid.RowEditor} roweditor This object * @param {Number} rowIndex The rowIndex of the row just edited */ 'beforeedit', /** * @event canceledit * Fired when the editor is cancelled. * @param {Ext.ux.grid.RowEditor} roweditor This object * @param {Boolean} forced True if the cancel button is pressed, false is the editor was invalid. */ 'canceledit', /** * @event validateedit * Fired after a row is edited and passes validation. * If the listener returns <tt>false</tt> changes to the record will not be set. * @param {Ext.ux.grid.RowEditor} roweditor This object * @param {Object} changes Object with changes made to the record. * @param {Ext.data.Record} r The Record that was edited. * @param {Number} rowIndex The rowIndex of the row just edited */ 'validateedit', /** * @event afteredit * Fired after a row is edited and passes validation. This event is fired * after the store's update event is fired with this edit. * @param {Ext.ux.grid.RowEditor} roweditor This object * @param {Object} changes Object with changes made to the record. * @param {Ext.data.Record} r The Record that was edited. * @param {Number} rowIndex The rowIndex of the row just edited */ 'afteredit' ); }, init: function(grid){ this.grid = grid; this.ownerCt = grid; if(this.clicksToEdit === 2){ grid.on('rowdblclick', this.onRowDblClick, this); }else{ grid.on('rowclick', this.onRowClick, this); if(Ext.isIE){ grid.on('rowdblclick', this.onRowDblClick, this); } } // stopEditing without saving when a record is removed from Store. grid.getStore().on('remove', function() { this.stopEditing(false); },this); grid.on({ scope: this, keydown: this.onGridKey, columnresize: this.verifyLayout, columnmove: this.refreshFields, reconfigure: this.refreshFields, beforedestroy : this.beforedestroy, destroy : this.destroy, bodyscroll: { buffer: 250, fn: this.positionButtons } }); grid.getColumnModel().on('hiddenchange', this.verifyLayout, this, {delay:1}); grid.getView().on('refresh', this.stopEditing.createDelegate(this, [])); }, beforedestroy: function() { this.stopMonitoring(); this.grid.getStore().un('remove', this.onStoreRemove, this); this.stopEditing(false); Ext.destroy(this.btns, this.tooltip); }, refreshFields: function(){ this.initFields(); this.verifyLayout(); }, isDirty: function(){ var dirty; this.items.each(function(f){ if(String(this.values[f.id]) !== String(f.getValue())){ dirty = true; return false; } }, this); return dirty; }, startEditing: function(rowIndex, doFocus){ if(this.editing && this.isDirty()){ this.showTooltip(this.commitChangesText); return; } if(Ext.isObject(rowIndex)){ rowIndex = this.grid.getStore().indexOf(rowIndex); } if(this.fireEvent('beforeedit', this, rowIndex) !== false){ this.editing = true; var g = this.grid, view = g.getView(), row = view.getRow(rowIndex), record = g.store.getAt(rowIndex); this.record = record; this.rowIndex = rowIndex; this.values = {}; if(!this.rendered){ this.render(view.getEditorParent()); } var w = Ext.fly(row).getWidth(); this.setSize(w); if(!this.initialized){ this.initFields(); } var cm = g.getColumnModel(), fields = this.items.items, f, val; for(var i = 0, len = cm.getColumnCount(); i < len; i++){ val = this.preEditValue(record, cm.getDataIndex(i)); f = fields[i]; f.setValue(val); this.values[f.id] = Ext.isEmpty(val) ? '' : val; } this.verifyLayout(true); if(!this.isVisible()){ this.setPagePosition(Ext.fly(row).getXY()); } else{ this.el.setXY(Ext.fly(row).getXY(), {duration:0.15}); } if(!this.isVisible()){ this.show().doLayout(); } if(doFocus !== false){ this.doFocus.defer(this.focusDelay, this); } } }, stopEditing : function(saveChanges){ this.editing = false; if(!this.isVisible()){ return; } if(saveChanges === false || !this.isValid()){ this.hide(); this.fireEvent('canceledit', this, saveChanges === false); return; } var changes = {}, r = this.record, hasChange = false, cm = this.grid.colModel, fields = this.items.items; for(var i = 0, len = cm.getColumnCount(); i < len; i++){ if(!cm.isHidden(i)){ var dindex = cm.getDataIndex(i); if(!Ext.isEmpty(dindex)){ var oldValue = r.data[dindex], value = this.postEditValue(fields[i].getValue(), oldValue, r, dindex); if(String(oldValue) !== String(value)){ changes[dindex] = value; hasChange = true; } } } } if(hasChange && this.fireEvent('validateedit', this, changes, r, this.rowIndex) !== false){ r.beginEdit(); Ext.iterate(changes, function(name, value){ r.set(name, value); }); r.endEdit(); this.fireEvent('afteredit', this, changes, r, this.rowIndex); } this.hide(); }, verifyLayout: function(force){ if(this.el && (this.isVisible() || force === true)){ var row = this.grid.getView().getRow(this.rowIndex); this.setSize(Ext.fly(row).getWidth(), Ext.isIE ? Ext.fly(row).getHeight() + 9 : undefined); var cm = this.grid.colModel, fields = this.items.items; for(var i = 0, len = cm.getColumnCount(); i < len; i++){ if(!cm.isHidden(i)){ var adjust = 0; if(i === (len - 1)){ adjust += 3; // outer padding } else{ adjust += 1; } fields[i].show(); fields[i].setWidth(cm.getColumnWidth(i) - adjust); } else{ fields[i].hide(); } } this.doLayout(); this.positionButtons(); } }, slideHide : function(){ this.hide(); }, initFields: function(){ var cm = this.grid.getColumnModel(), pm = Ext.layout.ContainerLayout.prototype.parseMargins; this.removeAll(false); for(var i = 0, len = cm.getColumnCount(); i < len; i++){ var c = cm.getColumnAt(i), ed = c.getEditor(); if(!ed){ ed = c.displayEditor || new Ext.form.DisplayField(); } if(i == 0){ ed.margins = pm('0 1 2 1'); } else if(i == len - 1){ ed.margins = pm('0 0 2 1'); } else{ if (Ext.isIE) { ed.margins = pm('0 0 2 0'); } else { ed.margins = pm('0 1 2 0'); } } ed.setWidth(cm.getColumnWidth(i)); ed.column = c; if(ed.ownerCt !== this){ ed.on('focus', this.ensureVisible, this); ed.on('specialkey', this.onKey, this); } this.insert(i, ed); } this.initialized = true; }, onKey: function(f, e){ if(e.getKey() === e.ENTER){ this.stopEditing(true); e.stopPropagation(); } }, onGridKey: function(e){ if(e.getKey() === e.ENTER && !this.isVisible()){ var r = this.grid.getSelectionModel().getSelected(); if(r){ var index = this.grid.store.indexOf(r); this.startEditing(index); e.stopPropagation(); } } }, ensureVisible: function(editor){ if(this.isVisible()){ this.grid.getView().ensureVisible(this.rowIndex, this.grid.colModel.getIndexById(editor.column.id), true); } }, onRowClick: function(g, rowIndex, e){ if(this.clicksToEdit == 'auto'){ var li = this.lastClickIndex; this.lastClickIndex = rowIndex; if(li != rowIndex && !this.isVisible()){ return; } } this.startEditing(rowIndex, false); this.doFocus.defer(this.focusDelay, this, [e.getPoint()]); }, onRowDblClick: function(g, rowIndex, e){ this.startEditing(rowIndex, false); this.doFocus.defer(this.focusDelay, this, [e.getPoint()]); }, onRender: function(){ Ext.ux.grid.RowEditor.superclass.onRender.apply(this, arguments); this.el.swallowEvent(['keydown', 'keyup', 'keypress']); this.btns = new Ext.Panel({ baseCls: 'x-plain', cls: 'x-btns', elements:'body', layout: 'table', width: (this.minButtonWidth * 2) + (this.frameWidth * 2) + (this.buttonPad * 4), // width must be specified for IE items: [{ ref: 'saveBtn', itemId: 'saveBtn', xtype: 'button', text: this.saveText, width: this.minButtonWidth, handler: this.stopEditing.createDelegate(this, [true]) }, { xtype: 'button', text: this.cancelText, width: this.minButtonWidth, handler: this.stopEditing.createDelegate(this, [false]) }] }); this.btns.render(this.bwrap); }, afterRender: function(){ Ext.ux.grid.RowEditor.superclass.afterRender.apply(this, arguments); this.positionButtons(); if(this.monitorValid){ this.startMonitoring(); } }, onShow: function(){ if(this.monitorValid){ this.startMonitoring(); } Ext.ux.grid.RowEditor.superclass.onShow.apply(this, arguments); }, onHide: function(){ Ext.ux.grid.RowEditor.superclass.onHide.apply(this, arguments); this.stopMonitoring(); this.grid.getView().focusRow(this.rowIndex); }, positionButtons: function(){ if(this.btns){ var g = this.grid, h = this.el.dom.clientHeight, view = g.getView(), scroll = view.scroller.dom.scrollLeft, bw = this.btns.getWidth(), width = Math.min(g.getWidth(), g.getColumnModel().getTotalWidth()); this.btns.el.shift({left: (width/2)-(bw/2)+scroll, top: h - 2, stopFx: true, duration:0.2}); } }, // private preEditValue : function(r, field){ var value = r.data[field]; return this.autoEncode && typeof value === 'string' ? Ext.util.Format.htmlDecode(value) : value; }, // private postEditValue : function(value, originalValue, r, field){ return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value; }, doFocus: function(pt){ if(this.isVisible()){ var index = 0, cm = this.grid.getColumnModel(), c; if(pt){ index = this.getTargetColumnIndex(pt); } for(var i = index||0, len = cm.getColumnCount(); i < len; i++){ c = cm.getColumnAt(i); if(!c.hidden && c.getEditor()){ c.getEditor().focus(); break; } } } }, getTargetColumnIndex: function(pt){ var grid = this.grid, v = grid.view, x = pt.left, cms = grid.colModel.config, i = 0, match = false; for(var len = cms.length, c; c = cms[i]; i++){ if(!c.hidden){ if(Ext.fly(v.getHeaderCell(i)).getRegion().right >= x){ match = i; break; } } } return match; }, startMonitoring : function(){ if(!this.bound && this.monitorValid){ this.bound = true; Ext.TaskMgr.start({ run : this.bindHandler, interval : this.monitorPoll || 200, scope: this }); } }, stopMonitoring : function(){ this.bound = false; if(this.tooltip){ this.tooltip.hide(); } }, isValid: function(){ var valid = true; this.items.each(function(f){ if(!f.isValid(true)){ valid = false; return false; } }); return valid; }, // private bindHandler : function(){ if(!this.bound){ return false; // stops binding } var valid = this.isValid(); if(!valid && this.errorSummary){ this.showTooltip(this.getErrorText().join('')); } this.btns.saveBtn.setDisabled(!valid); this.fireEvent('validation', this, valid); }, lastVisibleColumn : function() { var i = this.items.getCount() - 1, c; for(; i >= 0; i--) { c = this.items.items[i]; if (!c.hidden) { return c; } } }, showTooltip: function(msg){ var t = this.tooltip; if(!t){ t = this.tooltip = new Ext.ToolTip({ maxWidth: 600, cls: 'errorTip', width: 300, title: this.errorText, autoHide: false, anchor: 'left', anchorToTarget: true, mouseOffset: [40,0] }); } var v = this.grid.getView(), top = parseInt(this.el.dom.style.top, 10), scroll = v.scroller.dom.scrollTop, h = this.el.getHeight(); if(top + h >= scroll){ t.initTarget(this.lastVisibleColumn().getEl()); if(!t.rendered){ t.show(); t.hide(); } t.body.update(msg); t.doAutoWidth(20); t.show(); }else if(t.rendered){ t.hide(); } }, getErrorText: function(){ var data = ['<ul>']; this.items.each(function(f){ if(!f.isValid(true)){ data.push('<li>', f.getActiveError(), '</li>'); } }); data.push('</ul>'); return data; } }); Ext.preg('roweditor', Ext.ux.grid.RowEditor);


Are you serious!?!?

9 May 2011, 5:06 AM
I've found links to the row editing plugin but they were on extjs.com and no longer found, I figured 4 has it built in now so I can't use the code from the example..

I don't want to have pop ups asking to edit/add rows. Any help is appreciated!
You posted your question in the ext js 3 forums.

If for Ext JS 4, there is a rowediting example you can follow.

chris24300
10 May 2011, 3:13 AM
I need it for 3, I figure 4 has this built in now and I can't use it.

chris24300
10 May 2011, 4:42 AM
thanks for the code kendoctor, can you tell me what the first file is for? Eclipse won't format the code for me and it's all on one line... I see the second code is the ext.ux.gridRowEditor. Do I need both or can I use the second code you posted? Not sure if the first one is an example usage or not, doesn't declare the class like the second one does.

Thanks!