Biblioteca Webix JavaScript através dos olhos de um iniciante. Parte 5. Trabalhe com dados no lado do usuário



Sou desenvolvedor iniciante em front-end. Agora estou estudando e treinando em uma empresa de TI em Minsk. Aprender o básico do web-ui é um exemplo da biblioteca JS Webix. Quero compartilhar minha modesta experiência e salvá-la como um pequeno tutorial nesta interessante biblioteca de interface do usuário.

QUINTA TAREFA


Em um artigo anterior, Trabalhando com dados , com base nas funções CRUD, escrevi sobre tarefas padrão para gerenciar dados de aplicativos. Neste ponto, tentarei tornar o aplicativo mais amigável e perceber a capacidade de filtrar, classificar e agrupar dados. No artigo, considerarei as seguintes tarefas:


Na documentação, você pode encontrar os widgets Lista , Árvore , Tabela usados ​​no artigo .

As fontes estão no link .

O aplicativo finalizado pode ser encontrado aqui .

Filtrando e Classificando Dados da Tabela


Vamos começar com as tabelas - eu costumava usá-las para trabalhar com muitos dados. As tabelas na biblioteca Webix possuem vários filtros internos configurados diretamente no cabeçalho dos widgets Table e TreeTable. No widget Tabela , eu uso duas opções: um filtro de texto simples ( textFilter ) e um filtro com um conjunto de opções na lista suspensa ( selectFilter ). A tabela permite adicionar um filtro para cada coluna. Farei isso por dois: título e ano. Vou definir o cabeçalho neles, em vez de uma string com uma matriz - para caber no cabeçalho e no filtro. O segundo elemento da matriz é um objeto com uma propriedade content e um nome de filtro.
O código para o widget Tabela está no arquivo table.js e renderizado na guia "Painel".

Quando os caracteres são inseridos nos "textFilter"dados, eles serão filtrados por correspondência por substring. Se você selecionar a opção "selectFilter"- pelo valor selecionado.

columns:[
    { id:"rank", header:"", width:50, css:"rank"},
    { id:"title", header:["Film title", { content:"textFilter"}], fillspace:true },
    { id:"year",  header:["Released", {content:"selectFilter" }], width:100 },
    { id:"votes", header:"Votes", width:100 },
    { id:"rating", header:"Rating", width:100 },
    { header:"", template:"<span class='webix_icon wxi-close'></span>", width:35}
]

Resultado da filtragem por substring “estrela”:



resultado dos elementos de filtragem pelo valor selecionado “1991”:



Classificação. Como nos filtros, a classificação é tão fácil de disponibilizar para o usuário. Para fazer isso, basta suplementar a configuração da coluna com a propriedade de classificação . Existem vários tipos de classificação prontos: por valores numéricos, por data e por sequência. Para o ano, votos e colunas de classificação, definirei a classificação: "int" para classificar por valores numéricos. Para a coluna do título, o valor será "string".

    columns:[
        { id:"rank", header:"", width:50, css:"rank"},
        { id:"title", header:["Film title", { content:"textFilter"}], fillspace:true, 
         sort:"string"},
        { id:"year",  header:["Released", {content:"selectFilter" }], width:100, sort:"int"},
        { id:"votes", header:"Votes", width:100, sort:"int"},
        { id:"rating", header:"Rating", width:100, sort:"int"},
        { header:"", template:"<span class='webix_icon wxi-close'></span>", width:35}
    ]

Ao clicar na coluna do cabeçalho, os dados serão classificados de acordo com seu tipo. Resultado da classificação:



Classificação e filtragem de API


As soluções prontas para filtrar e classificar itens têm apenas tabelas. Mas, em geral, todos os widgets suportam esses recursos por meio dos métodos de API apropriados - filtrar e classificar. Demonstrarei a filtragem e a classificação usando a API com o widget Lista .

O código para o widget Lista está no arquivo users_module.js e renderizado na guia "Usuários".

Filtração. Na guia Usuários , após o botão "Adicionar nova pessoa", instalarei o widget Texto , que eu uso como filtro para os nomes da lista.

cols:[
    { 
        view:"button", id:"btn_add_person", 
        value:"Add new person", width:150, css:"webix_primary", 
        click:addPerson
    },
    { 
        view:"text", id:"list_input" 
    },
]

Agora vou abrir o arquivo script.js e adicionar a lógica responsável pela filtragem dos elementos.

$$("list_input").attachEvent("onTimedKeyPress",function(){
    var value = this.getValue().toLowerCase();
    $$("user_list").filter(function(obj){
        return obj.name.toLowerCase().indexOf(value) !== -1;
    })
});

Os elementos são filtrados de acordo com este princípio:
  • usando o método attachEvent, adiciono um manipulador ao evento onTimedKeyPress ;
  • o evento onTimedKeyPress é acionado inserindo caracteres no campo de texto, mas com um pequeno atraso, para não ativar o filtro a cada pressionamento de tecla;
  • então, obtenho o texto inserido e uso o método de filtro para começar a filtrar - procure correspondências no widget Lista.

Filtrando resultado via API:



Classificar. Os elementos do widget de lista serão classificados clicando nos botões “Sort asc”e “Sort desc”.

Para criar botões na guia Usuários , após a caixa de texto, adicionarei dois widgets de Botão com um manipulador de eventos click .

cols:[
    { 
        view:"button", id:"btn_add_person", 
        value:"Add new person", width:150, css:"webix_primary", 
        click:addPerson
    },
    { 
        view:"text", id:"list_input" 
    },
    { view:"button", id:"btn_asc", width:150, value:"Sort asc", css:"webix_primary", 
        click:()=>{
            $$("user_list").sort("#name#","asc")
     }},
    { view:"button", id:"btn_desc", width:150, value:"Sort desc", css:"webix_primary", 
        click:()=>{
            $$("user_list").sort("#name#","desc")
    }},
]

Dentro do manipulador de cliques, o método de classificação aceita o parâmetro: o nome do campo pelo qual estamos classificando os dados e a direção da classificação “asc”(ascendente) - ascendente e “desc”(descendente) - descendente. Por padrão, os dados são considerados linhas e classificados de acordo.

Resultado (os nomes na planilha são classificados em ordem alfabética):



Agrupamento de dados da tabela em árvore


Considere uma situação em que os dados devem ser agrupados de acordo com parâmetros arbitrários.
Estudarei o agrupamento usando o widget TreeTable como exemplo.

O código do widget TreeTable está localizado no arquivo products_module.js e renderizado na guia "Poducts".

Neste artigo: Módulos, Gráficos, Tabelas em Árvore e Trabalhando com Dados. CRUD , usei dados hierárquicos em uma tabela em árvore. Para resolver esse problema, alterei-os para obter uma matriz linear. Eu me livrei da hierarquia e transferi o campo para cada registro “category”.

[
    {"id": "1.1",   "title": "Standard Ticket",  "price": 21, "category":"Cinema", "rank":1.1},
    {"id": "2.1",   "title": "Cola",  "price": 10, "category":"Cafe", "rank":2.1},
    {"id": "3.1",   "title": "Flowers",  "price": 10, "category":"Other", "rank":3.1}
]

Existem duas maneiras de agrupar dados em uma tabela:


Os parâmetros para esses métodos são os mesmos e preciso agrupar os dados assim que chegarem, portanto, uso a primeira opção.
Na configuração do widget TreeTable, adiciono a propriedade do esquema . Essa propriedade determina por qual esquema os dados serão processados ​​em diferentes situações. Entre os manipuladores no sheme está o método $ group , que eu preciso agrupar os dados.

const products = {
    editable:true,
    view:"treetable",
    scrollX:false,
    columns:[
        { id:"rank", header:"", width:50 },
        { id:"title", header:"Title", fillspace:true, template:"{common.treetable()} #title#"},
        { id:"price", header:"Price", width:200, editor:"text" }
    ],
    select:"row",
    url:"data/products.js",
    scheme:{
        $group:{
            by:"category",
            map:{
                title:["category"]
            }
        },
        $sort:{ by:"value", dir:"asc" }
    }
}

Dentro do manipulador $ group, dois parâmetros são usados:
  • parâmetro obrigatório by , pelo qual os dados são agrupados. Aqui está um dos campos ("categoria");
  • objeto de mapa - aqui descrevemos os campos de dados para os grupos criados. O agrupamento quebra os dados de origem de acordo com os parâmetros especificados e cria "registros pai" para eles. Através do mapa, podemos adicionar novos campos a esses registros. Para que os dados na tabela sejam exibidos corretamente, adicionarei o campo "title". Passarei nele o valor do parâmetro pelo qual o agrupamento ocorre.

Além disso, configurei a função $ sort para classificar os dados agrupados em ordem alfabética.

Resultado do agrupamento:



Sincronização de componentes


A tarefa usa os widgets Gráfico e Lista, cujo código está no arquivo users_module.js e renderizado na guia "Usuários"

Os widgets de gráfico e lista usam os mesmos dados - uma matriz JSON. Esses componentes podem ser vinculados de forma que todas as alterações de dados em um deles (a fonte) sejam transmitidas para outro. Para fazer isso, use o método sync.

O método de sincronização permite copiar dados de um componente e transferi-los para outro. Ao mesmo tempo, alterações no componente principal, como adicionar, excluir etc., são imediatamente refletidas em outro.

Para começar, no widget Gráfico - gráfico - vou excluir o link de dados.

{
    view:"chart",
    id:"chart",
    type:"bar",
    value:"#age#",
    label:"#age#",
    xAxis:{
        template:"#name#",
        title:"Age"
    }
}

Agora, no arquivo script.js, usando o método sync, sincronizo o widget Gráfico com o widget Lista .

$$("chart").sync($$("user_list"));

Na função addPerson, a adição é deixada apenas para o widget Lista.

let addPerson = () => {
    let obj = {
        name:"Some name",
        age:Math.floor(Math.random() * 80) + 10, 
        country:"Some country"
    }
    $$("user_list").add(obj);
};

Agora, ao adicionar e remover entradas da lista, ocorrerão alterações no gráfico. A classificação e a filtragem no widget Lista agora afetarão os dados no gráfico.



Generalização


Usando exemplos práticos, mostrei como você pode melhorar a experiência do usuário. Além da classificação e filtragem padrão usando a API, a capacidade interna de fazer isso nos widgets Table e TreeTable com uma configuração foi dominada. Um método para agrupar dados em uma tabela foi demonstrado e o exemplo de sincronização expandiu a capacidade de melhorar a operação de widgets que usam a mesma fonte de dados.

O aplicativo finalizado pode ser encontrado aqui .

All Articles