Combobox inside grid doesn't show data after rendering - combobox

I have a grid that has combobox on one column. Data loads fine on the grid. But when I double click on one row to enable edit, the combobox doesn't show the data. (Please see the screenshot below) The highlighted part should show '1st Label'. But when I start to edit, it shows up like in the 2nd row with '2nd Label'.
I tried my code on 4.1 and it works fine. It seems 4.2.2 doesn't like combobox inside grid. Any help is really appreciated
This is my sample code. Please try it on Sencha's Code Editor to see both on 4.2.2 and 4.1.0
Ext.define('GridModel', {
extend: 'Ext.data.Model',
fields: [{
name: 'Id',
type: 'int'
}, {
name: 'Value',
type: 'int'
}]
});
Ext.define('ComboModel', {
extend: 'Ext.data.Model',
fields: [{
name: 'ComboId',
type: 'int'
}, {
name: 'Label',
type: 'string'
}],
idProperty: 'Order'
});
Ext.create('Ext.data.Store', {
storeId: 'comboStore',
model: 'ComboModel',
data: [{
ComboId: 1,
Label: '1st Label'
}, {
ComboId: 2,
Label: '2nd Label'
}]
});
Ext.create('Ext.data.Store', {
storeId: 'gridStore',
model: 'GridModel',
data: [{
Id: 1,
Value: 1
}, {
Id: 2,
Value: 2
}, {
Id: 3,
Value: 1
}, {
Id: 4,
Value: 2
}]
});
Ext.create('Ext.grid.Panel', {
width: 400,
height: 200,
renderTo: 'ct',
plugins: [
Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 2,
listeners: {
edit: function(editor, e) {
console.log(gridStore.getModifiedRecords());
}
}
})
],
store: Ext.data.StoreManager.lookup('gridStore'),
forceFit: true,
columns: [{
dataIndex: 'Id',
header: 'ID'
}, {
dataIndex: 'Value',
header: 'Label',
editor: {
xtype: 'combobox',
displayField: 'Label',
valueField: 'ComboId',
queryMode: 'local',
store: Ext.data.StoreManager.lookup('comboStore'),
allowBlank: true
},
renderer: function(value) {
var rec = comboStore.getById(value);
return rec ? rec.get('Label') : value;
}
}],
renderTo: Ext.getBody()
});

Related

Blank value in Grid with combobox when force select is true

I got a combocox in editor grid. When entering values I have to validate so I used property forceSelection : true . But turning on force selection raise another problem as the combo value is blank when the combo box loss focus as below attached image.
Sample code:
var employeeType = [{
'typeid': 1,
'typename': 'Contractor'
}, {
'typeid': 1,
'typename': 'Regular'
}];
var employeeTypeStore = Ext.create('Ext.data.Store', {
fields: ['typeid', 'typename'],
data: employeeType
});
Ext.define('Employees', {
extend: 'Ext.data.Model',
fields: [{
name: 'emptype',
type: 'string'
}, {
name: 'name',
type: 'string'
},
]
});
var empStore = Ext.create('Ext.data.Store', {
model: 'Employees',
data: [{
'emptype': 'Regular',
'name': 'John Doe'
},{
'emptype': 'Regular',
'name': 'Ricky'
},{
'emptype': 'Regular',
'name': 'Mason'
}]
});
var grid = Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
store: empStore,
width: 1000,
height: 500,
title: 'Employees',
columns: [{
text: 'Employee Type',
dataIndex: 'emptype',
editor: {
xtype: 'combobox',
queryMode: 'local',
store: employeeTypeStore,
displayField: 'typename',
valueField: 'typeid',
forceSelection : true
}
}, {
text: 'Employee Name',
dataIndex: 'name'
}],
plugins: {
ptype: 'cellediting',
clicksToEdit: 1
}
});
If the value is false then I need to show the last correct value.
Its the Expected behavior.
Setting forceSelection: true will restrict the user to select the value which is present in the list only. So if you loose the focus without selecting any item it will gonna blank.
You can use typeAhead: true to populate and autoselect the remainder of the text being typed if it matches a known value.

extjs form,combo and hiddenname

Have this code.
Ext.define('App.v2.model.Things', {
extend: 'App.v2.model.Base'
,fields: [{
name: 'C'
,type:'int'
},{
name:'NAME'
,type:'string'
},{
name:'SHORT_NAME'
,type:'string'
}]
,proxy:{
url:'/data/data1.php'
,reader : {
rootProperty: 'data'
},
extraParams: {
limit: 1000
}
},
idProperty: 'C'
});
model for document
Ext.define('App.v2.model.ThingsList', {
extend: 'App.v2.model.Base'
,fields: [{
name: 'C'
,type:'int'
},
{
name: 'THING_ID',
type:'int'
},
{
name: 'ZE',
type:'int'
},
{
name: 'HS',
type:'int'
},
{
name: 'THING_NAME',
type:'string'
},]
,proxy:{
url:'/data/thingsList.php'
,reader : {
rootProperty: 'data'
}
},
idProperty: 'C'
});
Form config
items: [{
xtype: 'form',
bodyStyle: 'border:none',
defaultType: 'textfield',
layout: 'fit',
maindata: [{
xtype: 'panel',
//layout: 'vbox',
layout: 'vbox',
id: 'ThingsForm',
items: [{
xtype: 'textfield',
fieldLabel: 'ЗЕ',
name: 'ZE',
width: 400,
allowBlank: false
},
{
xtype: 'textfield',
fieldLabel: 'HS',
name: 'HS',
width: 400,
allowBlank: false
},
{
xtype: 'combo',
fieldLabel: 'Thing',
name: 'THING_ID',
hiddenName: 'THING_NAME',
valueField: 'C',
displayField: 'SHORT_NAME',
store : {
model:'App.v2.model.Things',
autoLoad: true,
}
}
//]
]
}]
}]
load data to form
row = grid.store.getAt(this.conf.grid.getSelectionModel().getCurrentPosition().rowIdx);
form = this.down('form').getForm();
form.loadRecord(row);
all good. Form show values
after change of form try to update record
var record = form.getRecord(); // see old values of THING_ID and THING_NAME
record.set(form.getValues()); // see new value of THING_ID and OLD value of THING_NAME
How update THING_NAME to NEW value (TEXT) selected on COMBO in record?
only like describe there?
ExtJS 5 combobox - submitting both value and text

Chained combobox shows valuefield instead of displayfield when changing parent cb

How to reset chained combobox in my example the extjs way?
Consider this two comboboxes:
{
xtype: 'combo',
bind:{
store: '{contacts}'
},
reference: 'contactsCombo',
displayField: 'name',
name: 'contact',
typeAhead: false,
editable: false,
fieldLabel: 'Contact',
emptyText: 'Select a contact...',
anchor: '95%',
listeners: {
change: 'onSelectChange'
},
},
{
xtype: 'combo',
name: 'phone',
reference: 'phonesCombo',
fieldLabel: 'Phone',
displayField: 'number',
valueField:'id',
hiddenName: 'id',
emptyText: 'Select a phone...',
bind: {
store: '{contactsCombo.selection.phoneNumbers}'
},
anchor: '95%'
}
And corresponding models defines:
Ext.define('AppsBoard.model.Contact', {
extend: 'Ext.data.Model',
fields: [
'id', 'name'
],
});
Ext.define('AppsBoard.model.ViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.related',
stores: {
contacts: {
model: 'AppsBoard.model.Contact',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'contacts.json',
reader: {
type: 'json',
rootProperty: 'data'
}
}
}
}
});
Ext.define('AppsBoard.model.PhoneNumber', {
extend: 'Ext.data.Model',
fields: [
'id',
{
name: 'contact_id',
type: 'int',
reference: {
type: 'AppsBoard.model.Contact',
inverse: {
role: 'phoneNumbers'
}
}
},
'number'
],
proxy: {
type: 'MyProxy',
reader: {
type: 'json'
}
}
});
Ext.define('AppTest.store.MyProxy', {
extend: 'Ext.data.proxy.Proxy',
alias: 'proxy.MyProxy',
read: function (operation) {
var resultSet = {
1: [{
"id": 1,
"contact_id": 1,
"number": "6045551212"
},
{
"id": 2,
"contact_id": 1,
"number": "8009996541"
}],
2: [
{
"id": 3,
"contact_id": 2,
"number": "1232131233"
}
]
};
operation.setResultSet(this.getReader().read(resultSet[operation.getFilters()[0].getValue()]));
operation.setSuccessful(true);
},
erase: function (operation) {
console.log(operation);
}
});
My problem is when i switching my parent Combobox, it's associated child combobox shows valueField instead of displayField.
https://fiddle.sencha.com/#fiddle/vtg
you can see in your fiddle it's not use valueField but it's keep the value.
Since the store has been change the value is now not associated to anything in the new store, therefore you keep seen only the value.
you can clean the box by setting the forceSelection
{
xtype: 'combo',
name: 'phone',
reference: 'phonesCombo',
fieldLabel: 'Phone',
displayField: 'number',
valueField:'id',
hiddenName: 'id',
emptyText: 'Select a phone...',
forceSelection: true,
bind: {
store: '{contactsCombo.selection.phoneNumbers}'
},
anchor: '95%'
}
as long as you know there won't be a duplicates IDs

extJs - GridPanel with combobox cell editing

I have a grid panel populated from local store. I added combo box for editing type cell. I want my combo box to be populated from a remote source. But I can't make it load any data. Here is my code:
Ext.define('System.view.MainTab.NewConnection.Contacts', {
extend: 'Ext.grid.Panel',
alias: 'widget.newConnectionContactsPanel',
requires: [
'Ext.grid.View',
'Ext.grid.column.Column',
'Ext.form.field.ComboBox',
'Ext.toolbar.Toolbar',
'Ext.toolbar.Fill',
'Ext.button.Button',
'Ext.grid.plugin.RowEditing'
],
height: 250,
width: 400,
itemId: 'contactsGridPanel',
title: 'My Grid Panel',
initComponent: function() {
var records = [];
var store = new Ext.data.ArrayStore({
fields: [
{name: 'type'},
{name: 'value'}
]
});
store.loadData(records);
var me = this;
Ext.applyIf(me, {
columns: [
{
dataIndex: 'type',
xtype: 'gridcolumn',
text: 'Type',
flex: 1,
editor: {
xtype: 'combobox',
displayField: 'neme',
valueField: 'id',
queryMmode: 'remote',
store: new Ext.data.JsonStore({
proxy: {
type: 'ajax',
url: '/ws/rest/contacts/getKeywords.json?keywordType=CONTACTS',
reader: {
type: 'json',
root: 'data',
idProperty: 'id'
}
},
autoLoad: true,
fields: [
{type: 'integer', name: 'id'},
{type: 'string', name: 'name'}
]
})
}
},
{
dataIndex: 'value',
xtype: 'gridcolumn',
text: 'Value',
flex: 1,
editor: {
xtype: 'textfield'
}
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'bottom',
items: [
{
xtype: 'tbfill'
},
{
xtype: 'button',
itemId: 'removeBtn',
text: 'Remove'
},
{
xtype: 'button',
itemId: 'addBtn',
text: 'Add',
listeners: {
click: function (button, e, eOpts) {
var grid = button.up('#contactsGridPanel');
var store = grid.getStore();
var rowEditing = grid.getPlugin('rowediting');
rowEditing.cancelEdit();
var record = store.add({})[0];
rowEditing.startEdit(record, 0);
}
}
}
]
}
],
plugins: [
Ext.create('Ext.grid.plugin.RowEditing', {
pluginId: 'rowediting',
listeners: {
edit: function() {
}
}
})
]
});
me.callParent(arguments);
}
});
Here is a json response I get from the server:
{
"success": true,
"data": [
{
"id": 1,
"name": "Fax"
},
{
"id": 2,
"name": "Home page"
}
]
}
Can't make it all work. The combo box is empty. What am I doing wrong?
The most likely is that you have a typo in your displayField config.
As a side note, you should really say what kind of debugging you've done. Saying you "can't make it work" doesn't really help. Does the request hit the server? Does the store get data in it? Mentioning what you've done would help someone answering you.
You should catch the column Values from your remote source. Try adding the mapping attribute.
autoLoad: true,
fields: [
{type: 'integer', name: 'id', **mapping:'id'**},
{type: 'string', name: 'name', **mapping :'name'**}
]

Setting data from a store to a form panel which has a grid in extjs 4.2

I'm trying to set values for the components in a form panel and below is my code.
Form Panel with grid:
Ext.define('MyApp.view.MyForm', {
extend: 'Ext.form.Panel',
height: 436,
width: 754,
layout: {
columns: 4,
type: 'table'
},
bodyPadding: 10,
title: 'My Form',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'displayfield',
colspan: 4,
fieldLabel: '',
value: 'Display Field'
},
{
xtype: 'displayfield',
colspan: 2,
margin: '0 50 0 0 ',
fieldLabel: 'Age',
labelAlign: 'top',
value: 'Display Field'
},
{
xtype: 'displayfield',
colspan: 2,
fieldLabel: 'Country',
labelAlign: 'top',
value: 'Display Field'
},
{
xtype: 'gridpanel',
colspan: 4,
header: false,
title: 'My Grid Panel',
store: 'MyJsonStore',
columns: [
{
xtype: 'gridcolumn',
dataIndex: 'DeptName',
text: 'Dept Name'
},
{
xtype: 'gridcolumn',
dataIndex: 'DeptId',
text: 'Dept ID'
}
]
}
]
});
me.callParent(arguments);
}
});
Models:
Ext.define('MyApp.model.EmpModel', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.DeptModel'
],
fields: [
{
name: 'Name'
},
{
name: 'Age'
},
{
name: 'Country'
},
{
name: 'Dept'
}
],
hasMany: {
associationKey: 'Dept',
model: 'MyApp.model.DeptModel'
}
});
Ext.define('MyApp.model.DeptModel', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.EmpModel'
],
fields: [
{
name: 'DeptName'
},
{
name: 'DeptId'
}
],
belongsTo: {
associationKey: 'Dept',
model: 'MyApp.model.EmpModel'
}
});
Store:
Ext.define('MyApp.store.MyJsonStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.EmpModel'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'MyApp.model.EmpModel',
storeId: 'MyJsonStore',
data: {
EmpDet: [
{
EmpName: 'Kart',
Age: '29',
Dept: [
{
DeptName: 'Dev',
DeptId: '1000'
}
]
}
]
},
proxy: {
type: 'ajax',
url: 'data/empDet.json',
reader: {
type: 'json'
}
}
}, cfg)]);
}
});
Json data:
{
"EmpDet": [
{
"EmpName": "Kart",
"Age": "29",
"Dept": [
{
"DeptName": "Dev",
"DeptId": "1000"
}
]
}
]
}
Questions:
1) I had left the value of the component as "Display Field" itself because if I remove this value the width of the grid below decreases. I feel this is because of the table layout and colspans. Is there any other best way to display labels without any alignment change on value load.
2) I'm trying to set the value for the display field. I tried to do it with the afterrender event but the problem is that it throws a undefined error at Ext.getStore('MyJsonStore').getAt(0). I found that this works fine if I write the same in the click event of a button. So, I feel that the store is not loaded when I try the afterrender event of the displayfield (autoload for store is set to true). Is there an alternative for afterrender event of a component. Also, Is there a way to set all the field values at a stretch instead of setting every component one by one?
3) Also I find it difficult to do the association properly. I'm using Sencha Architect 2.2 and when I go the data index of the grid, I'm not able to get the "DeptName" and "DeptId" in the dropdown.
Please help.
For the question number 2, I want to suggest the below way. I hope it works for you.
My solution:
You can set the display fields values when the store is loaded. So you can use load event of store as below:
yourStoe.on('load',function()
{
//set display field values here
});

Resources