PDA

View Full Version : store with distinct option



umit
3 Sep 2010, 12:09 AM
Hallo!
I wrote a function, that you can use for distinct Element filtering.
The purpose is if you get resultsets with joins and have more entries, and you want to show the entries in more than one combobox you will get double entries, if you use the same store.
You may want to filter this "double entries".
Of corse you could make 2 requests to the server, but why bother the server with requests, if the client can do it(you may have performace issues on the server).

If your store looks like this:
Name
Anton
Toni
Toni

you will get this:
Name
Anton
Toni

Here the code:
function getDistinctStore(store,distinctKey){//info: store is a json store
var newstore=new Ext.data.ArrayStore();
var record;
store.data.each(function(rec){
if(record==null){
newstore.add(rec);
record=rec;
}
else
if(record.get(distinctKey)!=rec.get(distinctKey)){
newstore.add(rec);
record=rec;
}
});
return newstore;
}
It would be nice if Ext would have this as standard.
greets umit

dhilchrist
5 Jul 2012, 3:46 PM
Distinct rows from an Ext.data.XmlStore?? (Extjs 3.3.0 lib)

how can I retrieve distinct rows from an XmlStore,

Data Set
Job operation RunId Status
a launch 123 Pass
a lunch 123 Pass
a hold 124 Wait
a hold 124 wait

Result set,
I wanted to display only 2 rows based on RunId

a launch 123 Pass
a hold 124 wait

umit
5 Jul 2012, 11:37 PM
Hi,
use the filter function from the store,
i wrote this, when i was new to extjs and the implementation of mine has some kinda problems e.g. the store has to be sorted.


For your solution the filter function should do it, based on the criteria to filter(if you have the runid as seperate field in the store).
so something like:



var addedRunIds=[];
myXmlStore.filterBy(function(rec){
if(addedRundIds.indexOf(rec.get("runid")==-1){//does not contain it

addedRunIds.add(rec.get("runid"));
return true;

}
return false;
}


You can also make a new store and add to to the store instead of filtering it.
greets

dhilchrist
9 Jul 2012, 1:46 PM
thanks umit,
i tried like this but getting errors..expected string, identifier, number!!
store.load({
callback : function() {
var addedRunIds=new Array();
for (var i = 0; i < store.getCount() - 1; i++) {
record = store.getAt(i);
store.filterBy({
function(record){
if(addedRunIds.indexOf(record.get("TESJobRunID")==1){//does not contain it
addedRunIds.add(record.get("TESJobRunID"));
return true;
}
return false;
}
});
}
}
});

umit
9 Jul 2012, 11:20 PM
Hi,
You have 2 variables with the name record, it is difficult to tell which one is the one you use, you should take a different name like record2, otherwise you have to work with this.record, but that's fuzzy.

And when you use indexOf it return -1 when it cant find the record, not 1, sry i wrote 1 ...

try this


store.load({
callback : function() {
var addedRunIds=[];
store.filterBy(function(rec){
if(addedRunIds.indexOf(record.get("TESJobRunID")==-1){//does not contain it
//so add it and show it
addedRunIds.push(rec.get("TESJobRunID"));
return true;
}
return false;
});
}
});


What is the content of TESJobRunID ?

Is it:

a launch 123 Pass
a lunch 123 Pass
a hold 124 Wait
a hold 124 wait

or
123
123
124
124

if it is the 1. you have to split it to get the id.

dhilchrist
10 Jul 2012, 8:14 AM
the contents of TESJobRunId are

123
123
124
124

dhilchrist
10 Jul 2012, 8:54 AM
do I need to declare the function variable record/rec, id of function(record, id)?
if not I can use this rec.get("TESJobRunID") in the function right ?

dhilchrist
10 Jul 2012, 10:50 AM
if I use your code inside the store.load then it is filtering only the first page of the grid and also i tried without store.load but it is not filtering.
----------------------------
var store = new Ext.data.XmlStore({
autoDestroy: true,
storeId: 'myStore',
proxy: proxy,
root : "standard",
record: 'standardData',
idPath: 'rowId',
totalProperty: '@totalCount',
autoLoad: false,
paramNames: {
start: 'startRow',
limit: 'recordSize'
},
fields: fieldObjectList
});




store.load({
callback : function() {
var addedRunIds=[];
store.filterBy(function(rec){
if(addedRunIds.indexOf(rec.get("TESJobRunID"))==-1){//does not contain it
//so add it and show it
addedRunIds.push(rec.get("TESJobRunID"));
return true;
}
return false;
});
}
});
/* create the grid */
var grid = new Ext.grid.GridPanel({
store : store,
columns : displayList,
renderTo : '#divName#',
width : "100%",
autoHeight : true,
plugins: [filterRow],
stripeRows: true,
layout : 'fit',
viewConfig : {
forceFit : true
},
bbar : [new Ext.PagingToolbar({
store : store,
displayInfo : true,
pageSize : 10,
params:{
startRow: 0,
recordSize: 10
}
})]
});
-----------------------------

umit
10 Jul 2012, 11:17 AM
Hi,

you can use it by record.get("xyz") you don't need more variables.

What do you mean by: it's filtering the first page? does it have many pages? do you load only a part of the whole runids by the server?

You have to load and filter afterwards. So everytime you load, you have to filter. You can use an event, so that it autofilters when you load. The syntax would be:


store.on("load",function(){
//your filter function
});


But be careful with the filter, whenever you iterate it, you will only get the elements, that are shown. So when you use the store for something else too, use another store with the same structure.

dhilchrist
10 Jul 2012, 11:51 AM
thanks umit, it works!!!
yes i have around 1000 records and i am using pagination too, the issue i m facing now is records numbers shows in the pagination, it is showing the actual records# from store not the filtered one.

dhilchrist
10 Jul 2012, 3:07 PM
how can I store this store.filterby in store.on(load) to another store, causing problem with Plugin:[filterRow]

umit
11 Jul 2012, 12:05 PM
sorry i dont know what you exactly mean.
you can add the records from the store to another one with newstore.add(store.getRange(0,store.getCount()-1));

But I dont know what you exactly need and want to do

dhilchrist
11 Jul 2012, 12:23 PM
I have some filter plugin in the header of the Grid, so when try filter rows from plugin in the head, it is getting records from the actual store.
so i need to store this store.filterby values to another store display that in the grid.
I tried like thie following but it is stores only the first page to the new store.
-----------
var store = new Ext.data.XmlStore({
autoDestroy: true,
storeId: 'myStore',
proxy: proxy,
root : "standard",
record: 'standardData',
idPath: 'rowId',
totalProperty: '@totalCount',
pageSize: 20,
autoLoad:{params:{start:0, limit:20}},
paramNames: {
start: 'startRow',
limit: 'recordSize'
},
fields: fieldObjectList
});


var store2 = new Ext.data.XmlStore({
recordType: store.recordType
});
/* create the grid */
var grid = new Ext.grid.GridPanel({
store : store2,
columns : displayList,
renderTo : '#divName#',
width : "100%",
height : 300,
//plugins: [filterRow],
stripeRows: true,
layout : 'fit',
viewConfig : {
forceFit : true
},
bbar: [new Ext.PagingToolbar({
pageSize: 20,
store: store2,
displayInfo: true,
displayMsg: 'Displaying topics {0} - {1} of {2}',
emptyMsg: "No topics to display",
params:{
startRow: 0,
recordSize: 20
}
})]
});




store.on("load",function(){
var addedRunIds=[]; var records = [];
store.filterBy(function(rec){
if(addedRunIds.indexOf(rec.get("TESJobRunID"))==-1){//does not contain it
//so add it and show it
addedRunIds.push(rec.get("TESJobRunID"));
records.push(rec.copy());
return true;
}
return false;
});
store2.add(records);


});
------------------