PDA

View Full Version : [CLOSED] Local Filtering on ComboBox



ptrourke
May 28, 2014, 7:47 PM
Is there a sample showing a way to apply a local filter on a ComboBox, similar to the
<ext:GridFilters Local="true" /> feature on GridPanels? I ask because I have a store which is modified and filtered locally in a grid panel and, if possible, I would like to display filtered data from that store in a combobox without using the code behind and without modifying the store.

I have a data model in which there are Items, Varieties, and Types.
* Each Item belongs to one Variety, each Variety has one or more Items.
* Each Variety belongs to one Type, and each Type has one or more Varieties.
* Items can be moved from Variety to another, as long as the two Varieties belong to the same Type.

So I am working on a form for shifting items from one Variety to another.

I have a Store for the Varieties I am working with, called the "SelectedVarietiesStore." It is populated in JavaScript using an Add function that works well. The store is defined like this:



<ext:Store ID="SelectedVarietiesStore" runat="server" AutoDestroy="false" runat="server" AutoLoad="false" AutoDataBind="false" ClientIDMode="Static">
<Proxy>
<ext:PageProxy NoCache="true" />
</Proxy>
<Model>
<ext:Model ID="SelectedVarietiesModel" runat="server" ClientIDMode="Static">
<Fields>
<ext:ModelField Name="VarietyName" Type="String" />
<ext:ModelField Name="VarietyID" Type="Int" />
<ext:ModelField Name="TypeID" Type="Int" />
</Fields>
</ext:Model>
</Model>
</ext:Store>



There is a grid that shows the values from this store, and a context menu item that allows me to selected a Variety and move items from that Variety to a related one of the same Type. If I select this menu item, it opens a form with two ComboBoxes, the FromVariety and ToVariety, passing the VarietyID and the TypeID of the selected Variety to the form:



<ext:ComboBox ID="FromVarietyBox" runat="server" QueryMode="Local" Editable="false" StoreID="SelectedVarietiesStore" DisplayField="VarietyName" ValueField="VarietyID" FieldLabel="From Variety"></ext:ComboBox>
<ext:ComboBox ID="ToVarietyBox" runat="server" QueryMode="Local" Editable="false" StoreID="SelectedVarietiesStore" DisplayField="VarietyName" ValueField="VarietyID" FieldLabel="To Variety"></ext:ComboBox>


Now, the second ComboBox should be filtered to show only values which DO have the TypeID passed to the form, but do NOT have the VarietyID passed to the form (because I am constraining the target Variety to only those Varieties of the same Type which are not of the same Variety).

Because the SelectedVarietiesStore is populated locally, and not from a database, I do not want to do an Ajax or Postback to bind this ComboBox, I want to filter the values already in the store.

I believe that I am supposed to use the Query functionality to do this, but I can't find an example that matches what I'm trying to do. I looked at http://forums.ext.net/showthread.php?10943-CLOSED-Local-datastore-filtering-param-when-getting-data-to-combo-in-local-mode, but I can't figure out who what is going on there would apply to my situation.

Any suggestions or examples would be appreciated. Thanks!

Daniil
May 29, 2014, 6:15 AM
Hi @ptrourke,

You cannot have the same Store for two ComboBoxes if you need to show different data in those ComboBoxes. For example, if you filter a Store's data it affects all the components which the Store is associated with. Such a limitation of StoreID. (Btw, it should be OK in Ext.NET v3 / ExtJS 5).

So, you are going to use different Stores for both the ComboBoxes.

To load data I would suggest to use a Store's loadData JavaScript method.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store-method-loadData

ptrourke
May 29, 2014, 4:58 PM
Hi @ptrourke,

You cannot have the same Store for two ComboBoxes if you need to show different data in those ComboBoxes. For example, if you filter a Store's data it affects all the components which the Store is associated with. Such a limitation of StoreID. (Btw, it should be OK in Ext.NET v3 / ExtJS 5).


Thanks for this, Daniil. I hadn't noticed that a filter on one component affects any other components using the same store.

Does this also affect reading the store in JavaScript? For instance, I am saving the contents of the modified store to a database using the Store.each structure (this is example code, more is going on in the mapping of the store to the DirectMethod input):



var resultsToSend = [];
App.VarietiesStore.each(record, function (item) {
resultsToSend.add({
VarietyID: +item.VarietyID,
TypeID: +item.TypeID,
RightType: Boolean(+item.TypeID == RightTypeID),
VarietyName: item.VarietyName
});
});
App.direct.MyDirectMethod(resultsToSend);


If there's a filter on the store, will filtered records be skipped by the *Store.each* loop?

Daniil
May 30, 2014, 5:35 AM
Yes, it will be skipped.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store-method-each

But you can operate with a Store's snapshot. It is a MixedCollection of all the records.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store-property-snapshot

ptrourke
May 30, 2014, 4:09 PM
Yes, it will be skipped.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store-method-each

But you can operate with a Store's snapshot. It is a MixedCollection of all the records.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store-property-snapshot

Daniil,

Thanks a lot for this! Ok, my code now looks something like this:



var resultsToSend = [],
resultsRecords = App.VarietiesStore.snapshot || App.VarietiesStore.data;
resultsRecords.each(record, function (item) {
resultsToSend.add({
VarietyID: +item.VarietyID,
TypeID: +item.TypeID,
RightType: Boolean(+item.TypeID == RightTypeID),
VarietyName: item.VarietyName
});
});
App.direct.MyDirectMethod(resultsToSend);


This works as I wanted it to work. I assume that the reason for the OR in the assignment is because .snapshot is void unless a filter has been applied, in which case it simply passes "data"? If that's correct, please feel free to closed.

Patrick

Daniil
May 30, 2014, 5:17 PM
You are right. In some cases there might be used a PagingStore. So, I would recommend the following. It will work for regular Stores (non-PagingStore) as well.


var store = App.VarietiesStore,
resultsRecords = store.snapshot || store.allData || store.data;