Intermediate

Data Filtering and Sorting

Sometimes you need to view definite items rather then the whole dataset. Here you play around with the filter method.

The task is as follows: you have a film set and want to filter it by title and year, with the possibility to enter the text criterion into the input area. At the same time filtration should start with the first letter, while newly added letters would trigger data re-filtering.

Two major possibilities of data filtering are content filtering and sorting using built-in means and custom filtering where you should write your own function with the filter() method.

Content Filtering and Sorting

Available for datatable and treetable only. Filtering and sorting parameters are set for each column separately.

To enable filtering, use the content parameter and set the necessary filter type as its value, e.g.:

  • textFilter - filters data as you type values into the input;
  • selectFilter - allows selecting from the predefined list.

The full list of filter types is given in the corresponding section of the article dedicated to the Datable filtering.

Data are sorted thanks to the sort parameter, that may take one of the following values: "int", "date", "string", "string_strict (for case-sensitive filtering), "text", "server", "raw". It is also possible to define a custom sorting type. Read the details on available sorting types.

You click headers of the dedicated columns to enable both ascending and descending sorting patterns.

webix.ui({
    view:"datatable",
    id:"films",
    columns:[
        { id:"title",   header:["Title", {content:"textFilter"}], sort:"string"},
        { id:"year",    header:["Year",  {content:"selectFilter" ], sort:"int"},
        { id:"votes",   header:"Votes",  sort:"int"}
    ]
});

Related sample:  Filtering by Several Criteria (AND Logic)

If you want to include an additional criterion to the built-in filter, use the compare property to define the additional filtering

Datatable is a peculiar component and has a number of API peculiarities. That's why, refer to the corresponding articles:

TreeTable shares features of both DataTable and Tree, that's why it has similar familiar sorting and filtering patterns. In addition, it borrows the filterMode property from the tree API (described further).

Custom Filtering

Other components should be filtered with the dedicated filter function, that takes filtering value from the input area and shows only those data items that comply with it.

Filtering can be implemented in two ways:

Using data template

webix.ui({
    rows:[ //firstly define input area and data object
        {
            view:"toolbar",
            elements:[
               { view:"text", id:"list_input" }
            ]
        },
        {
            view:"list",
            id:"list",
            template:"#rank#. #title#",
            select:true,
            data:big_film_set
        }
    ]
});
 
$$("list_input").attachEvent("onTimedKeyPress",function(){ 
    var value = this.getValue().toLowerCase(); // input data are derived
    $$("list").filter("#title#", value);
}); // the titles are filtered

The same pattern is observed with components featuring similar data templates (dataview and Tree).
In the list above the template includes rank and title values for each film. More about data templates.

Using a function

The filter() method can have a function as an argument. It returns data values that comply with the input text:

$$("list_input").attachEvent("onTimedKeyPress",function(){ 
    var value = this.getValue().toLowerCase(); // here it gets user input value
    $$("list").filter(function(obj){  // here it filters all titles from the dataset 
        return obj.title.toLowerCase().indexOf(value)==0; 
    });
});

Related sample:  List: Filtering

Peculiarities of Tree Filtering

Tree Filtering

//html input field
<input type='text' placeholder="type filter criteria here" 
    style='width:250px; margin-left:20px' onkeypress="filter_tree()">
 
//filtering function
function filter_tree(){
    tree.filter("#value#", this.value);
};
 
// tree object
webix.ui({
    view:"tree",
    select:true,                
    data: smalltreedata
});

The function performs filtering according to the #value# values. It takes into account all the tree levels and displays results with the children of the filtered branches, even if the children's values don't comply with the filtering criterion.

At the same time, you can change the filtering pattern with the help of the tree filterMode property with an object value.

{
    view:"tree",
    filterMode:{
        showSubItems:false,
        openParents:false,
        level:3
    }   
}
  • showSubItems (boolean) - defines whether the component should display children of the filtered items.
  • openParents (boolean) - defines whether the component should expand branches to show the found items.
  • level (number) - sets the hierarchy to filter tree nodes (one-based numbering). The '0' value says to filter all nodes.

Related sample:  Filtering

Related sample:  Filtering in TreeTable

Filtering by Multiple Properties

It's common knowledge that data management components can feature more than one data template item per record. For instance, a datatable record consists of several cells in different columns, dataview and list records contain several items, which is reflected in their data template.

You can filter data in the component referring to either of its template values using one and the same input field.

webix.ui({
    rows:[
        { 
          view:"list", id:"dlist", 
          template: "#rank#. #title#. #year#<br/>#category#",
          // list config
        },
        {
          view:"text", 
          id:"filter-list" // input for filtering        
        }
    ]
});
 
 
$$("filter-list").attachEvent("onTimedKeypress", function(){
    var text = this.getValue().toString().toLowerCase();
    //after text entering - filter related grid
    $$("dlist").filter(function(obj){
        //filter by multiple properties
        var filter = [obj.title, obj.category, obj.year].join("|"); 
        filter = filter.toString().toLowerCase();
        return (filter.indexOf(text) != -1);
    });
});

Related sample:  Multiple Filter

Sorting

You can sort component data by any field in any direction using one of the following ways to match your data:

  • "int" - compares numeric values;
  • "date" - compares dates;
  • "string" - compares string values;
  • "string_strict" - case-sensitive "string";
  • "text" - compares visible item text (including template), datatable only;
  • "string_locale" - compares string values based on the locale;
  • "string_locale_strict" - case-sensitive "string_locale";
  • "text_locale" - compares visible item text based on the locale (including template), datatable only;
  • "server" - issues a server side request for a sorted dataset;
  • "raw" - basic sorter with simple comparison (a>b and vice versa);
  • or, you can set a custom sorting type.

Two ways of sorting are available for data components:

  • You can dynamically sort the component using the sort() method:
    // setting the object with parameters
webix.ui({
    view: "list",
    template:"#title# - #year#"
});
 
$$("list").sort({ 
    by:"#title#",
    dir:"asc",
    as:"string"
});


    // or using several parameters in the method
$$("chart").sort("#year#","desc");
$$("tree").sort("#value#", "asc");

Read a more detailed description of the sort method in the dedicated chapter of API Reference.

  • Or you can specify the initial sorting rule in the component data scheme:
webix.ui({
    view: "list",
    template:"#title# - #year#",
    scheme:{
        $sort:{
            by:"#title#",
            dir:"asc",
            as:"string"
       }
    } 
});

Adding Custom Sorting Type

You can define your own sorting type via the sorting.as property of the webix.DataStore.prototype object. You need to specify a function, that will describe a new type of sorting as follows. The parameters of this function are the objects themselves and the name of the specified field:

webix.DataStore.prototype.sorting.as.sort_type = 
function(a,b,prop){ return a[prop] > b[prop] ? 1 : -1 }

For example, let's set a new type "bylength" to sort data by the text length:

webix.DataStore.prototype.sorting.as.bylength = 
function(a,b,prop){ return a[prop].length > b[prop].length ? 1 : -1 }

To apply the newly created sorting type, you just need to set the type name as a value of the as parameter:

  • Dynamically, while using the sort() method:
    // setting the object with parameters
webix.ui({
    view: "list",
    template:"#title# - #year#"
});
 
$$("list").sort({ 
    by:"#title#",
    dir:"asc",
    as:"bylength"
});


    // using several parameters in the method
$$("list").sort("#title#", "asc", "bylength");
  • Or, specifying the initial sorting with the help of the $sort key of the data scheme:
webix.ui({
    view: "list",
    template:"#title# - #year#",
    scheme:{
        $sort:{
            by:"#title#",
            dir:"asc",
            as:"bylength"
       }
    }
});
Back to top