jmozley
13 Apr 2012, 4:48 AM
I have two combo boxes I want to use to select a parent and child based on a relationship such as country and city within the country. I've done this kind of thing with ExtJS 3 but am trying to use the model associations of Ext 4. I have this working to the point where the child store is loaded, but the values are not displayed in the child combo. The view, controller, stores and models are below.
Any suggestions on what I am doing wrong so that the combo does not display the store contents? The associations and loading of the store seems to work.
View:
Ext.define('MyApp.view.FormOne', {
extend: 'MyApp.view.BaseForm',
alias : 'widget.form-one',
title : 'Form One',
url : 'cgi-bin/create_me_for_form_one.pl',
initComponent: function () {
Ext.apply(this, {
items : [
{
xtype : 'combobox',
itemId : 'countryCombo',
name : 'country',
fieldLabel : 'Country',
emptyText : 'Select a country...',
displayField : 'country_name',
valueField : 'country_code',
store : 'CountryStore',
mode : 'local',
triggerAction : 'all',
remoteSort : true,
lastQuery : ''
},
{
xtype : 'combobox',
itemId : 'cityCombo',
disabled : true,
name : 'city',
fieldLabel : 'City',
displayField : 'city_name',
valueField : 'city_code',
store : 'CityStore',
mode : 'local',
triggerAction : 'all',
remoteSort : true,
lastQuery : ''
}
]
});
this.callParent(arguments);
}
});
Controller:
Ext.define('MyApp.controller.FormOneController', {
extend: 'MyApp.controller.BaseFormController',
formSelector: 'form-one',
views: [
'FormOne'
],
stores: [
'CountryStore',
'CityStore'
],
models: [
'CountryModel',
'CityModel'
],
refs: [
{
ref : 'formOne',
selector : 'formOne',
xtype : 'form-one',
autoCreate : true
}
],
init : function (application) {
if (this.inited) {
return;
}
this.inited = true;
this.control({
'.form-one #countryCombo' : {
select : this.onSelectCountry
}
});
this.callParent([application]);
},
actionDisplayView : function () {
//this.application.logIfConsole('function DisplayView');
this.application.setMainView(this.getFormOne());
},
onSelectCountry : function (countryCombo, countryArray) {
// Get parent form and enable the city combo within this
var parentForm = countryCombo.findParentByType('form');
var cityCombo = parentForm.child('#cityCombo');
cityCombo.setDisabled(false);
// load city store
//countryArray[0].cities().load();
countryArray[0].cities().load({
callback: function(city, operation) {
console.log(arguments);
Ext.each(city, function(city) {
console.log(city);
// This shows child records in firebug when a country is selected
});
}
});
// Missing something to get the combo to display to loaded store?
}
});
Country model:
Ext.define('MyApp.model.CountryModel', {
extend : 'Ext.data.Model',
idProperty : 'uid_country',
fields : [
'uid_country',
'country_name',
'country_code'
],
proxy: {
type : 'ajax',
url : 'data/countries.json',
reader : {
type : 'json',
root : 'data'
}
},
hasMany: {
model : 'MyApp.model.CityModel',
name : 'cities',
primaryKey : 'uid_country',
foreignKey : 'fk_t_country_uid_country'
}
});
Country store:
Ext.define('MyApp.store.CountryStore', {
extend : 'Ext.data.Store',
storeId : 'Country',
requires : 'MyApp.model.CountryModel',
model : 'MyApp.model.CountryModel',
root : 'data',
autoLoad : true
});
City model:
Ext.define('MyApp.model.CityModel', {
extend : 'Ext.data.Model',
idProperty : 'uid_city',
fields : [
'uid_city',
'city_name',
'city_code',
'fk_t_country_uid_country'
],
proxy: {
type : 'ajax',
url : 'data/cities.json',
reader : {
type : 'json',
root : 'data'
}
},
associations: [
{
type : 'belongsTo',
model : 'MyApp.model.CountryModel',
name : 'country',
primaryKey : 'uid_country',
foreignKey : 'fk_t_country_uid_country'
}
]
});
City store:
Ext.define('MyApp.store.CityStore', {
extend : 'Ext.data.Store',
storeId : 'City',
model : 'MyApp.model.CityModel',
root : 'data',
autoLoad: false
});
Any suggestions on what I am doing wrong so that the combo does not display the store contents? The associations and loading of the store seems to work.
View:
Ext.define('MyApp.view.FormOne', {
extend: 'MyApp.view.BaseForm',
alias : 'widget.form-one',
title : 'Form One',
url : 'cgi-bin/create_me_for_form_one.pl',
initComponent: function () {
Ext.apply(this, {
items : [
{
xtype : 'combobox',
itemId : 'countryCombo',
name : 'country',
fieldLabel : 'Country',
emptyText : 'Select a country...',
displayField : 'country_name',
valueField : 'country_code',
store : 'CountryStore',
mode : 'local',
triggerAction : 'all',
remoteSort : true,
lastQuery : ''
},
{
xtype : 'combobox',
itemId : 'cityCombo',
disabled : true,
name : 'city',
fieldLabel : 'City',
displayField : 'city_name',
valueField : 'city_code',
store : 'CityStore',
mode : 'local',
triggerAction : 'all',
remoteSort : true,
lastQuery : ''
}
]
});
this.callParent(arguments);
}
});
Controller:
Ext.define('MyApp.controller.FormOneController', {
extend: 'MyApp.controller.BaseFormController',
formSelector: 'form-one',
views: [
'FormOne'
],
stores: [
'CountryStore',
'CityStore'
],
models: [
'CountryModel',
'CityModel'
],
refs: [
{
ref : 'formOne',
selector : 'formOne',
xtype : 'form-one',
autoCreate : true
}
],
init : function (application) {
if (this.inited) {
return;
}
this.inited = true;
this.control({
'.form-one #countryCombo' : {
select : this.onSelectCountry
}
});
this.callParent([application]);
},
actionDisplayView : function () {
//this.application.logIfConsole('function DisplayView');
this.application.setMainView(this.getFormOne());
},
onSelectCountry : function (countryCombo, countryArray) {
// Get parent form and enable the city combo within this
var parentForm = countryCombo.findParentByType('form');
var cityCombo = parentForm.child('#cityCombo');
cityCombo.setDisabled(false);
// load city store
//countryArray[0].cities().load();
countryArray[0].cities().load({
callback: function(city, operation) {
console.log(arguments);
Ext.each(city, function(city) {
console.log(city);
// This shows child records in firebug when a country is selected
});
}
});
// Missing something to get the combo to display to loaded store?
}
});
Country model:
Ext.define('MyApp.model.CountryModel', {
extend : 'Ext.data.Model',
idProperty : 'uid_country',
fields : [
'uid_country',
'country_name',
'country_code'
],
proxy: {
type : 'ajax',
url : 'data/countries.json',
reader : {
type : 'json',
root : 'data'
}
},
hasMany: {
model : 'MyApp.model.CityModel',
name : 'cities',
primaryKey : 'uid_country',
foreignKey : 'fk_t_country_uid_country'
}
});
Country store:
Ext.define('MyApp.store.CountryStore', {
extend : 'Ext.data.Store',
storeId : 'Country',
requires : 'MyApp.model.CountryModel',
model : 'MyApp.model.CountryModel',
root : 'data',
autoLoad : true
});
City model:
Ext.define('MyApp.model.CityModel', {
extend : 'Ext.data.Model',
idProperty : 'uid_city',
fields : [
'uid_city',
'city_name',
'city_code',
'fk_t_country_uid_country'
],
proxy: {
type : 'ajax',
url : 'data/cities.json',
reader : {
type : 'json',
root : 'data'
}
},
associations: [
{
type : 'belongsTo',
model : 'MyApp.model.CountryModel',
name : 'country',
primaryKey : 'uid_country',
foreignKey : 'fk_t_country_uid_country'
}
]
});
City store:
Ext.define('MyApp.store.CityStore', {
extend : 'Ext.data.Store',
storeId : 'City',
model : 'MyApp.model.CityModel',
root : 'data',
autoLoad: false
});