PDA

View Full Version : Help! editing grid rows with popup form



FreeBaseBuzz
13 Jan 2010, 7:50 PM
Hi, I'm trying to do a grid with a popup form for editing or adding rows.

pretty much followed the 3.0 version of the example here
http://www.extjs.com/deploy/dev/examples/writer/writer.html

however, Somehow I've screwed up how the form updates the record in the grid when altering the code to go from a form on the same page, to a form in a popup. I mean, it should work exactly the same, but I've somehow broken it.

Can someone tell me what i'm doing wrong?




Ext.ns('App', 'App.trainingItem');

var _Debug = true, _UseConsole = true, _UsePopups = true;
function myAlert(value) {
if (_Debug) {
if ((_UseConsole) && (window.console)) {
console.log(value);
} else if (_UsePopups) {
alert(value);
}
}
}

// Create HttpProxy instance. Notice new configuration parameter "api" here instead of load. However, you can still use
// the "url" paramater -- All CRUD requests will be directed to your single url instead.
var proxy = new Ext.data.HttpProxy({
api: {
read : 'index.cfm?event=mng.training-plan.template.item.list.grid',
create : 'index.cfm?event=mng.training-plan.template.item.list.create',
update : 'index.cfm?event=mng.training-plan.template.item.list.update',
destroy : 'index.cfm?event=mng.training-plan.template.item.list.destroy'
}
});

// Typical JsonReader. Notice additional meta-data params for defining the core attributes of your json-response
var reader = new Ext.data.JsonReader({
idProperty: 'ITEMID',
root: 'ITEMS',
}, [
{name: 'ARCHIVEDATE', mapping: 'ARCHIVEDATE', type: 'date', dateFormat: 'c'},
'CREATEDBYEMAIL',
'CREATEDBYFIRSTNAME',
'CREATEDBYGROUPID',
'CREATEDBYGROUPNAME',
'CREATEDBYLASTNAME',
'CREATEDBYPARENTGROUPNAME',
'CREATEDBYPARENTGROUPID',
'CREATEDBYUSERNAME',
'CREATEDBYROLE',
'CREATEDBYID',
{name: 'CREATIONDATE', mapping: 'CREATIONDATE', type: 'date', dateFormat: 'c'},
'INTERNALCOURSECODE',
'INTERNALCOURSEID',
'INTERNALCOURSENAME',
'INTERNALCOURSEPROVIDERNAME',
'INTERNALCOURSEPROVIDERID',
'INTERNALCOURSEPROVIDERTYPE',
'ISEXTERNALTRAINING',
'ITEMID',
'TPTEMPLATEDESCRIPTION',
'TPTEMPLATEID',
'TPTEMPLATENAME',
'TRAININGPLANCREATEDBYID',
'TRAININGPLANCREATEDBYROLE',
{name: 'TRAININGPLANCREATIONDATE', mapping: 'TRAININGPLANCREATIONDATE', type: 'date', dateFormat: 'c'}
]);

// The new DataWriter component.
var writer = new Ext.data.JsonWriter({
encode: true,
writeAllFields: false
});

// Typical Store collecting the Proxy, Reader and Writer together.
var store = new Ext.data.Store({
id: 'trainingTemplateItemsStore',
proxy: proxy,
reader: reader,
writer: writer, // <-- plug a DataWriter into the store just as you would a Reader
autoSave: false, // <-- false would delay executing create, update, destroy requests until specifically told to do so with some [save] buton.
//batch: true,
listeners: {
write : function(store, action, result, res, rs) {
App.setAlert(res.success, res.message); // <-- show user-feedback for all write actions
},
exception : function(proxy, type, action, options, res, arg) {
if (type === 'remote') {
Ext.Msg.show({
title: 'REMOTE EXCEPTION',
msg: res.message,
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK
});
}
}
}
});

// A new generic text field
var textField = new Ext.form.TextField();
/**
* @class App.trainingItem.FormPanel
* A typical FormPanel extension
*/
App.trainingItem.Form = Ext.extend(Ext.form.FormPanel, {
labelAlign: 'right',
frame: true,
border: false,
width: 500,
defaultType: 'textfield',
defaults: {
anchor: '100%'
},

// private A pointer to the currently loaded record
record : null,

/**
* initComponent
* @protected
*/
initComponent : function() {
// build the form-fields. Always a good idea to defer form-building to a method so that this class can
// be over-ridden to provide different form-fields
this.items = this.buildForm();

// build form-buttons
this.buttons = this.buildUI();

// add a create event for convenience in our application-code.
this.addEvents({
/**
* @event create
* Fires when trainingItem clicks [create] button
* @param {FormPanel} this
* @param {Object} values, the Form's values object
*/
create : true
});

// super
App.trainingItem.Form.superclass.initComponent.call(this);
},

/**
* buildform
* @private
*/

buildForm : function() {
var trainType = new Ext.form.RadioGroup({
name: 'ISEXTERNALTRAINING',
id: 'ISEXTERNALTRAINING',
columns: 1,
items: [{
boxLabel: 'Internal Course', name: 'TrainingType', inputValue: 0, checked: true
}, {
boxLabel: 'External Course', name: 'TrainingType', inputValue: 1
}],
listeners:{
change:{fn:function(radiogroup, radio) {
this.ownerCt.getForm().findField('provider-combo').clearValue();
this.ownerCt.getForm().findField('provider-combo').store.load({params:{ProviderType: radio.getGroupValue()}});
}}
}
});

var comboProvider = new Ext.form.ComboBox({
name: 'INTERNALCOURSEPROVIDERNAME',
fieldLabel: 'Provider',
xtype: 'combo',
id: 'provider-combo',
triggerAction: 'all',
width: 220,
forceSelection: true,
lazyRender:true,
mode: 'local',
store: new Ext.data.JsonStore({
autoDestroy: true,
autoLoad: {
params: {
providerType: 0
}
},
url: 'index.cfm?event=mng.training-plan.template.provider.list',
waitMsg: 'Loading...',
root: 'ITEMS',
fields: ['GROUPNAME','GROUPID']
}),
displayField:'GROUPNAME',
valueField:'GROUPID',
emptyText:'Select a Provider',
listeners:{
select:{fn:function(combo, value) {
this.ownerCt.getForm().findField('course-combo').clearValue();
this.ownerCt.getForm().findField('course-combo').store.load({params:{ProviderId: combo.getValue()}});
}}
}
});

var comboCourse = new Ext.form.ComboBox({
name: 'INTERNALCOURSENAME',
fieldLabel: 'Course',
xtype: 'combo',
id: 'course-combo',
width: 220,
forceSelection: true,
lazyRender:true,
mode: 'local',
emptyText:'Select a Course',
listEmptyText: 'No courses for this Provider',
store: new Ext.data.JsonStore({
autoDestroy: true,
url: 'index.cfm?event=mng.training-plan.template.course.list',
waitMsg: 'Loading...',
root: 'ITEMS',
fields: ['INDUCTIONID','INDUCTIONNAME', 'COURSECODE', 'INDUCTIONDESCRIPTION']
}),
displayField:'INDUCTIONNAME',
valueField:'INDUCTIONID',
});

return [
trainType,
comboProvider,
comboCourse,
{fieldLabel: 'Details', xtype: 'textarea', name: 'DETAILS', id: 'detailfield', width: 220, height: 100}
];
},

/**
* buildUI
* @private
*/
buildUI: function(){
return [{
text: 'Save',
iconCls: 'icon-save',
handler: this.onUpdate,
scope: this
}, {
text: 'Create',
iconCls: 'silk-trainingItem-add',
handler: this.onCreate,
scope: this
}, {
text: 'Cancel',
handler: this.onCancel,
scope: this
}];
},

/**
* loadRecord
* @param {Record} rec
*/
loadRecord : function(rec) {
this.record = rec;
this.getForm().loadRecord(rec);
},

/**
* onUpdate
*/
onUpdate : function(btn, ev) {
// App.trainingItem.Grid.fireEvent('update', this, this.getForm().getValues());
this.fireEvent('update', this, this.getForm().getValues());

// for some reason using the code below triggered the too much recursion error.
// if (this.record == null) {
// return;
// }
// if (!this.getForm().isValid()) {
// App.setAlert(false, "Form is invalid.");
// return false;
// }
// this.getForm().updateRecord(this.record);
},

/**
* onCreate
*/
onCreate : function(btn, ev) {
if (!this.getForm().isValid()) {
App.setAlert(false, "Form is invalid");
return false;
}
this.fireEvent('create', this, this.getForm().getValues());
this.getForm().reset();
},

/**
* onCancel
*/
onCancel : function(btn, ev) {
this.getForm().reset();
this.ownerCt.hide();
}
});

/**
* App.trainingItem.Grid
* A typical EditorGridPanel extension.
*/
App.trainingItem.Grid = Ext.extend(Ext.grid.EditorGridPanel, {
frame: true,
title: 'trainingItems',
height: 300,
width: 800,
style: 'margin-top: 10px',

initComponent : function() {

// typical viewConfig
this.viewConfig = {
forceFit: true
};

// relay the Store's CRUD events into this grid so these events can be conveniently listened-to in our application-code.
this.relayEvents(this.store, ['destroy', 'save', 'update']);

// build toolbars and buttons.
this.tbar = this.buildTopToolbar();
this.buttons = this.buildUI();
// super
App.trainingItem.Grid.superclass.initComponent.call(this);
},

/**
* buildTopToolbar
*/
buildTopToolbar : function() {
return [{
text: 'Add',
iconCls: 'silk-add',
handler: this.onAdd,
scope: this
}, '-', {
text: 'Delete',
iconCls: 'silk-delete',
handler: this.onDelete,
scope: this
}, '-'];
},

/**
* buildUI
*/
buildUI : function() {
return [{
text: 'Save',
iconCls: 'icon-save',
handler: this.onSave,
scope: this
}];
},

/**
* onSave
*/
onSave : function(btn, ev) {
this.store.save();
},

/**
* onAdd
*/
onAdd : function(btn, ev) {
this.fireEvent('addnew', this, this.getForm().getValues());

// var u = new this.store.recordType({
// first : '',
// last: '',
// email : ''
// });
// this.stopEditing();
// this.store.insert(0, u);
// this.startEditing(0, 1);
},

/**
* onDelete
*/
onDelete : function(btn, ev) {
var index = this.getSelectionModel().getSelectedCell();
if (!index) {
return false;
}
var rec = this.store.getAt(index[0]);
this.store.remove(rec);
}
});


Ext.onReady(function() {
Ext.QuickTips.init();

var PlanID = Ext.get('tpid').getValue();
store.load({params:{trainingPlanID: PlanID}});
// create trainingItem.Form instance
var trainingItemForm = new App.trainingItem.Form({
id: 'trainingItemForm',
listeners: {
create : function(fpanel, data) { // <-- custom "create" event defined in App.trainingItem.Form class
var rec = new trainingItemGrid.store.recordType(data);
trainingItemGrid.store.insert(trainingItemGrid.store.getCount(), rec);
},
update : function(fpanel, data) { // <-- custom "update" event defined in App.trainingItem.Form class
myAlert('updateFired' + data);
var index = trainingItemGrid.getSelectionModel().getSelectedCell();
if (!index) {
return false;
}
var rec = trainingItemGrid.store.getAt(index[0]);
rec.beginEdit();
rec.set(data);
rec.endEdit();
}
}
});

var rowactions = new Ext.ux.grid.RowActions({
header: 'Actions',
keepSelection: true,
width: 150,
actions: [{
iconCls: 'icon-edit',
qtip:'Edit Template'
}, {
iconCls: 'icon-archive',
qtip:'Delete Template'
}
],
listeners:{
action: function (grid, record, action, row, col) {
if (action == 'icon-edit'){
grid.fireEvent('rowdblclick', grid, row, action);
} else if (action == 'icon-archive'){
grid.getSelectionModel().selectRow(row);
Ext.MessageBox.confirm('Message', 'Do you really want to delete this template item?' , doDel);
}
}
}
});

var trainingItemColumns = [
rowactions,
{
header: "INTERNALCOURSENAME",
dataIndex: 'INTERNALCOURSENAME',
width: 180,
sortable: true
}, {
header: "INTERNALCOURSEID",
dataIndex: 'INTERNALCOURSEID',
width: 180,
sortable: true
}, {
header: "ISEXTERNALTRAINING",
dataIndex: 'ISEXTERNALTRAINING',
width: 180,
sortable: false
}, {
header: "INTERNALCOURSEPROVIDERNAME",
dataIndex: 'INTERNALCOURSEPROVIDERNAME',
width: 180,
sortable: false
}, {
header: "CREATEDBYUSERNAME",
dataIndex: 'CREATEDBYUSERNAME',
width: 180,
sortable: false
}, {
header: "CREATIONDATE",
dataIndex: 'CREATIONDATE',
width: 180,
sortable: false
}
];

// create trainingItem.Grid instance
var trainingItemGrid = new App.trainingItem.Grid({
renderTo: 'TemplateItems',
store: store,
columns: trainingItemColumns,
plugins: rowactions,
listeners: {
rowdblclick: function(g, index, ev) {
var rec = g.store.getAt(index);
editWindow.show();
trainingItemForm.loadRecord(rec);
},
rowclick: function(g, index, ev) {
var rec = g.store.getAt(index);
trainingItemForm.loadRecord(rec);
},
destroy : function() {
trainingItemForm.getForm().reset();
},
addnew : function() {
editWindow.show();
trainingItemForm.getForm().reset();
}
}
});

var editWindow = new Ext.Window({
title: 'trainingItem -- All fields are required',
layout:'fit',
//width:400,
height:300,
closeAction:'hide',
plain: true,
autoScroll: true,
items: trainingItemForm
});


});