10

How do I send extra parameters when using a store for a combobox in ExtJS 4?

I know that I can use "extraParams" in the proxy-settings, but that will affect ALL elements that is using the same store.

I.e if I have a Grid that is using a store called "Users" that will list all users in a system. At the same time, I have a combobox, that also uses the store "Users", but this time I want to list all Users that has "status=2", thus I want to send the param "&status=2" on the Ajax call to the back-end.

If I use something like:

store.getProxy().extraParams = {
  status: 2
};

It will work, but the Grid will at the same time be updated to also use "&status=2". I ONLY want the combobox to use the param.

I guess I could turn off "autoupdate" on the Grid, then set the "extraParams" on the "render" event on the combobox and then unset it when the combobox gets hidden, but what would be a very ugly solution.

I can also duplicate the store to a "Users2" and use that one for the combobox, but that is a ugly solution as well.

What is the correct way to do this? It must be a very common thing for most people.

UPDATE 1:

I know I can use something like:

store.load({
  params:{
    'foo1': bar1,
    'foo2': bar2
  } 
});

But how would I use that in ExtJS 4 MVC? There I just specify "store: Users" in the form-object. How would I send those extra parameters to the .load() function?

I have tried the following:

{
xtype: 'combobox',
fieldLabel: 'Server',
name: 'server',

//store: 'ServersIP',
store: new Cloud.store.ServersIP(),

/*
listeners: {
    beforeload: function(store, options) {
        console.log(store);
    }
},
*/

valueField: 'id',
displayField: 'name_id',
emptyText: 'Select a Server...',
editable: false
},

However, it gives error "Uncaught TypeError: Cannot read property 'ServersIP' of undefined"

But the name is correct:

Ext.define('Cloud.store.ServersIP', {

extend: 'Ext.data.Store',
model: 'Cloud.model.Server', 

Also, where exactly would I put the listener? I assume I did not get that one correct in my example either?

UPDATE 2:

I've got a little bit further to a solution now:

store: Ext.create('Cloud.store.ServersIP', {
proxy: {
    extraParams: {
        param1: 'value1',
        param2: 'value2'
    }
},                          
}),

The above does NOT work. It works if I only have a "one-level" variable in the params to Ext.Create. For some reason, it does not like it when I pass in proxy => extraParams => param1.

This one works:

store: Ext.create('Cloud.store.ServersIP', {
aaa: 'bbb'
}),

But then of course, my extraParams are not there. Anyone know how to fix this last part?

Daniele Testa
  • 943
  • 3
  • 9
  • 24

5 Answers5

9

I just solved this problem. combobox queryMode:remote with extra parameters.

just instantiate the store in "VIEW" inside initComponent and override the proxy

//instantiate the store

var store = Ext.create('Cloud.store.ServersIP', {
    storeId: 'YourStoreId'
});
store.proxy.extraParams = { param1: 'value1', param2: 'value2' };

and in xtype:combobox

//set combobox store

{
    xtype: 'combobox',
    queryMode:'remote',
    store : Ext.data.StoreManager.lookup('YourStoreId'),
    ...
    ...
}

I hope you understand my proposed solution.

Abdul Rehman Yawar Khan
  • 1,019
  • 2
  • 17
  • 37
2

Instead of referencing the same store as the grid you can create a new instance of the same store. This way the two store instances are managed separately.

So in your form replace store: 'Users' with store: new MyApp.store.Users() and then you can use whichever method works better for you (extraparams, load with params, beforeload listener, etc)

dbrin
  • 15,197
  • 4
  • 51
  • 82
  • This sounds exactly what I want. However, I cannot get it to work. I have updated my question. – Daniele Testa Jul 21 '13 at 20:15
  • Yes can confirm it not working. tried for 3 days... no luck it is an extjs bug with filters and stores. You cant even make the extra params as post as result. – Sangoku Jun 17 '15 at 07:29
2

You can catch the 'beforeload' store event and alter the current load-operation. This way the parameters won't persist to other requests.

Ext.create('Ext.data.Store', {
    model: MyModel,
    autoLoad: true,
    listeners:{
        // Fires before a request is made. op is an Ext.data.Operation object
        beforeload:function(store,op){ 
            // Set request parameters (without overriding other parameters)
            op.params = Ext.apply(op.params||{},{
                someParam:true
            });
        }
    }
});
TheZver
  • 1,284
  • 2
  • 13
  • 17
  • Reviewer here: Please provide a brief description of how your code works to help the asker *understand* it better. – Suever Apr 10 '16 at 15:55
  • 1
    @TheZver, in Ext JS 6.0.1 I had to update it a little bit: op.setParams(Ext.apply(op.getParams()||{},{ ... – Alexandr Oct 18 '17 at 16:09
1

You can set autoLoad to false on your store, and then call the load method yourself, and use the params option:

var store = Ext.create('My.Store', {
    autoLoad: false
    ...
});

store.load({
    params: {status: 2}
});

That will work if you need your combo to load only once and then query in local mode. If you need your combo to make multiple calls to the server (remote mode), set your params in the beforeload event of the store:

comboStore.on('beforeload', function(store, operation) {
    operation.params = operation.params || {};
    operation.params.status = 2;
});
rixo
  • 18,198
  • 3
  • 35
  • 50
  • 1
    Your example does not use MVC that is used in ExtJS 4. How would I specify those load-params in MVC? There I just set "Store: Users" on the form-object. – Daniele Testa Jul 20 '13 at 14:37
  • Also, the Grid is using the same Store. Putting the store to "autoLoad=false" will force me to manually load the store in ALL the places where the store is used. I use that store in many places in my application. – Daniele Testa Jul 20 '13 at 14:39
  • Using the same store instance for the grid and the combo is begging for problems. When your combo will filter its store in order to apply its query, that will also filter your grid. That's probably not what you want. You should provide the combo with its own store by providing a configuration with `xtype` or `xclass`. – rixo Jul 20 '13 at 14:51
  • Yes, that is the way I have it now, but I think that is an ugly solution. I would prefer to be able to use one generic store and then apply parameters depending on what object is using the store. Like the grid might want "&status=1&clean=1" and the combobox might want "&status=2&clean=0". Pretty crappy that ExtJS does not support this by default. All that would be needed is to be able to put the "params" directly on the object that is using the store. – Daniele Testa Jul 20 '13 at 15:21
  • There is another problem that you are overlooking and that is data binding to views. If you change the same store instance in one view the other view will change with it leading to strange unexpected problems. – dbrin Jul 21 '13 at 01:45
1

This is the best code I could come up with. No listener is needed :)

Create a new instance of the "users"-store and change the params in that one.

xtype: 'combobox',
fieldLabel: 'Users',
name: 'users',

store: (function() {
  var s = Ext.create('MyApp.store.Users');
  s.proxy.extraParams = {
    active: '1'
  }
  return s;
})(),
Daniele Testa
  • 943
  • 3
  • 9
  • 24
  • 1
    Proxy is shared between all instances of a store class (and the associated model), so that will set extraParams for all instances of `MyApp.store.Users`... – rixo Jul 24 '13 at 13:59
  • 1
    My test result shows that it did set extraParams for all instances of MyApp.store.Users. – realjin Oct 14 '14 at 16:08