PDA

View Full Version : Edit newly created grid record, someone save me from jumping off a bridge



brokentwig
28 Sep 2011, 7:43 PM
I have a grid with RowEditor plugin enabled. I'm using autoSync() since I can't find an easy way to reference the "Update" button on the editor. I'm having trouble adding a record, and then opening the editor on the new record. The view, and edit work great. When I click the Add button, the createRecord fuction fires and I can reference the grid using this.getGrid(). I just can't put together an insert/edit function to save my life. I've searched and tried so many different examples that Google has banned me. I'm hoping someone smarter than I can look at my View and Controller and suggest a solution (createRecord function is located at bottom of controller):

Here's my view:


Ext.define('MyIpSys.view.IpNetworkView' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.ipnetworkview',
margin: 0,
border: 1,
store: 'IpNetworkStore',
selType: 'rowmodel',

dockedItems: [{
xtype: 'toolbar',
items: [{
iconCls: 'add',
text: 'Add',
action: 'add'
}, {
iconCls: 'delete',
text: 'Delete',
disabled: true,
itemId: 'delete',
action: 'delete'
}]
}],

columns: [
{
header: 'Network Name',
dataIndex: 'network_name',
editor: 'textfield',
flex: 1,
minWidth: 100
},
{
header: 'Subnet',
dataIndex: 'network_subnet',
editor: 'textfield',
flex: 1,
minWidth: 100
},
{
header: 'Mask',
dataIndex: 'network_mask',
editor: 'textfield',
flex: 1,
minWidth: 100
},
{
header: 'Gateway',
dataIndex: 'network_gateway',
editor: 'textfield',
flex: 1,
minWidth: 100
},
{
header: 'Campus Name',
dataIndex: 'campus_id',
flex: 1,
minWidth: 100,
renderer: comboCampusRenderer,
editor: {
xtype: 'combobox',
store: 'IpCampusStore',
allowBlank: false,
queryMode: 'local',
typeAhead: true,
displayField: 'campus_name',
forceSelection: true,
valueField: 'id',
triggerAction : 'all',
emptyText: 'Select a campus...'
}
},
{
header: 'Network Type',
dataIndex: 'network_type_id',
flex: 1,
minWidth: 100,
renderer: comboNetworkTypeRenderer,
editor: {
xtype: 'combobox',
store: 'IpNetworkTypeStore',
allowBlank: false,
queryMode: 'local',
typeAhead: true,
displayField: 'network_type_name',
forceSelection: true,
valueField: 'id',
triggerAction : 'all',
emptyText: 'Select a type...'
}
}
],

initComponent: function() {

this.editor = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 2
});

Ext.apply(this, {
plugins: [this.editor]
});

this.callParent(arguments);

}
});

And my controller:


Ext.define('MyIpSys.controller.IpNetworkController', {
extend : 'Ext.app.Controller',

stores : ['IpNetworkStore'],
models : ['IpNetworkModel'],

views : [
'IpNetworkView'
],

refs:[
{ ref: 'grid', selector: 'gridpanel'},
{ ref: 'view', selector: 'ipnetworkview'}
],

init: function() {

this.control({
'ipnetworkview' : {
show: this.loadList
},

'ipnetworkview button[action=add]': {
click: this.createNetwork
}

});


},

// Reload the list every time it is shown
loadList : function(list) {
list.getStore().load();
},

createNetwork: function(button) {
//Grid can be access by this.getGrid()
//Insert new record,
// this.getGrid().store.insert({},0); works fine to add a record //Json post has record id=0, but I can either return a success: true, or create a new
record and return the new id. Not sure what to do with it.
//(get new ID from json_response?),
//select record (Id from grid, or id =0, or ID from json?),
//editStart on new record
}
});

fschaeffer
28 Sep 2011, 9:41 PM
Hello,

we're using a REST store for this and setting presence-option in Model disables the first post to the server.

So we have

Model


validations: [
{type: 'presence', field: 'user_id'}
]

Store


Ext.define('BII.store.GroupUsers', {
extend: 'Ext.data.Store',
model: 'BII.model.GroupUser',
autoSync: true,

proxy: {
type: 'rest',
url : 'data/mod/rightsmanager/groupUser',
reader: {
type: 'json',
root: 'data'
},
writer: {
writeAllFields: false
}
},
autoLoad: false
});

Controller


onButtonClick: function(btn) {
var grid = btn.up('panel'),
store = grid.getStore();
store.insert(0,{});
grid.editingPlugin.startEdit(0,1);
}

This works perfectly for us, a new record is created grid-wise but not submitted to the server, the rowEditor opens automatically the new record for editing and after pressing Update the new record will be submitted to the server (using POST as the property phantom is still true and so Ext handles the new record as to be created - which is exactly what we needed).

HTH

brokentwig
29 Sep 2011, 4:09 PM
@fschaeffer,
Thanks for providing a working example, I appreciate it a lot. I implemented your code, but get an error. I've been getting this error off and on during my attempts to build this insert, but can 't figure it out. "views is undefined". I look at the source code, but can't decipher what it might be. Google doesn't help either. Firebug leads me here (in ext-all-debug):


onSelectChange: function(record, isSelected, suppressEvent, commitFn) { var me = this,
views = me.views,
viewsLn = views.length,

store = me.store,
rowIdx = store.indexOf(record),
eventName = isSelected ? 'select' : 'deselect',
i = 0;


I also see a json post when I click "Add". I see you mentioned the restful proxy waits due to the validation. I don't understand how the validation would work since Extjs sets the id as zero when it creates it. Disabling autoSync still throws the "views is undefined" error though, so it's not the auto-post.

brokentwig
29 Sep 2011, 7:50 PM
Well, turns out that for whatever reason, the code doesn't work when the grid is in a panel, that sits inside of a card. I was using a card layout to easily switch between panels from a menu. Once I changed the grid panel to just exist as the center panel of my viewport, the code worked fine. I had been getting the "views not defined" error on every version of the code I tried. It was popping up any time I tried to select the newly created record, regardless of what method I used. The startEdit function calls a select method, so it was erroring at that point. It must be a bug, or the card layout is doing something funny. Now I just need to find another way to switch content xtypes on menu click. Thanks for your help.

fschaeffer
29 Sep 2011, 8:26 PM
Hello,

I don't know for what reason you'll need views, the only place where views can be used is AFAIS a controller (at least this is what the docs at Sencha tell me), as all components only have a property called view (without s). So you should have a look at your scope and debug your me whether it really is the controller and not the panel.

The validation works as we built the model in a "clever" way. We have a unique id for each store row (I called it rights_id) which also is defined as idProperty for the store. The validation uses another field which must be present (user_id in my example) but is not defined as idProperty. When I create a record I use


store.insert(0,{});

which will insert a record without any information at all. Thus the model validation finds no appropriate user_id, fails and the rowEditor is opened.

HTH

brokentwig
30 Sep 2011, 4:28 PM
I see what you are doing with the validation, nice trick. As far as the views is concerned, it is an internal attribute of the selection method. I'm going to comb through my code one more time using the card layout to see if I missed something in the setup. Otherwise I will count it as a bug and find another way to create/destroy the panels. Thanks fschaeffer.