So basically i am trying to do the same as i did in my previous question - Chained combobox shows valuefield instead of displayfield when changing parent cb
BUT now i want to be able to select child combo without picking parent.
Here is what i did to make basic filtering but i've stucked to make it possible to select child cb.
Ext.define('AppTest.CategoryViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.category',
stores: {
categories: {
fields: ['id', 'name'],
proxy: {
type: 'ajax',
url: 'categories.json',
reader: {
type: 'json'
}
}
},
users: {
storeId: 'userStore',
fields: ['id', 'category_id', 'number'],
autoLoad: true,
filters: [{
property:'category_id',
disabled: '{!categoryCombo.selection}',
//disableOnEmpty:true,
value: '{categoryCombo.selection.id}',
/*filter: function (item) {
var me = this,
filterFn = me._filterFn || me.getFilterFn(),
convert = me.getConvert(),
value = me._value;
me._filterValue = value;
console.log(value);
me.isDateValue = Ext.isDate(value);
if (me.isDateValue) {
me.dateValue = value.getTime();
}
if (convert && !me.preventConvert[me.getOperator()]) {
me._filterValue = convert.call(me.scope || me, value);
}
return filterFn.call(me.scope || me, item);
},*/
//extjs is seems to be bugged here, disable doesn't work without it.
updateDisableOnEmpty: function(disableOnEmpty) {
var disabled = this.getDisabled();
if (disableOnEmpty) {
disabled = Ext.isEmpty(this.getValue());
}
this.setDisabled(disabled);
}
//filterFn:function(item){
//console.log(new Error().stack);
//}
}],
proxy: {
type:'ajax',
url:'users.json',
reader: {
type:'json'
}
}
}
}
});
https://fiddle.sencha.com/#fiddle/103r
What am i missing?
Did it myself.
So i had to define publishers in parent config:
users: {
alias:'store.users',
fields: ['id', 'category_id', 'number'],
autoLoad: true,
filters: [{
property:'category_id',
value: '{categoryCombo.value}',
//disabled: '{!categoryCombo.selection}',
disableOnEmpty:true,
//filter: function (item) {
// var me = this,
// filterFn = me._filterFn || me.getFilterFn(),
// convert = me.getConvert(),
// value = me._value;
// me._filterValue = value;
// console.log(value);
// me.isDateValue = Ext.isDate(value);
// if (me.isDateValue) {
// me.dateValue = value.getTime();
// }
// if (convert && !me.preventConvert[me.getOperator()]) {
// me._filterValue = convert.call(me.scope || me, value);
// }
//
// return filterFn.call(me.scope || me, item);
//},
updateDisableOnEmpty: function(disableOnEmpty) {
var disabled = this.getDisabled();
if (disableOnEmpty) {
disabled = Ext.isEmpty(this.getValue());
}
this.setDisabled(disabled);
}
//filterFn:function(item){
//console.log(new Error().stack);
//}
}],
proxy: {
type:'ajax',
url:'resources/data/users.json',
reader: {
type:'json'
}
}
}
{
// store: 'categories',
bind: {
store: '{categories}'
},
xtype: 'combo',
reference: 'categoryCombo',
displayField: 'name',
valueField:'id',
publishes:'value',
name: 'category',
typeAhead: false,
fieldLabel: 'Category',
emptyText: 'Select a category...',
anchor: '95%'
},
{
xtype: 'combo',
name: 'user',
reference: 'userCombo',
fieldLabel: 'User',
displayField: 'number',
valueField: 'id',
hiddenName: 'id',
emptyText: 'Select a user...',
anchor: '95%',
//store: {
// type:'users'
//},
bind: {
fieldLabel: '{categoryCombo.selection.name}',
//filters: [{
// property:'category_id',
// value: '{categoryCombo.value}'
// //disabled: '{!categoryCombo.selection}',
// //disableOnEmpty:true
//}],
store: '{users}'
},
listeners: {
change: 'onSelectChange'
}
}
Behind the scenes what's the difference between this config and bind store?How did binds affect on perfomance? is this angular like?
Related
So I have a combobox that is loaded dynamically for a certain view.
Whenever I put the queryMode to remote, it would load the data if I clicked the combobox, but if set to local it won't show any data.
My store will return the requested data properly, it's just it won't show in the combobox.
Am I missing something here?
Hope someone can help me.
This is my controller for the view with the combobox:
Ext.define('Stm.controller.HpUpdate', {
extend: 'Ext.app.Controller',
requires: [
'Stm.view.contents.hpupd.Detail'
],
stores: [
'SiteDomain'
],
fromDetail: false,
isAbort: false,
isDataSeted: false,
firstSorters: undefined,
recordId: undefined,
isUpdate: false,
init: function() {
this.callParent(arguments);
console.log(Ext.getDisplayName(arguments.callee));
this.control({
'hup-list': {
afterRender: this.setupStmList
}
});
this.addRef([{
ref: 'list',
selector: 'hup-list'
},
{
ref: 'detail',
selector: 'hup-detail'
},
]);
},
setupStmList: function() {
console.log(Ext.getDisplayName(arguments.callee));
var me = this;
var store = me.getSiteDomainStore();
var record = Cps.Util.baseRecord();
store.load({
params: param,
callback: function(records, operation, success) {
var response = operation.response;
if (!response || response.length === 0) {
return;
}
var responseText = response.responseText;
if (!responseText || responseText.length === 0) {
return;
}
var res = Ext.decode(responseText);
if (res.common.st === 'mainte' || res.common.st === 'abort') {
return;
}
if (res.common.st === 'ng') {
Cps.Util.alert(res.common.msg);
return;
}
if (records.length === 0) {
return;
}
me.getList().down('#dtAplDateTimeFrom').down('#dateField').focus();
}
});
me.firstSorters = this.getHpUpdateStore().getSorters();
},
});
This is my view:
Ext.define('Stm.view.contents.hpupd.List', {
extend: 'Ext.container.Container',
alias: 'widget.hup-list',
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'cps-combobox',
fieldLabel: 'Domain',
itemId: 'cmbSiteDomain',
queryMode: 'local',
store: {
type: 'sitedomain'
},
width: 350,
displayField: 'siteDomain',
valueField: 'siteId',
}],
});
Store:
Ext.define('Stm.store.SiteDomain', {
extend: 'Extends.data.Store',
alias: 'store.sitedomain',
requires: [
'Cps.Setting',
'Stm.model.SiteInfo'
],
model: 'Stm.model.SiteInfo',
pageSize: Stm.Const.controller.dataCountLimit,
proxy: {
type: 'ajax',
url: Cps.Setting.getEntryUrl() + '/stm/st-update/site-domain',
reader: {
type: 'json',
rootProperty: 'data'
},
actionMethods: {
create: 'POST',
read: 'POST',
update: 'POST',
destroy: 'POST'
}
}
});
When you set queryMode to local it means that data will not be loaded from remote source and data should be defined by for example Ext.data.ArrayStore
{
xtype: 'combobox'
queryMode: 'local',
valueField: 'id',
displayField: 'name',
store: new Ext.data.ArrayStore({
fields: ['id', 'name'],
data: [[1, 'item1'], [2, 'item2']]
})
}
If you want to data to be loaded from remote source just once and combo query data locally you should add store items manually
Define your combo like:
{
xtype: 'combobox'
itemId: 'myCombo'
queryMode: 'local',
valueField: 'id',
displayField: 'name',
store: new Ext.data.ArrayStore({
fields: ['id', 'name'],
data: []
})
}
And then add items to the combo like:
Ext.Ajax.request({
url : 'Remote_Source',
success: function(response, opts) {
var json = Ext.decode(response.responseText),
store = me.down("#myCombo").getStore();
Ext.each(json.items, function(item){
store.add(item);
});
}
});
Note: This is sample code you should add your implementation
This is exactly what I am doing. First I build my store by adding items. And then I use the store in my combobox with querymode: local. When I expand the combobox, no items show. When I change querymode to remote, the items show upon expansion, but they are grayed, as the store tries to load data from the server, which fails of course. I have not idea what to do about it. It looks like a bug to me.
I try to create a combobox(with autoCompleted) and a remote store.When a user types some letters in the combobox,it goes to the server to take a new Datastore.
And I get nothing in my combobox.What's wrong with my code?How can I do for this?
Here's my combobox:
Ext.define('HDDTest.view.mod.searchDetails', {
extend: 'Ext.Panel',
controller: 'home',
items: [
{
xtype: 'combobox',
width: 450,
id: 'createRelatedConceptComboBox',
name: 'createRelatedConceptComboBox',
fieldLabel: 'Test',
//hideTrigger:true,
valueField: 'text',
emptyText: 'Select Concept',
typeAhead: true,
typeAheadDelay: 350,
minChars: 1,
listeners: {
change: 'onRelatedConceptComboBoxClicked'
},
store: {
type: 'GetRelatedConceptStore'
}
}
]
});
Here's my controller:
Ext.define('HDDTest.controller.main.HomeController', {
extend: 'Ext.app.ViewController',
alias: 'controller.home',
onRelatedConceptComboBoxClicked: function (constructors, text) {
var getRelatedConceptStore = Ext.create('HDDTest.store.GetRelatedConceptStore');
getRelatedConceptStore.load({
params: {
sValue: 'text'
},
callback: function (records, success) {
},
scope: this
});
}
});
Here's my store:
Ext.define('HDDTest.store.GetRelatedConceptStore', {
extend: 'Ext.data.Store',
field: ['value', 'text'],
alias: 'store.GetRelatedConceptStore',
storeId: 'GetRelatedConceptStore',
autoSync: true,
autoLoad: true,
proxy: {
type: 'ajax',
url: "http://127.0.0.1/api/TSGH/GetAllSearchResults",
method: 'GET',
reader: {
type: 'json',
rootProperty: '',
transform: function (records) {
var data = new Array();
for (var i = 0; i < records.length; i++) {
data[i] = new Array();
data[i][0] = records[i].NCID;
data[i][1] = records[i].DEFAULT_NAME + '(' + records[i].NCID + ')';
}
console.log(data);
return data;
}
}
}
});
When I type some letters in my combobox I get nothing and without any error messages in my console window. How can I do for this?
Thanks in advance, Ben
There seems to be some error in the processing of transform() method or the Model field name for the displayField property.
Here is the working code with transform() method commented out.
I am trying the get a combox in a grid which select something in the editor function. But the rendering value is 0 each time. After saving it works correctly.
Ext.define('Shopware.apps.Order.view.detail.BackPosition', {
override: 'Shopware.apps.Order.view.detail.Position',
initComponent: function () {
var me = this;
me.mdsupplierStore = Ext.create('Shopware.apps.Order.store.MDSupplier').load();
me.callParent(arguments);
},
getColumns: function(grid) {
var me = this;
var col = me.callOverridden(arguments);
var md_supplier = {};
grid.mdsupplierStore = me.mdsupplierStore;
var MDSupplier= {
header: 'Lieferant',
dataIndex: 'md_supplier',
flex:2,
renderer: me.supplierColumn,
editor: {
xtype: 'combobox',
editable: false,
queryMode: 'local',
allowBlank: false,
store: grid.mdsupplierStore,
displayField: 'name',
valueField: 'id',
}
};
col = Ext.Array.insert(col, 9, [MDSupplier]);
return col;
},
supplierColumn: function(value, metaData, rowRecord) {
var me = this;
console.log(value);
//value is 0 when I click the editor combobox <---
},
});
Model:
Ext.define('Shopware.apps.Order.model.MDSupplier', {
extend:'Shopware.data.Model',
idProperty : 'id',
fields:[
{ name : 'id', type: 'int'},
{ name : 'name', type: 'string'}
]
});
Store:
Ext.define('Shopware.apps.Order.store.MDSupplier',{
configure: function() {
return { controller: 'MDSupplier' };
},
/**
* Define that this component is an extension of the Ext.data.Store
*/
extend: 'Ext.data.Store',
/**
* Auto load the store after the component
* is initialized
* #boolean
*/
autoLoad: false,
/**
* Define the used model for this store
* #string
*/
model: 'Shopware.apps.Order.model.MDSupplier',
proxy : {
type : 'ajax',
url: '/backend/MDSupplier/load',
reader:{
type: 'json',
root: 'data',
totalProperty: 'total'
}
}
});
Can anybody tell me, what am I doing wrong ?
I got it. The processing of the data was wrong, so the field was everytime NULL
I have a combo with a remote store in the modal window. To obtain the data is necessary to send an extra parameter to the store. This parameter is stored as a property of the window. How can I pass it?
This is my app.js file (I use MVC model, atleast try to use it :) ):
Ext.application( {
requires: [
'Ext.Ajax'
],
autoCreateViewport: true,
name: 'PM',
stores: [
...
'SourceIps',
...
],
models: [
...
],
controllers: [
...
],
init: function() {
}
} );
How I show window:
showAddRProbe: function () {
var data = {
'deviceId': this.getProbesDeviceCombo().getValue()
};
var addProbe = Ext.create( 'PM.view.AddProbe', [true, data] );
addProbe.show();
}
Window:
Ext.define( 'PM.view.AddProbe', {
extend: 'Ext.window.Window',
...
constructor: function( data ) {
this.newProbe = data[0];
this.probeData = data[1];
...
Required parameter passed as probeData.data.deviceId
Combo:
{
xtype: 'combo',
allowBlank: false,
blankText: Locale.gettext( 'Please select a Source IP' ),
fieldLabel: Locale.gettext( 'Source IP' ),
name: 'sourceIP',
triggerAction: 'all',
store: 'SourceIps',
value: Ext.getStore( 'SourceIps' ).getAt(0).get('id'),
valueField: 'id',
displayField: 'name',
queryMode: 'local'
}
Store:
Ext.define('PM.store.SourceIps', {
extend: 'Ext.data.Store',
model: 'PM.model.IdName',
autoLoad: true,
proxy: {
type: 'ajax',
api: {
read: 'data/getDeviceIps.php'
},
reader: {
type: 'json',
root: 'data',
successProperty: 'success',
messageProperty: 'message'
}
}
});
I tired to add extraParam as follow, but it does not work:
var probeData = this.getProbeWindow().probeData.data;
this.getSourceIpCombo().getStore().getProxy().setExtraParam( 'deviceId', probeData.deviceId );
this.getSourceIpCombo().getStore().load();
Use
this.getSourceIpCombo().getStore().load({
params: {
deviceId : probeData.deviceId
}
});
You could add storeId property to your store and then use
var store = Ext.data.StoreManager.lookup('myStore');
and use this to apply extra params:
Ext.apply(store.getProxy().extraParams, {
foo : 'bar',
...
});
or
store.getProxy().setExtraParam("countriesId", 1) // add parameter 'countriesId' = 1
I'm using ExtJS 4.1. I am trying to wait for all the the stores for comboboxes to load. I listen for the beforerender event of the window.
In this if the combobox count is not defined, then I get all the comboboxes, save the count, load the stores and register a callback that decrements the combobox count. When the count goes to zero, it call the show method, and the window is displayed.
If the combobox count is defined, then if it is zero, I return true to allow the window to show, otherwise I return false.
However, the problem is that not all of the comboboxes show the displayValue, and show the
valueField instead.
console.log('--- onWindowBeforeRender');
if (typeof this.comboboxCount != 'undefined') {
if (this.comboboxCount == 0) {
console.log('returning true:');
return true;
}
else {
console.log('returning false1:');
return false;
}
}
var x = component.query('combobox');
console.log('x.length:');
console.log(x.length);
this.comboboxCount = x.length;
for (var i = 0; i < x.length; i++) {
var y = x[i];
console.log('y:'+i);
console.log(y);
y.store.load({
scope: this,
callback: function(records, operation, success) {
this.comboboxCount--;
console.log('comboboxCount:' + this.comboboxCount);
if (!this.comboboxCount) {
console.log('all stores loaded.');
this.show();
}
}
});
}
console.log('returning false2');
return false;
Here is the code for the comboboxes:
{
xtype: 'combobox',
anchor: '100%',
fieldLabel: 'Region',
name: 'region_id',
displayField: 'name',
store: 'RegionStore',
valueField: 'id'
},
{
xtype: 'combobox',
anchor: '100%',
fieldLabel: 'Country',
name: 'country_id',
displayField: 'name',
store: 'CountryStore',
valueField: 'id'
}
Here are the stores:
Ext.define('RR.store.CountryStore', {
extend: 'Ext.data.Store',
requires: [
'RR.model.CountryModel'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'RR.model.CountryModel',
storeId: 'CountryStore',
proxy: {
type: 'ajax',
api: {
create: '/country/create',
read: '/country/read',
update: '/country/update'
},
reader: {
type: 'json',
root: 'countrys'
}
}
}, cfg)]);
}
});
Ext.define('RR.store.RegionStore', {
extend: 'Ext.data.Store',
requires: [
'RR.model.RegionModel'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'RR.model.RegionModel',
storeId: 'RegionStore',
proxy: {
type: 'ajax',
api: {
create: '/region/create',
read: '/region/read',
update: '/region/update'
},
reader: {
type: 'json',
root: 'regions'
}
}
}, cfg)]);
}
});
I have resolved the issue. The store for the combobox was requesting only 25 records at a time. Not all of the records were loaded. and therefore the id was not being found and the displayField's value was being set to the valueField.
Changing the server side code to ignore start/limit solved the problem.
From the store's documentation:
If this store is buffered, this can ONLY find records which happen
to be cached in the page cache. This will be parts of the dataset
around the currently visible zone, or recently visited zones if
the pages have not yet been purged from the cache