Start Building Professional
Web Apps Today


 
Categories Question details Back To List
Question  posted by Charly on Oct 23, 2008 08:01
open dhtmlx forum
Treegrid complex filter

Hi all,

I have a treegrid which it expand shows the months of the year (January, February, etc), I would have a filter in the month column to show only the months checked in the filter. I've got the div that "paint" the 12 months in the filter, but I dont know how to continue, there is some code (API) to perform this action or I have to use built-in filters?

I followed the example available from the URL http://www.dhtmlx.com/docs/products/dhtmlxGrid/samples/header_footer/grid_complexheader_content.html to create a tree grid with client-side column filtering. The filtering performs satisfactory when there are a few records, however when I increase the record count to I am seeing a significant decrease in performance on the client-side. Is there anything I can do to increase performance on the client-side besides filtering the data server-side? I want to avoid re-fetching the data from the server.

Thanks in advance,

Charly.
Answer posted by Support on Oct 23, 2008 08:12
Starting from dhtmlxgrid 1.5 grid has built-in filtering funcitonality ( starting 1.6 it available in treegrid as well )
Please check 
    http://dhtmlx.com/docs/products/dhtmlxTreeGrid/samples/grid_operations/treegrid_filtering.html?un=1224775998000
    http://dhtmlx.com/docs/products/dhtmlxGrid/samples/filtering/?un=1224776013000
    http://dhtmlx.com/docs/products/dhtmlxGrid/doc/articles/Data_filtering_search.html#grid_fsing
    http://dhtmlx.com/docs/products/dhtmlxGrid/doc/articles/Filtering_in_TreeGrid.html#grid_tg_filtering

on medium and big datasets built in filters will work 10 times faster than solution based on grid_complexheader_content.html example ( especially if smartRendering mode enabled ) 
Answer posted by Charly on Oct 23, 2008 09:10
Thanks for your quick response, but had already read these samples and don't solve much.
I will try to explain it better with my code.
I'v hardcoded dhtmlxgreed_hmenu to show the month in a context menu:

dhtmlXGridObject.prototype._createHContext=function()
{
    if (this._hContext) return this._hContext;
    var d = document.createElement("DIV");
    d.oncontextmenu = function(e){ (e||event).cancelBubble=true; return false; };
    d.onclick=function(e){
        (e||event).cancelBubble=true;
        return true;
        }
    d.className="dhx_header_cmenu";
    d.style.width=d.style.height="5px";
    d.style.display="none";
    var a=[];
    var i=0;
    if (this._fake)
        i=this._fake._cCount;   
   
   
 
    meses = new Array ("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre");

 
   
    for (var i; i<meses.length; i++){
        a.push("<div class='dhx_header_cmenu_item'><input type='checkbox' column='"+addZero(true_ind)+"' />"+meses[i]+"</div>");
     }   
   
    d.innerHTML=a.join("");

Now, I want to filter the treegrid with the months checked, I do it with this code (in the same function):
    var totalRows = [];
    var checkedRows = [];
    var checkedRowsFormatted = [];
    //Funcion para ocultar las rows no filtradas
    var f=function(){
        var c=this.getAttribute("column");
        mygrid.expandAll();
        //array de las rows total
        totalRows = mygrid.getAllItemIds().toArray();
        //array de las rows filtradas
        if (this.checked) checkedRows.push(c)
        else checkedRows.pop(c);

           
        var checkedRowsFormatted = [];
        var nocheckedRowsFormatted = [];
        for (i=0; i<getClientId(totalRows).length; i++){
            checkedRowsFormatted.push(getClientId(totalRows)[i]);
            for (j=0; j<checkedRows.length; j++){
                checkedRowsFormatted.push(getClientId(totalRows)[i]+"-"+checkedRows[j]);
            }
        }
       
        nocheckedRowsFormatted = checkedRowsFormatted.filter(totalRows);   
        for (l=0; l<checkedRowsFormatted.length; l++) mygrid.setRowHidden(checkedRowsFormatted[l],false);
        for (l=0; l<nocheckedRowsFormatted.length; l++) mygrid.setRowHidden(nocheckedRowsFormatted[l],true);       
    }
    for (var i=0; i<d.childNodes.length; i++)
        d.childNodes[i].firstChild.onclick=f;

As you can see, they are functions built by me, but it is very slow, there is some code (API) to perform this action faster?

Thank you again

Answer posted by Support on Oct 24, 2008 01:52
I'm not sure that understood used logic correctly, bu I think you can increase performance by replacing the 

  var checkedRowsFormatted = [];
  var nocheckedRowsFormatted = [];
  for (i=0; i<getClientId(totalRows).length; i++){
  checkedRowsFormatted.push(getClientId(totalRows)[i]);
  for (j=0; j<checkedRows.length; j++){
  checkedRowsFormatted.push(getClientId(totalRows)[i]+"-"+checkedRows[j]);
  }
  }
   
  nocheckedRowsFormatted = checkedRowsFormatted.filter(totalRows);  
  for (l=0; l<checkedRowsFormatted.length; l++) mygrid.setRowHidden(checkedRowsFormatted[l],false);
  for (l=0; l<nocheckedRowsFormatted.length; l++) mygrid.setRowHidden(nocheckedRowsFormatted[l],true);  

with 
var checkedRowsFormatted = {};
for (i=0; i<getClientId(totalRows).length; i++){
  checkedRowsFormatted[getClientId(totalRows)[i]]=true;
  for (j=0; j<checkedRows.length; j++){
    checkedRowsFormatted[getClientId(totalRows)[i]+"-"+checkedRows[j]]=true;
  }

grid.setFiltrationLevel(-2);
grid.filterBy(0,function(value,id){
     if (checkedRowsFormatted[id]) return true;
     return false;
});

Probably the part which collect row IDs may be simplified as well, but I not fully understood its logic.
Answer posted by Charly on Oct 28, 2008 04:18
Sorry, you have reason, I should be post the hole js. Anyway, the answer has been very useful, thank you very much.
Now, I have another problem with your function:
I want filter by month, when I checked one month the filter work perfectly, but if I checked another month, only filter by this month  (i.e. I filter by January and only shows January, If I checked February too, only show February, instead January and February).
How could be resolved this??
Thanks very muach again.

Answer posted by Support on Oct 28, 2008 05:45

You can use any logic inside fitlering function, so you can place code here which checks not the simple rule, but group of rules. 

grid.filterBy(0,function(value,id){
  if (any_kind_of_logic()) return true;
  return false;
});

also it possible to combine few filterBy calls 
grid.filterBy(0,function(value,id){
  if (any_kind_of_logic()) return true;
  return false;
});
grid.filterBy(0,function(value,id){  
  if (any_other_kind_of_logic()) return true;
  return false;
},true); //true means that filtering will be executed against results of previous filterBy command