Reputation: 8067
I am getting a json array string as response from a page. I want to bind it with a combobox.
This is the success block which gives me the json array string:
The json array string looks like this:
Please let me know hoe to bind this with the combobox drop down.
Regards,
EDIT:
This is the latest code I tried:
Ext.define('Country',{
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'string' },
{ name: 'name', type: 'string' }
]
});
Ext.define('CountryCombo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.countrycombo',
allowBlank: false,
queryMode: 'local',
valueField: 'id',
displayField: 'name',
store: {
model: 'Country',
data: [
{ id: 'China', name: 'China'},
{ id: 'Japan', name: 'Japan'},
{ id: 'Malaysia', name: 'Malaysia'}
]
},
listeners: {
"select": function(obj){
Ext.Ajax.request({
url: '/CellEditing/FormServlet',
method: 'POST',
params: {
data: obj.getValue()
},
success: function(obj){
alert('success');
alert(obj.responseText);
console.log(StateCombo.storeStates); //This is undefined hence getting error
StateCombo.storeStates.loadData(obj.responseText);
},
failure: function(obj){
alert('failure');
}
});
}
}
});
var storeStates = Ext.create('Ext.data.Store', {
autoLoad: false,
fields: ['State']
});
Ext.define('State',{
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' }
]
});
Ext.define('StateCombo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.statecombo',
queryMode: 'local',
valueField: 'State',
displayField: 'State',
store: storeStates
});
This is the latest I tried but still when I select something from 1st combobox, the second combobox is not getting populated. any Help on this please?
Upvotes: 2
Views: 10887
Reputation: 404
You cannot use StateCombo because it is the name of class and not the object instance itself. Therefor the store cannot be accessed by the code StateCombo.storeStates.
Actually, if you want to access the store to load data, you can do it in two ways. First, because on creation store object you save it in storeStates variable, you can access it and use. storeStates is either global variable or is know by closure. So by writting the following clause you execute the required operation:
storeStates.loadData();
Another way is by accessing the combobox control and then getting its bound store. By accessing the control means not using the class name, but it's instance. In order to access the combobox control, you first have to modify your declaration of combobox and define instance name by setting itemId:
Ext.define('StateCombo', {
itemId: 'stateCombo',
extend: 'Ext.form.field.ComboBox',
alias: 'widget.statecombo',
queryMode: 'local',
valueField: 'State',
displayField: 'State',
store: storeStates
});
Once the widget is known, it can be found by:
var arr = Ext.ComponentQuery.query('stateCombo');
Now, we can load data:
if (arr.length>0)
arr[0].loadData();
Upvotes: 2
Reputation: 954
Technically this code will work:
http://jsfiddle.net/sdt6585/wPzPD/29/
Ext.define('Country',{
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'string' },
{ name: 'name', type: 'string' }
]
});
Ext.define('CountryCombo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.countrycombo',
allowBlank: false,
queryMode: 'local',
valueField: 'id',
displayField: 'name',
store: {
model: 'Country',
data: [
{ id: 'China', name: 'China'},
{ id: 'Japan', name: 'Japan'},
{ id: 'Malaysia', name: 'Malaysia'}
]
},
listeners: {
"select": function(obj){
Ext.Ajax.request({
url: '/CellEditing/FormServlet',
method: 'POST',
params: {
data: obj.getValue()
},
callback: function (response, operation) {
//This should be the text string in reponseText, just putting it there since I don't have it
response.responseText = '{data: [{state: "State One"}, {state: "State Two"}, {state: "State Three"}]}'
//Put this in your success function
var data = Ext.JSON.decode(response.responseText).data;
storeStates.loadData(data);
}
});
}
}
});
var storeStates = Ext.create('Ext.data.Store', {
autoLoad: false,
fields: ['state']
});
Ext.define('State',{
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' }
]
});
Ext.define('StateCombo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.statecombo',
queryMode: 'local',
valueField: 'state',
displayField: 'state',
store: storeStates
});
Ext.form.Panel.create({
title: 'Tester',
renderTo: Ext.getBody(),
items: [
CountryCombo.create(),
StateCombo.create()
]
});
The major changes are these:
While that technically works, it's not the most elegant solution. You would be working with much more maintainable code to follow this process.
Ext.define('MyApp.models.Country',{
extend: 'Ext.data.Model',
requires: ['Ext.data.SequentialIdGenerator'],
idgen: 'sequential',
fields: [
{ name: 'name', type: 'string' }
]
});
Ext.define('MyApp.stores.Country', {
model: 'MyApp.models.Country',
data: [
{ name: 'China'},
{ name: 'Japan'},
{ name: 'Malaysia'}
]
});
Ext.define('MyApp.models.State',{
extend: 'Ext.data.Model',
requires: ['Ext.data.SequentialIdGenerator'],
idgen: 'sequential',
fields: [
{ name: 'state', type: 'string' }
],
proxy: {
type: 'ajax',
method: 'post',
url: '/CellEditing/FormServlet',
reader: {
type: 'json',
root: 'data',
successProperty: false
}
}
});
Ext.define('MyApp.stores.State', {
model: MyApp.models.State
});
Ext.define('MyApp.views.CountryCombo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.countrycombo',
allowBlank: false,
queryMode: 'local',
valueField: 'name',
displayField: 'name',
store: MyApp.stores.Country.create()
});
Ext.define('MyApp.views.StateCombo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.statecombo',
queryMode: 'local',
valueField: 'state',
displayField: 'state',
store: MyApp.stores.State.create()
});
Ext.form.Panel.create({
title: 'Tester',
renderTo: Ext.getBody(),
items: [
countryCombo = MyApp.views.CountryCombo.create(),
stateCombo = MyApp.views.StateCombo.create()
]
});
countryCombo.on('beforeselect', function (combo, record, index, eOpts) {
stateCombo.store.load({
params: {data: record.get('name')}
});
});
Upvotes: 4
Reputation: 404
Let's see the example below of using two combobox controls bound to two different stores. Changing first combobox raises event which reload (in my example it do filters) the data accordingly to the selected value. Then the store of the second combobox is reloaded and the control refilled.
This example shows how both model, store and view are cooperate and used together. Generally it uses local data collection, but you can easily to configure the store and proxy so it will bring the data from the server side:
// Set up a model to use in our Store
Ext.define('Countries', {
extend: 'Ext.data.Model',
fields: [
{name: 'abbr', type: 'string'},
{name: 'name', type: 'string'}
]
});
// The data store containing the list of states
var countries = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
model: 'Countries',
data : [
{"abbr":"US", "name":"United States"},
{"abbr":"FR", "name":"France"}
//...
]
});
// Set up a model to use in our Store
Ext.define('States', {
extend: 'Ext.data.Model',
fields: [
{name: 'cntry', type: 'string'},
{name: 'abbr', type: 'string'},
{name: 'name', type: 'string'}
]
});
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
autoLoad: false,
fields: ['abbr', 'name'],
model: 'States',
data : [
{"cntry": "US", "abbr":"AL", "name":"Alabama"},
{"cntry": "US", "abbr":"AK", "name":"Alaska"},
{"cntry": "US", "abbr":"AZ", "name":"Arizona"},
{"cntry": "FR", "abbr":"PR", "name":"Paris"}
//...
],
listeners: {
beforeload: function () {
}
}
});
// Create the combo box, attached to the states data store
var a = Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose Country',
store: countries ,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
// Basically this code was tested on Simple Online ExtJS Code Editor
// http://ext4all.com/post/simple-online-extjs-code-editor
// so it was bounded to the codeoutput control
renderTo: 'codeoutput',
listeners: {
// when we change the value of Countries combobox, this event is raised
change: function(obj, newVal, oldVal, eOpts) {
// we can also use states.filter() function in the same way
states.filterBy ( function(record, id) {
// newVal variable is available due to closure, so we can compare the row with the selected country and result appropriate notification
if (record.get("cntry")==newVal) return true;
});
}
}
});
// Create the combo box, attached to the states data store
var a = Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose State',
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
renderTo: 'codeoutput'
});
Upvotes: 1
Reputation: 2216
just a quick thought from edited post, response is containing
{"data":[{"state":"sanghai"},{"state":"state2"}]}
state in lowercase while in store it is defined as fields: ['State']
and another thing the ajax response is json string, so it should be decoded before calling the loadData
method of store.
like var response = Ext.decode(obj.responseText);
then call loadData as StateCombo.storeStates.loadData(response.data);
Upvotes: 1
Reputation: 366
use loadData method to load data to your combobox.
yourCombo.store.loadData(obj.responsetext);
Upvotes: 2