Extjs Combo - How to load value to combo using GetForm().load - extjs

I have a combo box inside a form like:
xtype: 'combo',
id: 'example',
name: 'ax',
triggerAction: 'all',
forceSelection: true,
editable: false,
allowBlank: false,
fieldLabel: 'example',
mode: 'remote',
displayField:'name',
valueField: 'id',
store: Ext.create('Ext.data.Store', {
fields: [
{name: 'id'},
{name: 'name'}
],
//autoLoad: false,
proxy: {
type: 'ajax',
url: 'example.php',
reader: {
type: 'json',
root: 'rows'
}
}
}
})
I don't want that auto load because that's slow when i start.
But i want set a value to combo box when i click edit button and load value to combo
this.down('form').getForm().load({
url: 'load.php',
success:function(){
}
});
data from load.php like (name of combe is ax)
{ success:true , data : { ax: '{"id":"0","name":"defaults"}' } }
But that's not working. How can i do that thanks.
p/s: If i have autoLoad : true and data is { success:true , data : { ax: '0' } } that's work well. But that's slow when i start.

What you want to do is make sure the combo is loaded before you try to set it's value.
You could check if the combo's store has any data in it:
if(combo.getStore().getCount() > 0)
{
//the store has data so it must be loaded, you can set the combo's value
//doing a form.load will have the desired effect
}
else
{
//the store isn't loaded yet! You can't set the combo's value
//form.load will not set the value of the combo
}
If it does, you can just set the value. But more likely however it will not have been loaded.
You could also do something like this
//in the controller's init block
this.control({
"#myEditButton" : {click: this.loadForm}
});
//a function in your controller
loadForm: function(button)
{
var combo; //get your combo somehow, either via references or via the button
combo.getStore().load({
scope: this,
callback:
function(records, operation, success)
{
if(success)
{
//load your form here
}
}
});
}
I know that might seem like a lot of code, but it's the only way to know for sure if the combo was loaded. If it is not, you cannot set it's value.
A third option would just be to explicitly load the store before you open your view.

Related

How to load data into Combobox?

I try to fill the form with the response data from the backend,but my formpanel contains combobox,how could load the data into combobox.
I tried to use the method setValues() in formpanel,and I set the displayField and valueField, but the combobox still shows [object,object].
Here is my store code
Ext.define('Servicemsg.directory.AppSystemStore', {
extend:'Ext.data.Store',
fields:['id','code','name','comments','lastupdatetime'],
proxy:{
type:'ajax',
url:'',
reader:{
type:'json',
}
},
})
Here is the code of combobox
{
xtype: 'combobox',
label: 'Provider',
name:'provider',
store:Ext.create('Servicemsg.directory.AppSystemStore'),
displayField:'name',
valueField:'id',
autoLoadOnValue:true
}
Here is my request code
form.load({
url:'#url#'+data.id,
success:function (form,result,data) {
form.setValues(result.result);
}
});
Response data like this
{
name:'',
text:'',
id:'',
provider:{
id:'',
name:'',
}
}
You can grab the combobox of the form and add the values to the combobox's store manually. Once the combobox store has the values, you can set a value to the combobox if applicable.
form.load({
url:'#url#'+data.id,
success:function (form,result,data) {
const combobox = form.down('combobox');
combobox.getStore().add(results.providers);
combobox.setValue(/*value that the comobobox should show*/);
form.setValues(result.result);
}
});
It seems like in this case using a store is overkill. Considering you have an
empty proxy and are just using it to try and load data into your combobox.
Instead you should create a View Model and with a property comboBoxData. You should
then bind this value to the data property on your combox box.
This is what your model would like like
Ext.define('Fiddle.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
data: {
comboBoxData: null
}
});
This is what your combo box should look like
{
xtype: 'combobox',
label: 'Provider',
name: 'provider',
displayField: 'name',
valueField: 'id',
autoLoadOnValue: true,
bind: {
data: '{comboBoxData}'
}
}
This is what your success function would look like.
(How you get the view model will depend on where this is being called)
success: function (form, result, data) {
var vm = this.lookupViewModel();
vm.set('comboBoxData', result.result);
}
You may have to tweak this for you specific implementation. But, hopefully this gives you a good idea of the best approach for this.

default value in combobox as value from store

I'm trying to get a return value of my json store to setValue in my combobox. The value of this json value is the current selected option in the database. My this.selectedCat store returns the current category value of the record where it's working in. my this.store returns all the available select options.
var fields = {
fields: ['text']
};
var notfields ={
fields:['category']
}
this.store = new GO.data.JsonStore({
url: GO.settings.modules.infoscherm.url + 'json.php',
baseParams:{
task:'selects'
},
root: 'results',
fields: fields.fields
});
this.selectedCat = new GO.data.JsonStore({
url: GO.settings.modules.infoscherm.url + 'json.php',
baseParams: {
task:'currentselectedcat',
id:'id'
},
root: 'results',
fields: notfields.fields
});
this.category = new Ext.form.ComboBox({
name: 'category',
width: 100,
store: this.store,
fieldLabel: "Categorie",
displayField:'text',
triggerAction: 'all',
editable: false,
selectOnFocus:true,
value: this.selectedCat //returns [object Object] naturally
});
Am I doing something wrong?
I think you need to start listening the "load" event of "Ext.data.JsonStore".
And the attached handler of "load" event will contain code to select any particular value by using "setValue" function of combobox object...
P.S. : Store values are made available in combobox drop down menu only if you configured the "store" config of combobox to the store object, in your case, you need to implement some logic within the handler of "load" event.

ExtJS combobox not rendering

I have a combobox editor for a grid column. It is editable too. The store for the combobox has autoLoad config, set to false implying that when the user clicks on the combobox, the store is loaded. It works fine if I don't type in anything in the combobox and click on it. However, if I type something first in the combobox, then click outside and then again click on the combobox to load the dropdown, it doesn't render at all. It just shows loading and then doesn't display the drop down.
It's a very weird problem as I have similar comboboxes for other columns as well which work fine but they are not editable.
Is this anything to do with the editable config?
var contextDropDownStoreforFactGrid = Ext.create('Ext.data.Store', {
fields: [{name:'context',type:'string'}],
proxy: {
type: 'ajax',
url: context + '/FcmServlet',
extraParams: {
'action': 'getContextDropDownValues'
},
reader: {
type: 'json'
}
},
autoLoad: false /* load the store only when combo box is selected */
});
editor: {
xtype: 'combo',
store: contextDropDownStoreforFactGrid,
qureyMode: 'remote',
id: 'fact_contextId',
displayField:'context',
valueField: 'context',
vtype: 'alphanum',
listeners: {
beforeQuery: function(query) {
if (contextDropDownStoreforFactGrid.getCount() != 0) {
contextDropDownStoreforFactGrid.removeAll();
contextDropDownStoreforFactGrid.load();
}
}
}
},
renderer: function(value) {
var index = contextDropDownStoreforFactGrid.find('context', value);
if (index != -1) {
return contextDropDownStoreforFactGrid.getAt(index).data.context;
}
return value;
}
You have a spelling error in your combobox configuration:
qureyMode: 'remote',
should be
queryMode: 'remote',
This is probably causing the combobox not to load data from your store.

remote combobox gives AJAX call for the first time even if it is cascaded

Team,
I am having strange problem.
I am having two combo-boxes and I want to cascade one of them using the value of other.
So on select event of one combo-box I am getting another combo box and loading that store.
But what I have observed is the below case.
User selects first combo box value for very first time so store is loaded for second combo box.
When user selects second combo-box for very first time then AJAX call is made don't know why ?
Once again if user selects combo-box one then store is loaded for combo-box second
When user selects second combo-box once again AJAX call is not made (Why AJAX call is made for the first time)
I am not able to understand during step 2 why AJAX call is made for second combo as it is already loaded in step 1.
Code details
xtype: 'combo',id='firstcombo', name: 'DEFAULT_VALUE' ,minChars:2, value: decodeHtmlContent('') ,width:200 ,listWidth:500, resizable: true,
valueField : 'id', displayField: 'id', pageSize: 15,forceSelection:true, enableKeyEvents: true,
store: new Ext.data.Store({reader: new Ext.data.CFQueryReader({id: 'NAME',
fields:[{name:'id', mapping:'id'}]}),
fields: [{name:'id', mapping:'id'}],
url:'server/ajax/Params'
}
}),
listeners : {
select:function(combo, record, index) {
this.setRawValue(decodeHtmlContent(record.get('id')));
cascadeFields();
}
xtype: 'combo',id='secondcombo', name: 'DEFAULT_VALUE' ,minChars:2, value: decodeHtmlContent('') ,width:200 ,listWidth:500, resizable: true,
valueField : 'id', displayField: 'id', pageSize: 15,forceSelection:true, enableKeyEvents: true,
store: new Ext.data.Store({reader: new Ext.data.CFQueryReader({id: 'NAME',
fields:[{name:'id', mapping:'id'}]}),
fields: [{name:'id', mapping:'id'}],
url:'server/ajax/Params',
baseParam:{valuefirst:''}
},
listeners: {
beforeload: function(store, options) {
var value = Ext.getCmp('fistcombo').value;
Ext.apply(options.params, {
valuefirst:value
});
},
}),
listeners : {
select:function(combo, record, index) {
this.setRawValue(decodeHtmlContent(record.get('id')));
}
function cascadeFields()
{
var combo = Ext.getCmp('secondcombo');
if(combo.store)
{
var store = combo.store;
combo.setDisabled(true);
combo.clearValue('');
combo.store.removeAll();
combo.store.load();
combo.setDisabled(false);
}
}
You should specify no autoload on the stores:
autoload: false
And on the combo boxes, you should set the querymode to local:
queryMode: 'local'
Edit: You might want autoload on the first combo store though.

EXTJS 3.2.1 EditorGridPanel - ComboBox with jsonstore

I am using EXTJS with an editorgridpanel and I am trying to to insert a combobox, populated with JsonStore.
Here is a snapshot of my code:
THE STORE:
kmxgz.ordercmpappro.prototype.getCmpapproStore = function(my_url) {
var myStore = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: my_url
, method: 'POST'
})
, reader: new Ext.data.JsonReader({
root: 'rows',
totalProperty: 'total',
id: 'list_cmpappro_id',
fields: [
{name: 'list_cmpappro_id', mapping: 'list_cmpappro_id'}
, {name: 'list_cmpappro_name', mapping: 'list_cmpappro_name'}
]
})
, autoLoad: true
, id: 'cmpapproStore'
, listeners: {
load: function(store, records, options){
//store is loaded, now you can work with it's records, etc.
console.info('store load, arguments:', arguments);
console.info('Store count = ', store.getCount());
}
}
});
return myStore;
};
THE COMBO:
kmxgz.ordercmpappro.prototype.getCmpapproCombo = function(my_store) {
var myCombo = new Ext.form.ComboBox({
typeAhead: true,
lazyRender:false,
forceSelection: true,
allowBlank: true,
editable: true,
selectOnFocus: true,
id: 'cmpapproCombo',
triggerAction: 'all',
fieldLabel: 'CMP Appro',
valueField: 'list_cmpappro_id',
displayField: 'list_cmpappro_name',
hiddenName: 'cmpappro_id',
valueNotFoundText: 'Value not found.',
mode: 'local',
store: my_store,
emptyText: 'Select a CMP Appro',
loadingText: 'Veuillez patienter ...',
listeners: {
// 'change' will be fired when the value has changed and the user exits the ComboBox via tab, click, etc.
// The 'newValue' and 'oldValue' params will be from the field specified in the 'valueField' config above.
change: function(combo, newValue, oldValue){
console.log("Old Value: " + oldValue);
console.log("New Value: " + newValue);
},
// 'select' will be fired as soon as an item in the ComboBox is selected with mouse, keyboard.
select: function(combo, record, index){
console.log(record.data.name);
console.log(index);
}
}
});
return myCombo;
};
The combobox is inserted in an editorgridpanel.
There's a renderer like this:
Ext.util.Format.comboRenderer = function(combo){
return function(value, metadata, record){
alert(combo.store.getCount()); //<== always 0!!
var record = combo.findRecord(combo.valueField || combo.displayField, value);
return record ? record.get(combo.displayField) : combo.valueNotFoundText;
}
};
When the grid is displayed the first time, instead of have the displayField, I have : "Value not found."
And I have the alert : 0 (alert(combo.store.getCount())) from the renderer.
But I can see in the console that the data have been correctly loaded!
Even if I try to reload the store from the renderer (combo.store.load();), I still have the alert (0)!
But when I select the combo to change the value, I can see the data and when I change the value, I can see the displayFiel!
I don't understand what's the problem?
Since now several days, I already tried all the solutions I found...but still nothing!
Any advice is welcome!
Yoong
The core of the problem is that you need to hook an listener which will execute after the grid store loaded. That listener will then convert the combo grid content to the displayField content instead of valueField.
Here is my resolution to this issue.
Ext.ns("Ext.ux.renderer");
Ext.ux.renderer.ComboBoxRenderer = function(combo, grid) {
var getValue = function(value) {
var record = combo.findRecord(combo.valueField, value);
return record ? record.get(combo.displayField) : value;
};
return function(value) {
var s = combo.store;
if (s.getCount() == 0 && grid) {
s.on({
load: {
single: true,
fn: function() {
grid.getView().refresh()
}
}
});
return value
}
return getValue(value)
}
};
You can use this renderer in your code like the following:
{
header: 'Header',
dataIndex: 'HeaderName',
autoWidth: true,
renderer: Ext.ux.renderer.ComboBoxRenderer(combo, grid),
editor: combo
}
This is a common issue. If you need a store value to display in the combo, handle the store's load event and select the appropriate value in the combo only after that. You shouldn't need a specific record just to render the combo up front.
I would recommend adding the field required from the combobox's store, to the grid's store, and change the renderer to use that field. (It does not have to be in the database)
and on the afteredit event of the grid, grab that value from the combobox's store and copy it to the grid's store.
This would yield better performance.
Actually, the problem seems to be that the grid renders the combobox values BEFORE the loading of the store data.
I found something here.
But when I applied the override, still the same problem...
The question i: how to defer the render of the combobox, waiting for the loading of the store?

Resources