I have an in-line store that is inside of a simple combobox. This store has some default inline-data. Now I'm looking for an event that gets fired once the store is created and this event needs to supply me with the data that is in the store.
I tried it like this:
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose',
store: {
autoLoad: true,
fields: [
{name: 'name', type: 'string'}
],
data : [
{"name":"TestName_A"},
{"name":"TestName_B"},
{"name":"TestName_C"},
],
listeners: {
load: function(store) {
let records = store.getData()
records.forEach(record => {
console.log(record.getField('name'))
})
}
}
},
queryMode: 'local',
valueField: 'name',
displayField: 'name',
renderTo: Ext.getBody()
});
But it doesn't work. store.getData() doesn't seem to contain my records.
There's my fiddle:
https://fiddle.sencha.com/?fiddle=v7#fiddle/1h53
Use this now store show console data:
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose',
queryMode: 'local',
valueField: 'name',
displayField: 'name',
renderTo: Ext.getBody(),
listeners: {
afterrender: function(me) {
var store = Ext.create('Ext.data.Store', {
//autoLoad: true,
fields: [
{name: 'name', type: 'string'}
],
data : [
{"name":"TestName_A"},
{"name":"TestName_B"},
{"name":"TestName_C"},
],
listeners: {
datachanged : function(store) {
Ext.each(store.data.items,function(rec){
console.log(rec.data.name);
});
}
}
});
me.setStore(store);
store.load();
}
},
});
I finally managed to solve the problem by accessing the store after it's combobox is rendered:
https://fiddle.sencha.com/?fiddle=v7#fiddle/1h7c
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose',
store: {
autoLoad: true,
fields: [
{name: 'name', type: 'string'}
],
data : [
{"name":"TestName_A"},
{"name":"TestName_B"},
{"name":"TestName_C"},
],
},
queryMode: 'local',
valueField: 'name',
displayField: 'name',
renderTo: Ext.getBody(),
listeners: {
afterrender: function(me) {
let store = me.getStore()
console.log("Event fired!")
store.each(record => {
console.log(record.get('name'))
})
}
},
});
You can easily do this by creating store afterrender of combo box and set store to combo box.
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose',
queryMode: 'local',
valueField: 'name',
displayField: 'name',
renderTo: Ext.getBody(),
listeners: {
afterrender: function(me) {
var store = Ext.create('Ext.data.Store', {
autoLoad: true,
fields: [
{name: 'name', type: 'string'}
],
data : [
{"name":"TestName_A"},
{"name":"TestName_B"},
{"name":"TestName_C"},
],
listeners: {
load: function(store) {
Ext.each(store.data.items,function(rec){
console.log(rec.data.name);
});
}
}
});
me.setStore(store);
}
},
});
Related
I have a combo box that I need to get access to the store in code so that I can apply a filter to it. Here is the definition of the combo.
//ItemGeneralPanel.js
Ext.define('myCompany.view.item.ItemGeneralPanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.myApp.ItemGeneralPanel',
layout: 'vbox',
bodyPadding: 4,
defaults: { width: 800 },
items: [
{
xtype: 'combobox',
fieldLabel: 'Replenishment Source',
displayField: 'name',
valueField: 'id',
queryMode: 'local',
forceSelection: true,
bind: { value: '{item.sourceId}', store: '{replenishmentSourceList}' }
},
]
});
My ItemController has this in it:
//ItemController.js
stores: [
'item.ItemList',
'item.ReplenishmentSourceList'
],
And my store looks like this:
//ReplenishmentSourceList.js
Ext.define('myCompany.store.item.ReplenishmentSourceList', {
extend: 'Ext.data.Store',
model: 'myCompany.model.Source',
sorters: 'name'
});
And the model just has a list of fields(Source.js):
How do I reference this combo box in my controller so that I can get a reference to its store and then apply a filter to the results coming back. Something like this:
//ItemEditViewController.js
myFunction: function (facilId) {
this.lookup('replenishmentSourceList').getStore().load({
scope: this,
callback: function (records, operation, success) {
if (!success) {
Ext.log({ level: 'error', msg: 'Error loading facility list', dump: operation });
var text = (operation.getError() ? operation.getError().response.responseText : operation.getResponse().responseText);
var msg = Ext.decode(text).message;
Ext.Msg.show({ title: 'Error', msg: 'Error loading Source data.<br>' + msg, buttons: Ext.Msg.OK, icon: Ext.Msg.ERROR });
}
else {
this.lookup('replenishmentSourceList').getStore().setFilters({
property: 'facilityId',
operator: '==',
value: 'facilId'
});
This isn't working, so I figured if I could get the combobox, I could do something like:
myRefToComboBox.getStore()....
Any ideas?
If you want to get the store directly then you can simply use storeId and perform a lookup on created stores Ext.data.StoreManager.lookup('myStore') which will return the store instance. Refer docs for Ext.data.StoreManager.
Below is a sample which you can try out in fiddle (Check console as it prints the store instance using store manager):
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('myCompany.store.item.ReplenishmentSourceList', {
alias: 'store.replenishmentSourceList',
extend: 'Ext.data.Store',
sorters: 'name'
});
Ext.define('myCompany.view.item.ItemGeneralPanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.myApp.ItemGeneralPanel',
layout: 'vbox',
bodyPadding: 4,
defaults: {
width: 800
},
items: [{
xtype: 'combobox',
fieldLabel: 'Replenishment Source',
displayField: 'name',
valueField: 'id',
queryMode: 'local',
forceSelection: true,
store: {
type: 'replenishmentSourceList',
storeId: 'myStore'
}
}, ]
});
Ext.create({
xtype: 'myApp.ItemGeneralPanel',
renderTo: Ext.getBody()
});
console.log(Ext.data.StoreManager.lookup('myStore'));
}
});
Edit
The above is one way to get the store, another way is to get the combobox or the panel view from controller using getView() and then get the store.
Below is the code with controller (check the console):
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('MyApp.UserController', {
alias: 'controller.user',
extend: 'Ext.app.ViewController',
myFunction: function (facilId) {
console.log(this.getView())
console.log(this.getView().down('#replenishmentCombo').getStore());
}
});
Ext.define('myCompany.store.item.ReplenishmentSourceList', {
alias: 'store.replenishmentSourceList',
extend: 'Ext.data.Store',
sorters: 'name'
});
Ext.define('myCompany.view.item.ItemGeneralPanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.myApp.ItemGeneralPanel',
controller: 'user',
layout: 'vbox',
bodyPadding: 4,
defaults: {
width: 800
},
listeners: {
boxready: 'myFunction'
},
items: [{
xtype: 'combobox',
itemId: 'replenishmentCombo',
fieldLabel: 'Replenishment Source',
displayField: 'name',
valueField: 'id',
queryMode: 'local',
forceSelection: true,
store: {
type: 'replenishmentSourceList',
storeId: 'myStore'
}
}, ]
});
Ext.create({
xtype: 'myApp.ItemGeneralPanel',
renderTo: Ext.getBody()
});
// console.log(Ext.data.StoreManager.lookup('myStore'));
}
});
I have the following model and store in my app.
My problem is that when I'm trying to load the records into the second store it doesn't work. I've tried different store methods and nothing (Store Manual).
In my app the first store records are loaded in a controller, where an Ajax call receives the data.products variable.
Any ideas what I'm doing wrong?
PS: I'm using ExtJs 4.1
Fiddle sencha
Ext.define('App.model.Product', {
extend: 'Ext.data.Model',
alias: 'model-product',
idgen: 'sequential',
fields: [
{ name: 'available', type: 'boolean', useNull: false, defaultValue: true },
{ name: 'country', type: 'int', useNull: false },
{ name: 'key', type: 'string', useNull: false },
{ name: 'name', type: 'string', useNull: false }
],
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'products'
}
}
});
Ext.define('App.store.Product', {
extend: 'Ext.data.Store',
autoLoad: true,
autoSync: true,
groupField: 'id',
countryFilter: function(countryId) {
this.clearFilter();
this.filter('country', countryId);
return this;
},
getRecordsForCountry: function (countryId) {
var records = [];
this.findBy(function (record) {
if (record.get('country') === countryId) {
records.push(record.copy());
}
});
return records;
},
model: 'App.model.Product',
sorters: [ {
property: 'key',
direction: 'ASC'
} ],
sortOnLoad: true
});
Ext.onReady(function () {
var data = {
products: [{
country: 1,
key: 'test1',
name: 'Test1'
}, {
country: 2,
key: 'test2',
name: 'Test2'
}, {
country: 3,
key: 'test3',
name: 'Test3'
}]
};
var store = Ext.create('App.store.Product');
store.loadRawData(data, false);
var store2 = Ext.create('App.store.Product'),
records = store.getRecordsForCountry(1);
store2.add(records);
//tried also:
//store2.loadRecords(records);
//store2.loadData(records);
//store2.loadRawData(records);
var combobox = Ext.create('Ext.form.field.ComboBox', {
queryMode: 'local',
forceSelection: true,
displayField: 'name', // <-- Add this
valueField: 'key',
renderTo: Ext.getBody(),
store: store
});
var combobox2 = Ext.create('Ext.form.field.ComboBox', {
queryMode: 'local',
forceSelection: true,
displayField: 'name', // <-- Add this
valueField: 'key',
renderTo: Ext.getBody(),
store: store2
});
});
<link href="http://docs.sencha.com/extjs/4.1.1/extjs-build/resources/css/ext-all.css" rel="stylesheet"/>
<script src="http://cdn.sencha.com/ext/gpl/4.1.1/ext-all.js"></script>
Apparently these two settings:
autoLoad: true,
autoSync: true
screws the whole store up and calls load with empty records (triggerd by loadRawData, loadRecords, clearFilter, filter).
After setting these two to false the loading happens only on explicit call to the load methods.
Ext.define('App.model.Product', {
extend: 'Ext.data.Model',
alias: 'model-product',
idgen: 'sequential',
fields: [
{ name: 'available', type: 'boolean', useNull: false, defaultValue: true },
{ name: 'country', type: 'int', useNull: false },
{ name: 'key', type: 'string', useNull: false },
{ name: 'name', type: 'string', useNull: false }
],
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'products'
}
}
});
Ext.define('App.store.Product', {
extend: 'Ext.data.Store',
autoLoad: false,
autoSync: false,
groupField: 'id',
countryFilter: function(countryId) {
this.clearFilter();
this.filter('country', countryId);
return this;
},
getRecordsForCountry: function (countryId) {
var records = [];
this.findBy(function (record) {
if (record.get('country') === countryId) {
records.push(record.copy());
}
});
return records;
},
model: 'App.model.Product',
sorters: [ {
property: 'key',
direction: 'ASC'
} ],
sortOnLoad: true
});
Ext.onReady(function () {
var data = {
products: [{
country: 1,
key: 'test1',
name: 'Test1'
}, {
country: 2,
key: 'test2',
name: 'Test2'
}, {
country: 3,
key: 'test3',
name: 'Test3'
}]
};
var store = Ext.create('App.store.Product');
store.loadRawData(data, false);
var store2 = Ext.create('App.store.Product'),
records = store.getRecordsForCountry(1);
store2.add(records);
//tried also:
//store2.loadRecords(records);
//store2.loadData(records);
//store2.loadRawData(records);
var combobox = Ext.create('Ext.form.field.ComboBox', {
queryMode: 'local',
forceSelection: true,
displayField: 'name', // <-- Add this
valueField: 'key',
renderTo: Ext.getBody(),
store: store
});
var combobox2 = Ext.create('Ext.form.field.ComboBox', {
queryMode: 'local',
forceSelection: true,
displayField: 'name', // <-- Add this
valueField: 'key',
renderTo: Ext.getBody(),
store: store2
});
});
<link href="http://docs.sencha.com/extjs/4.1.1/extjs-build/resources/css/ext-all.css" rel="stylesheet"/>
<script src="http://cdn.sencha.com/ext/gpl/4.1.1/ext-all.js"></script>
I defined a view that should be able to be called in two modes. There are only two differences depending on a flag:
title of view (config.title)
selectfield might be shown or hidden
Here is the simplified view:
Ext.define('MyApp.view.fancyView', {
xtype: 'fancyview',
extend: 'Ext.form.Panel',
config: {
cls: 'fancyviewclass',
title: "titleDependingOnFlag",
items: [
{
xtype: 'fieldset',
name: 'fieldsetFancy',
items: [
{
xtype: 'selectfield',
itemId: 'stateID',
usePicker: true,
label: 'state',
store: 'States',
name: 'StateID',
valueField: 'ID',
displayField: 'ID'
},
{
xtype: 'selectfield',
itemId: 'countryID',
usePicker: true,
label: 'country',
store: 'Countries',
name: 'CountryID',
valueField: 'ID',
displayField: 'ID',
//hidden: true
}
]
}
]
}
});
And of course there is a controller that creates this view. At the moment I'm passing the flag as config value, see
Ext.define('MyApp.controller.fancyController', {
...
raisedBasedOnTap:function (flag){
this.myFancyFlag = !!flag;
var myFancyView = Ext.create('FLSMOBILE.minimax.view.CallReportTimestampPlaceCar', {
myFancyFlag: me.myFancyFlag
});
app.pushView(myFancyView);
}
...
});
What would be the best approach to make the title depending on a flag (like title: fancyFlag? 'title1' : 'title2') and hide selectfield countryID based on the flag?
Thanks in advance!
I have to populate a ComboBox in ExtJS 4.2 using JSON data received from a php.
Code so far :
DataStore:
var Cstates = new Ext.data.Store({
autoLoad: true,
url: 'data.php',
storeId: 'Cstates',
reader: new Ext.data.JsonReader({
root: 'state'
}),
idProperty: 'abbr',
fields: ['abbr', 'name']
});
ComboBox:
{
xtype: 'combo',
id: 'cmbState',
fieldLabel: ' Select state :',
triggerAction: 'all',
store: Cstates,
queryMode: 'local',
valueField: 'abbr',
displayField: 'name',
triggerAction: 'all',
typeAhead: true,
emptyText: '* All States',
forceSelection: true,
selectOnFocus: true,
allowBlank: false,
selectOnTab: true,
//hidden: true,
disabled: true
}
JSON received:
{state:[{"abbr":"E1","name":"EAST1"},{"abbr":"E2","name":"EAST2"}]}
Also later I need to populate this combobox with some other value that will be returned in the same format from a php using GET ie data.php?region=EAST.
Here is the chained combobox working example
// first combobox model definition
Ext.define('ArticleMainGroup', {
extend: 'Ext.data.Model',
fields: [
{name: 'PWHG', type: 'int'},
{name: 'PWHG_BEZ', type: 'string'}
]
});
// first combobox store definition
var articleMain = new Ext.data.JsonStore({
model: 'ArticleMainGroup',
autoLoad: true,
proxy: {
type: 'ajax',
url: '<?php echo base_url() ?>dashboard/promotion',
reader: {
type: 'json',
root: 'ArticleMainGroup',
idProperty: 'PWHG'
}
}
});
// second combobox store definition
var articleBase = new Ext.data.JsonStore({
model: 'ArticleBaseGroup',
proxy: {
type: 'ajax',
url: '<?php echo base_url() ?>dashboard/promotion',
reader: {
type: 'json',
root: 'ArticleBaseGroup',
idProperty: 'PWG'
}
}
});
// first combobox definition
{
xtype: 'combobox',
fieldLabel: 'ANA MAL GRUBU',
store: articleMain,
id: 'art-main-group',
queryMode: 'local',
autoSelect: true,
forceSelection: true,
triggerAction: 'all',
inputWidth: 240,
margin: '5 0 0 0',
listConfig: { cls: 'combo-dep' },
valueField: 'PWHG',
displayField: 'PWHG_BEZ',
listeners: {
select: function(combo) {
Ext.getCmp('art-base-group').setValue("");
/**
* this is the important part
* articleBase is a store definition which is bound to second combobox
* when we send a parameter by extraParams, the target store using this
* parameter via url string
* after that we should re-load the target store by load() method
* as a result, target combobox will populate based on this url parameter
* like http://localhost/dashboard?maingroup=10
*/
articleBase.proxy.extraParams = {'maingroup': combo.getValue()};
articleBase.load();
}
}
}
// second combobox definition
{
xtype: 'combobox',
fieldLabel: 'MAL GRUBU',
store: articleBase,
id: 'art-base-group',
queryMode: 'local',
autoSelect: false,
forceSelection: true,
triggerAction: 'all',
editable: false,
valueField: 'PWG',
displayField: 'PWG_BEZ',
inputWidth: 240,
margin: '10 0 0 0',
listConfig: { cls: 'combo-dep' },
listeners: {
select: function(combo) {
Ext.getCmp('art-sub-group').setValue("");
articleSub.proxy.extraParams = {'maingroup': Ext.getCmp('art-main-group').getValue(), 'basegroup': combo.getValue()}
articleSub.load();
}
}
}
I'm having a data sort problem with a combobox.
Data source is JSON. Data is sorted in sql. Resulting set(in sql) and JSON result looks fine:
{"rows":[{"id":"TOT","txt":" Alle diagnosen"},{"id":"612","txt":"(acute) bloeding distale tract. digestivus*"},{"id":"042","txt":"(auto)-intoxicatie"},{"id":"402","txt":"(benigne) peptisch ulcus*"},{"id":"10","txt":"(bij)niertumor"},{"id":"652","txt":"(chorio)retinitis.. etc etc
Resulting data looks fine(=same sort order as JSON result) when I inspect the store with with firebug:
However, the resulting combobox has a different(wrong) sorting(first 2 are ok):
It is not sorted on the display value, nor on the id value. There is no sorter added anywwhere.
Combo:
{
xtype: 'combobox',
id: 'ComboDiag',
itemId: 'ComboDiag',
width: 280,
fieldStyle: '',
name: 'ComboDiag',
fieldLabel: 'Diagnose',
labelWidth: 90,
displayField: 'txt',
queryMode: 'local',
store: 'ComboDiagStore',
typeAhead: true,
valueField: 'id',
listeners: {
render: {
fn: me.onComboDiagRender,
scope: me
}
}
}
Store:
Ext.define('AppPitDash.store.ComboDiagStore', {
extend: 'Ext.data.Store',
alias: 'store.ComboDiagStore',
requires: [
'AppPitDash.model.ComboDiagModel'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
storeId: 'ComboDiagStore',
model: 'AppPitDash.model.ComboDiagModel',
proxy: {
type: 'ajax',
url: './php/get-data-diagCombo.php',
reader: {
type: 'json',
root: 'rows'
}
}
}, cfg)]);
}
});
Model:
Ext.define('AppPitDash.model.ComboDiagModel', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id'
},
{
name: 'txt'
}
]
});
I'm using Sencha Architect 2, first time.
This is rather an annoyance than a showstopper, but still help would be appreciated.
Try adding remoteSort: true to callParent method in store definition.
Try to use:
remoteGroup: true,
remoteSort: true,
sortInfo: { field: 'order', direction: 'DESC' },