yaksey yaksey - 3 months ago 13
jQuery Question

Create a dropdown with several options which contain custom filters

I already searched the web but I haven't found a solution to my question yet. Maybe I searched for the wrong terms, so I'm sorry if the solution to my problem might be very simple.

Example-table:
Example-table

So, what I want to do is the following:


  • provide a dropdown with several options

  • every option provides a custom filter (e.g. 'option1' shows all
    records that are available, 'option2' shows all records that are
    available and have label F, 'option3' shows all records that are
    available and have label E, …)

  • apply the filter immediately 'live'



So, how can I achieve this?

Thanks in advance.

Answer

I created ready to use component ( pure js no Jquery needed ) with filtering of table rows by column values. Component use data attributes, it can be customised for filtering any column.

var FilterSelect=function(selectSelector,tableSelector){

   this.$select=document.querySelector(selectSelector);//our select
   this.$table=document.querySelector(tableSelector); //our table
   
   this.filter=null; //filter value
   this.columnNum=null; //column num to check value
  
   this._bind();
  
   
   //run setting and filtering in beginning ( option can be set )
   this._setAndFilter();

};



// method sets parameters from chosen option
FilterSelect.prototype._set=function(){

      var option=this.$select.options[this.$select.selectedIndex];//get current option
    this.filter=typeof option.dataset.filter!='undefined'?option.dataset.filter:null;
    
    this.columnNum=typeof option.dataset.columnNum!='undefined'?option.dataset.columnNum:null;
  
};

//method filters table
FilterSelect.prototype._filterTable=function(){

  var trs=this.$table.querySelectorAll("tr");
  
  for (var i=0; i<trs.length; i++){
    
    
      var tr=trs[i];
    
      if (this.columnNum==null){
      
        //no filters
        tr.style.display="block"
        continue;
      }
    
      
      var td=tr.querySelectorAll("td")[parseInt(this.columnNum)];//get td 
    
      var value=td.innerText;//get td inner text to compar
    
      if (value!=this.filter)
      tr.style.display="none"; //filter does not match - hide
      else
        tr.style.display="block";//display block - filter match
  }
  
};

//filtering table and setting options
FilterSelect.prototype._setAndFilter=function(){

   this._set();//set current filter and column
   this._filterTable();//do table filtering
  
};

//bind select change event
FilterSelect.prototype._bind=function(){

  this.$select.addEventListener("change",function(){
  

    this._setAndFilter();
    
    
  }.bind(this));
  
  

};

//usage
var filterSelect=new FilterSelect('#select','#table');
<select id="select">
  <option>No filter</option>
  <option data-column-num="3" data-filter="E">Filter Label E</option>
  <option data-column-num="2" data-filter="Yes">Filter Available</option>
  <option data-column-num="3" data-filter="F">Filter Label F</option>
  <option data-column-num="2" data-filter="No">Filter Not Available</option>
</select>  

<table id="table">
  <tr>
    <td>1</td><td>One</td> <td>Yes</td><td>E</td>
  </tr>  
  <tr>
    <td>2</td><td>Two</td> <td>Yes</td><td>F</td>
  </tr>  
  <tr>
  <td>3</td><td>Three</td> <td>No</td><td>E</td>
  </tr>
</table>

Information about data attributes:

data-column-num - number of column to check filter value ( starts from 0 )

data-filter - value of filter to check in text inside chosen by columnNum column

Above component enables filtering by single column value. Here is component with possibility to filter for many columns - https://jsfiddle.net/maciejsikora/0kbubfts/