Intermediate

Фильтрация и сортировка данных

Иногда бывает необходимо просмотреть определённые элемента, а не весь набор данных. Для этих случаем существует метод filter.

Представим, что у нас есть список фильмов и мы хотим отфильтровать его по названию и году выпуска с возможностью вводить текстовый критерий в поле. В то же время фильтрация должна начинаться с первой буквы, а добавление новых элементов будет вызывать повторную фильтрацию.

Существует два способа фильтрации данных: фильтрация и сортировка данных встроенными инструментами и пользовательская фильтрация, при которой создаётся своя функция с методом filter().

Фильтрация и сортировка содержимого

Доступны только для datatable и treetable. Параметры сортировки и фильтрации указываются отдельно для каждого столбца.

Чтобы разрешить фильтрацию, используйте параметр content и укажите необходимый тип фильтра в качестве значения, например:

  • textFilter - фильтрует данные, когда пользователь вводит текст в поле;
  • selectFilter - позволяет выбирать из списка заранее заданных опций.

Полный список типов фильтра доступен по этой ссылке.

Данные сортируются с помощью параметра sort, который принимает одно из следующих значений: "int", "date", "string", "string_strict (для фильтрации с учётом регистра), "text", "server", "raw". Вы также можете задать свой тип сортировки. Читайте подробнее о доступных типах сортировки.

При клике на хедер столбца происходит сортировка в восходящем/нисходящем направлении.

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)

Если вам необходимо добавить какой-либо критерий во встроенный фильтр, используйте свойство compare.

У Datatable своя специфика фильтрации и сортировки, поэтому соответствующую информацию вы можете найти в следующих статьях:

TreeTable разделяет возможности DataTable и Tree, поэтому у этого компонента похожие шаблоны сортировки и фильтрации. Также, компонент заимствует свойство filterMode API дерева (описано дальше).

Пользовательская фильтрация

Остальные компоненты фильтруется с помощью функции filter, которая принимает значение для фильтра из поля и показывает те элементы, которые соответствуют этому значению.

Фильтрация возможна двумя способами:

С использованием темплейтов данных

webix.ui({
    rows:[ // прежде всего определите инпут и объект данных
        {
            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(); // получаем данные из инпута
    $$("list").filter("#title#", value);
}); // названия отфильтрованы

Такой же шаблон у компонентов с похожими темплейтами данных (dataview и Tree). В примере выше в темплейты каждого фильма включены значения rank и title. Читайте более подробную информацию о темплейтах.

С использованием функции

Метод filter() принимает функцию в качестве аргумента. Он возвращает значения данных, которые соответствуют данным поля:

$$("list_input").attachEvent("onTimedKeyPress",function(){ 
    var value = this.getValue().toLowerCase(); // получаем значение поля
    $$("list").filter(function(obj){  // фильтруем все фильмы по названию
        return obj.title.toLowerCase().indexOf(value)==0; 
    });
});

Related sample:  List: Filtering

Особенности фильтрации в Tree

Фильтрация в Tree

// воле ввода html 
<input type='text' placeholder="type filter criteria here" 
    style='width:250px; margin-left:20px' onkeypress="filter_tree()"/>
 
// функция для фильтрации
function filter_tree(){
    tree.filter("#value#", this.value);
};
 
// объект tree 
webix.ui({
    view:"tree",
    select:true,                
    data: smalltreedata
});

Функция выполняет фильтрацию в соответствии со значениями #value#, а также учитывает все уровни дерева и показывает результаты с дочерними элементами отфильтрованных веток, даже если значения этих элементов не соответствуют критерию фильтрации.

Вы можете изменить шаблон фильтрации с помощью свойства filterMode.

{
    view:"tree",
    filterMode:{
        showSubItems:false,
        openParents:false,
        level:3
    }   
}
  • showSubItems (boolean) - определяет, показывать ли дочерние элементы отфильтрованных веток.
  • openParents (boolean) - определяет, развёртывать ли ветки, чтобы показать найденные элементы.
  • level (number) - задаёт глубину фильтрации узлов дерева (начинается с '1'). Значение '0' фильрует все узлы.

Related sample:  Filtering

Related sample:  Filtering in TreeTable

Фильтрация по нескольким свойствам

У компонентов данных может быть более одного темлейта на каждую запись. Например, запись datatable состоит из нескольких ячеек разных столбцов. Записи dataview и list содержат несколько элементов, которые отражаются в их темплейте.

Вы можете фильтровать компонент, ссылаясь на любой из его темплейтов и использовать при этом одно поле ввода.

webix.ui({
    rows:[
        { 
          view:"list", id:"dlist", 
          template: "#rank#. #title#. #year#<br/>#category#",
          // конфиг списка
        },
        {
          view:"text", 
          id:"filter-list" // поле для фильтрации     
        }
    ]
});
 
 
$$("filter-list").attachEvent("onTimedKeypress", function(){
    var text = this.getValue().toString().toLowerCase();
    // после ввода текста фильтруем соответствующую сетку
    $$("dlist").filter(function(obj){
        // фильтрация по нескольким свойствам
        var filter = [obj.title, obj.category, obj.year].join("|"); 
        filter = filter.toString().toLowerCase();
        return (filter.indexOf(text) != -1);
    });
});

Related sample:  Multiple Filter

Сортировка

Вы можете отсортировать компонент данных по любому из его полей и в любом направлении, используя один из следующих режимов:

  • "int" - сравнивает числовые значения;
  • "date" - сравнивает даты;
  • "string" - сравнивает строки без учёта регистра;
  • "string_strict" - сравнивает строки с учётом регистра;
  • "text" - сравнивает видимый текст (включая темплейты);
  • "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" - создаёт запрос на сервер за данными;
  • "raw" - базовая сортировка с простым сравнением (a>b и наоборот);
  • вы также можете определить пользовательский тип сортировки.

Варианты сортировки компонентов данных:

  • Динамическая сортировка с помощью метода sort():
    // описываем объект с параметрами
webix.ui({
    view: "list",
    template:"#title# - #year#"
});
 
$$("list").sort({ 
    by:"#title#",
    dir:"asc",
    as:"string"
});


    // или используем метод с несколькими параметрами
$$("chart").sort("#year#","desc");
$$("tree").sort("#value#", "asc");

Более подробную информацию о методе sort читайте в справочнике API.

  • Вы можете определить правило изначальной сортировки в компоненте данных с помощью scheme:
webix.ui({
    view: "list",
    template:"#title# - #year#",
    scheme:{
        $sort:{
            by:"#title#",
            dir:"asc",
            as:"string"
       }
    } 
});

Как добавить пользовательский тип сортировки

Вы можете определить свой тип сортировки через свойство sorting.as у объекта webix.DataStore.prototype. Вам необходимо указать функцию, которая будет описывать тип сортировки следующим образом. 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 }

Давайте определим новый тип "bylength" для сортировки данных по длине текста:

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

Чтобы применить новый тип сортировки, вам необходимо передать имя этого типа в параметр as:

  • Динамичеси, с помощью метода sort():
    // указываем объект с параметрами
webix.ui({
    view: "list",
    template:"#title# - #year#"
});
 
$$("list").sort({ 
    by:"#title#",
    dir:"asc",
    as:"bylength"
});


    // передаём несколько параметров в метод
$$("list").sort("#title#", "asc", "bylength");
  • Или же укажите изначальную сортировку с помощью ключа $sort у объекта scheme:
webix.ui({
    view: "list",
    template:"#title# - #year#",
    scheme:{
        $sort:{
            by:"#title#",
            dir:"asc",
            as:"bylength"
       }
    }
});
Наверх