How to call the remote store for combobox in extjs v7.5? - extjs

I have a combobox with data downloaded from a remote server. I want a request to be sent every time I click on the combobox, because I want to dynamically set parameters in proxy.setExtraParams(params). I set params in beforeQuery function.
I have this example that I found on the Internet. In my application, the combo works in a similar way. https://fiddle.sencha.com/#fiddle/3ij5&view/editor
However, it works fine in version 7.4 and does not work in version 7.5.
The documentation for 7.5 says that when queryMode: 'remote' you have to manually load the store. Where do I call store.load() so that the combo has time to process the parameters for the proxy?

You have to set the autoLoad to true.
Because you do not want to load the store initially, you have to add a listener (as you did) and set the autoLoad.
You just want to call the listener once, because after that the autoLoad is set.
listeners: {
beforeQuery: {
fn: function (queryPlan) {
console.log('[ComboBox::beforeQuery] set autoLoad to true');
this.getStore().setAutoLoad(true);
return queryPlan;
},
single: true
}
}

Related

ExtJs 6 checkcolumn listener when cell's red flag is removed or known to stay

I am having a table with checkcolumn (Ext.grid.column.Check) items.
When (un-)checking an item an ajax callback is immediately done to the backend.
There is two outcomes:
- successfully handling by the backend and the flag disappears, or
- the flag stays. but it is not determinable from user's point of view when that happened.
During the call a small red flag is shown on top left corner of the cell.
If the backend call returns successful the red flag gets removed; otherwise it stays.
Now I need a listener callback for when the ajax call has returned.
There is a bunch of listeners at https://docs.sencha.com/extjs/6.0.0/classic/Ext.grid.column.Check.html#events but I do not find the one helping me with my problem.
Why I ask? - I want to show a page wide unmodifiable wait layer/icon during the backend call. The layer must be removed after the call has finished no matter how successfully it did finish.
Your checkcolumn is part of a grid which is bound to a store. The checkcolumn does not have anything to do with the synchronization itself. Synchronization is part of the store. Obviously, since you tell us that sync is executed whenever you click on a checkbox, you have set the store to autoSync: true, which limits your options because it hides the work and does not intuitively allow you to add a sync callback to the store.
If you do the sync manually, you can add a callback to the sync:
store.sync({
callback: function(batch) {
...
}
});
This callback is executed when the XmlHttpRequests are finished, regardless of their outcome; and you can then check the state of each batch or the state of the store and act accordingly (e.g. MessageBox).
Also, you could override the onEndUpdate function on your store, and add the callback option to the sync that is triggered there.
For solving my issue I did have to use Ext.data.Store implementation.
Checking on the operation value solved it for me.
Ext.define('MyDataStorage', {
extend: 'Ext.data.Store',
...
autoLoad: true,
autoSync: true,
remoteFilter: true,
remoteSort: true,
listeners: {
update: function(store, record, operation, modifiedFieldNames, details, eOpts) {
if ( 'commit' == operation ) {
Ext.ComponentQuery.query('#someList')[0].doSomething();
}
},
}
});
The autoSync:true was set like Alexander guessed. I was not able to do the sync differently.
Thank you Alexander for your expertise and hint.

Multiple classes in Ext JS to update and share the same config settings

I am fairly new to using Ext JS 4.0.7, and have recently discovered the Config options, so I have set up the following config class, which initialises with the following:
Ext.define('CurrentRowSelection', {
extend: 'Ext.app.Controller',
config: {
currentAccountID: {
$value: 'Empty',
cached: true,
evented: true
}
},
initialize: function(config) {
this.callParent(config);
}
});
I am able to update this config quite nicely from another class's listener event, which is right clicking on a row record and grabbing the currentAccountID value. However, every time I try to access the new, updated, config from a new class after initialising - it keeps reverting back to the 'Empty' value.
The following is used to set the config from the class containing the listener:
var CurrentRowSelection = new CurrentRowSelection();
CurrentRowSelection.setCurrentAccountID(1);
However, when I create a new constructor in a new class, with the hope of accessing this newly updated config from elseware, my console.log is telling me that it is continuously reverting back to the default values, as it seems to be initialising each time a new constructor is created - which makes sense, but I need to stop it.
How can I do thisand make sure that this value is saved all the time, every time? Thank you.
Don't make new controllers every time. Every controller should be instantiated only once, because if you instantiate multiple controllers of the same type, every event binding you prepare in the control method is executed multiple times (the control method usually is the most important method of a controller, although there may be exceptions.)
So every controller should exist as a single instance only, and that singleton would be accessed using getController wherever and whenever you need it:
MyAppName.app.getController("ControllerName").setCurrentAccountID(1)
That said, I would recommend to look into using stores for data storage, not controllers. Stores offer the possibility to synchronize the settings with a server (create, read, update, delete). If you want to create a singleton store, you would give it a storeId and use Ext.getStore() to access the store.
For example, the config settings in my application are in the first record of the store with storeid AllSettings:
Ext.getStore("AllSettings").getAt(0).get("groupDiscoveryCacheHours")

ExtJS 4. Hidden treepanel with autoload false

I have a treepanel inside my form. The code is
{
xtype:'treepanel',
rootVisible:false,
hidden:true,
autoload:false,
store:{autoload:false,proxy:{type:'ajax',url:'../json/objectList.php?id='+id},root:{text:'Objects',id:'src',expanded:true}},
listeners:{
show:function(){
this.store.load();
}
}
}
The problem is, I want to prevent loading before the tree is shown. But setting autoload to false does not have any effect. I still see a server request, even if the tree is hidden.
The autoLoad property does not work for tree stores as the load is based on the expansion of the node as you are doing for root. This is what I do to overcome it.
In your store confing
root:{
text:'Objects',
id:'src',
expanded:true,
children:[]
}
Setting an empty children object will prevent the store load. Then all you need to do is set up a listener on the tree view to load the store as you have done. You will need to modify the server code to return the data without the children property...so just the array.

ExtJs combobox stores loading and form

I have a problem with comboboxes on my form.
The problem is that when I load form data (with form.loadRecord) sometimes comboboxes are empty even though I know that the model has the data.
When I look into Firebug I can see that the combobox stores are loaded after the record has been loaded. I thinks this is the reason – the combobox stores are loaded later then record is loaded.
This is how I set combobox stores:
//All stores have autoload:true configuration.
var possessionGroundsStore = Ext.create('path.to.store');
var vehicleTypesStore = Ext.create('path.to.store');
var usePurposesStore = Ext.create('path.to.store');
this.editView = Ext.create('path.to.view');
this.editView.getPossessionGroundsField().store = possessionGroundsStore;
this.editView.getVehicleTypeIdComboBox().store = vehicleTypesStore;
this.editView.getUsePurposeField().store = usePurposesStore;
//later
this.editView.loadRecord(record);
Is there a common way to solve this problem?
The only way I can see now is to use store.load callbacks in every combobox store
and then execute loadRecord after all stores were loaded, but it seems complex.
Any help?
UPDATE:
When form.loadRecord is called it internally calls field.setValue().
So, the point is: combobox store have to be populated before setValue is called.
If the store is not loaded you will see valueField instead of displayField.
The default config for comboboxes will trigger a store load when they get expanded for the first time after being created.
That will happen for any combobox unless you give it a queryMode: 'local' config. In other words the default combobox config almost always completes loading it's store after the component is created. For that reason, it seems strange to me that your combos are having a hard time with being loaded too late, maybe they are being loaded too early with autoLoad: true
However, I don't run into the same problem you have because I usually set-up my comboboxes with queryMode: 'local' and pre-load the stores for them right at the app initialization stage. I do that because my combo stores are usually all reference stores that could get used in many different views in my app. I don't recreate the store when I create a combo component, I just get a reference to the already existing and loaded reference store with Ext.getStore('ComboStoreId'). You could try setting up your app like that.
If you don't want to do that, you could also try removing the autoLoad: true config from your combo stores, then call yourComboStore.load() after you call loadRecord.

ExtJS 4 URL is undefined when I try store.load()

I have a Panel with multiple grids. I'm trying to make some kind of global refresh button by which I mean, a button that will refresh all the grids and open tabs, without losing data like when F5 is pressed.
With two of the grids it was easy just get the store and load it but the third one makes a problem. When I try the same as with the previous two which works OK I get URL is undefined.
Here is my code:
reloadInstructionsStore: function() {
var reloadInstructionSt = this.getStore('Instructions');
var activeCat = this.getActiveCategory();
reloadInstructionSt.clearFilter(true);
reloadInstructionSt.filter({
filterFn: function(item) {
return item.get('category_id') == activeCat;
}
}),
reloadInstructionSt.load();
},
The only reason I can think of is that the store that I use here is defined different from the other 2. It's not with PROXY and CRUD, but looks like this:
Ext.define('MY.store.Instructions', {
extend: 'Ext.data.Store',
model: 'MY.model.InstructionRecord',
autoLoad: true,
data: g_settings.instructionsApi.initialData
});
Is the problem here and is there a way to make things work even like this?
Thanks
Leron
You do not need to reload this store, the data is provided on initial page load. The variable g_settings.instructionsApi.initialData tells me that the data is available as static on the page. All you need to do in this case is reset the filter, and just remove the reloadInstructionSt.load(); call.
If you actually do want the data to reload from the server, you will need to give your store a url that it can get the data from and the server will have to be able to serve this data up.

Resources