I am trying to display a property from a JSON received from a server in a combobox within a grid with cell editing. When the user selects an option I want to display the same property, but when the user saves the grid, I want the complete JSON to be sent to the server (not just the display value nor the id field).
This is what I have so far (available here http://jsfiddle.net/apater39/do0xg4r1/ ):
Ext.define('NS.model.State', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int'
}, {
name: 'name',
type: 'string'
}]
});
Ext.define('NS.store.State', {
extend: 'Ext.data.Store',
model: 'NS.model.State',
data: [{
"id": 1,
"name": "Alabama"
}, {
"id": 2,
"name": "Alaska"
}, {
"id": 3,
"name": "Arizona"
}]
});
Ext.define('NS.model.Person', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int'
}, {
name: 'firstName',
type: 'string'
}, {
name: 'state',
type: 'NS.model.State'
}]
});
Ext.define('NS.store.Grid', {
extend: 'Ext.data.Store',
model: 'NS.model.Person',
data: {
'items': [{
'id': 1,
"firstName": "Lisa",
"state": null
}, {
'id': 2,
"firstName": "Bart",
"state": null
}, {
'id': 3,
"firstName": "Homer",
"state": null
}, {
'id': 4,
"firstName": "Marge",
"state": null
}]
},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.create('NS.store.Grid'),
columns: [{
header: 'First Name',
dataIndex: 'firstName',
flex: 1,
editor: 'textfield'
}, {
header: 'State',
dataIndex: 'state',
flex: 1,
editor: {
xtype: 'combobox',
store: Ext.create('NS.store.State'),
queryMode: 'local',
displayField: 'name',
valueField: 'id'
}
}],
selType: 'cellmodel',
plugins: [{
ptype: 'cellediting',
clicksToEdit: 2
}],
height: 150,
width: 200,
renderTo: Ext.getBody()
});
If I use valueField 'id' then when the user chooses an option from the combobox the id is displayed (instead of the displayField).
The JSON that I would like to be sent is this:
{
"id": 1,
"firstName": "Lisa",
"state":
{
"id": 1,
"name": "Alabama"
}
}
Thanks for the help.
UPDATE:
Based on the suggestion of Jorge Ramon, I arrived at a solution (see http://jsfiddle.net/apater39/8opsqg5s/ ). The important thing is to to listen to the edit event of cellediting pluging, and then find the selected record of the combo and set the corresponding property.
var gridPanel = Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: gridStore,
columns: [{
header: 'First Name',
dataIndex: 'firstName',
flex: 1,
editor: 'textfield'
}, {
header: 'State',
dataIndex: 'state',
flex: 1,
editor: {
xtype: 'combobox',
store: Ext.create('NS.store.State'),
displayField: 'name',
valueField: 'name',
editable: false,
queryMode: 'local',
forceSelection: true,
triggerAction: 'all',
selectOnFocus: true,
allowBlank: false
},
renderer: function(value) {
return value.name;
}
}],
selType: 'cellmodel',
plugins: [{
ptype: 'cellediting',
clicksToEdit: 2,
listeners: {
edit: function(editor, ctx, eOpts) {
var vendorColIdx = 1;
if (vendorColIdx === ctx.colIdx) {
var combo = ctx.grid.columns[vendorColIdx].getEditor(ctx.record);
var vendorRecord = combo.findRecord('name', ctx.record.get('state'));
ctx.record.set('state', vendorRecord.data);
}
ctx.grid.getStore().sync();
}
}
}],
height: 250,
width: 200,
renderTo: Ext.getBody()
});
The JSON sent becomes:
{"id":1,"firstName":"Lisa","state":{"id":2,"name":"Alaska"}}
You will need to change several stuff in your code to achieve want you want to do...
First is that your are trying to work with association (Person contains a State) but you are not declaring the association. To declare your association correctly, I suggest to read this : https://stackoverflow.com/a/16492938/3494608 And also deeply suggest to read this : http://extjs-tutorials.blogspot.fr/2012/05/extjs-hasmany-relationships-rules.html
Afterward, you will need to see how to correctly set your association because your combobox here only set a value (the id of the model corresponding to the select state) and not the record itself.
And then, you will see how to send the complete model with association. I did not did it myself within Ext4.2 but you'll find some lecture in google (Key words: extjs save nested model). Found this first : https://www.sencha.com/forum/showthread.php?274778-Add-new-record-of-Model-that-contains-nested-Model
I don't have a "all-in-one" solution because working with association is unfortunately a though work with ExtJs (less with ExtJs 5+ but still...)
Good luck!
You want to have the combo editor set like this example:
editor: {
xtype: 'combobox',
store: 'Vendors',
displayField: 'name',
valueField: 'name',
editable: false,
queryMode: 'remote',
forceSelection: true,
triggerAction: 'all',
selectOnFocus: true,
allowBlank: false
}
Then, use the celleditor plugin:
plugins: {
ptype: 'cellediting',
clicksToEdit: 1,
listeners: {
edit: 'onGridEditorEdit'
}
}
And handle the plugin's edit event:
onGridEditorEdit: function (editor, ctx, eOpts) {
var vendorColIdx = 2;
if (vendorColIdx === ctx.colIdx + 1) {
var combo = ctx.grid.columns[vendorColIdx].getEditor(ctx.record);
var vendorRecord = combo.findRecord('name', ctx.record.get('vendorName'));
ctx.record.set('vendorId', vendorRecord.get('id'));
}
ctx.grid.getStore().sync(); // Force a post with the updated data.
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.