Ir para o conteúdo
jQuery Grid Checkbox Column Alternatives – Part II

jQuery Grid Checkbox Column Alternatives – Part II

Uma rápida recapitulação: a coluna Checkbox é um recurso que fornece configuração padrão para transformar valores booleanos na grade do jQuery em caixas de seleção.

10min read

Esta é a segunda parte que aborda o tópico de alternativas de coluna de caixa de seleção do jQuery Grid e/ou implementações personalizadas. Como expliquei, no entanto, os padrões nunca são bons o suficiente para todos os cenários existentes e a comunidade mencionou a limitação que tem em relação à coexistência com modelos de coluna e linha. Embora existam razões válidas para isso, também há muitos casos em que você deseja ir:

Alternativa de coluna de caixa de seleção jQuery Grid usando o modelo para melhorar a funcionalidade e a experiência de correspondência.

Bem, você não está vendo errado - parece essencialmente o mesmo. É muito simples, na verdade. Digamos, se um aplicativo tem usado as caixas de seleção até agora e (como sempre acontece) surge uma ideia para adicionar alguma funcionalidade adicional sobre a coluna existente / nova que requer o uso de um modelo. Portanto, é razoável querer manter a mesma interface do usuário de antes, certo?

Além disso, como você deve se lembrar do primeiro blog, não gosto muito da aparência da caixa de seleção padrão e Deus me livre que o usuário esteja executando algum outro sistema operacional ... Agora, essas caixas de seleção parecem fantásticas, então vamos ver como podemos usá-las.

O recurso de coluna de caixa de seleção para o resgate!

Não vendo errado novamente - o que percebi ao criar os modelos de entrada é que o recurso padrão em si também é um! O recurso está lá, os estilos e outras partes úteis estão lá para montarmos como acharmos melhor. Com isso dito, a primeira e mais fácil coisa de reutilizar é o modelo de coluna de caixa de seleção e seus estilos.

O modelo

Esse modelo usa tags HTML Span estilizadas junto com CSS para criar esse elemento de interface do usuário, o que significa que é completamente aberto para estilo e independente da implementação do sistema operacional ou do navegador. Veja como um modelo como esse ficaria:

var checkboxTemplate="<span style=\'width:100%;display:inline-block;overflow:hidden;text-align:center;\'>' +
"<span class=\"ui-state-default ui-corner-all ui-igcheckbox-small\">"+"<span class=\"ui-icon ui-icon-check ui-igcheckbox-small-{{if ${SalariedFlag} === \"true\"}}on{{else}}off{{/if}}\"/>"+"</span></span>";

Agora a estrutura para os vãos:

  • O Span mais externo atua como um recipiente de células que se espalha no espaço disponível e permite que os internos sejam bem centralizados. Opcional.
  • O do meio atua como a borda da caixa de seleção. Necessário.
  • O mais interno é o preenchimento vazio / carrapato. O "ui-igcheckbox-small-off/on" são os respectivos estilos. Observe que o estilo 'off' substitui o 'on', então você pode essencialmente ter 'on' por padrão e adicionar/remover 'off' conforme apropriado (é exatamente assim que será feito mais tarde). Além disso, se você notou o componente 'pequeno', também há uma versão 'normal' que você pode ver no recurso Seletores de linha. Necessário.

O resultado disso não é surpreendente (estávamos atrás deles de qualquer maneira). A melhor parte é que você obtém a mesma aparência de antes (se estiver usando o recurso), obtém um controle de interface do usuário que parece muito melhor do que o padrão e até sangra com o estilo de outros controles. Além disso, ele não se encaixa apenas no estilo, ele combina com o estilo dos Seletores de Linha (que eu vejo como essencial é que ambos são usados) e combina com o tema, já que a aparência vem do CSS e vem do tema. Um exemplo de definição de grade usando o acima:

$.ig.loader(function () {
    $("#grid").igGrid({
        primaryKey: "BusinessEntityID",
        height: 550,
        dataSource: "@Url.Action("Employees")",
        autoGenerateColumns: false,
        columns: [
            { key: "BusinessEntityID", width: "50px", headerText: "ID", dataType: "number" , template: "<a href=\"http://msdn.microsoft.com/en-us/library/ms124432(v=sql.100).aspx\">${BusinessEntityID}</a>"},
            { key: "LoginID", width: "250px", headerText: "Login ID", dataType: "string" },
            { key: "JobTitle", width: "220px" , headerText: "Job Title", dataType: "string" },
            { key: "SalariedFlag", width: "120px", headerText: "SalariedFlag", dataType: "bool", template: checkboxTemplate },
            { key: "CurrentFlag", width: "100px",headerText: "Current Flag", dataType: "bool" , template: "<span style=\'width:100%;display:inline-block;overflow:hidden;text-align:center;\'><span class=\'ui-state-default ui-corner-all ui-igcheckbox-normal\'><span class=\'ui-icon ui-icon-check ui-igcheckbox-normal-on{{if ${CurrentFlag} === \'true\'}} {{else}} ui-igcheckbox-normal-off{{/if}}\'/></span></span>'}
             ],
        features: [
            { name: "Filtering", mode: "advanced", type: "local" },
            { name: "Sorting", type: "local" },
            { name: "Updating", editMode: 'none'}]
    });
});

A grade resultante com as caixas de seleção pequenas (padrão) na coluna 'Assalariado' e 'normal' na "Bandeira atual":

Colunas de caixa de seleção usando o modelo do recurso padrão.

E, sim, eles vão Metro ou Modern UI (acho que é assim que será chamado agora) se você aplicar o tema 'metro':

Colunas de caixa de seleção usando o modelo do recurso padrão com o tema metro / moderno aplicado.

Como você pode ver, como os valores são booleanos, as colunas não têm problemas com outros recursos do Grid.

Atualizações de valor em linha com um clique

Obviamente, assim como na solução anterior, você pode se conectar ao evento de clique para lidar com a interação do usuário sem entrar no modo de edição. Como antes, o uso da API de atualização exigirá que o próprio recurso seja carregado e inicializado com a grade (NetAdvantage® jQuery Online Help : igGrid Updating). Desta vez, no entanto, temos duas colunas desta vez. As opções são duas – duplicar o manipulador de eventos para cada coluna ou simplesmente passar a chave da coluna para a função e usá-la em vez do valor estático:

var checkboxTemplate = "<span style=\'width:100%;display:inline-block;overflow:hidden;text-align:center;\'>' +
    "<span class=\"ui-state-default ui-corner-all ui-igcheckbox-small\">" +
    "<span class=\"ui-icon ui-icon-check ui-igcheckbox-small-{{if ${SalariedFlag} === \"true\"}}on{{else}}off{{/if}}\"" +
    " data-rowid=\"${BusinessEntityID}\"  onclick=\"checkboxChanged(event, 'SalariedFlag');\"/></span></span>";

O atributo 'data-' será usado para acompanhar a chave de linha e a coluna será passada para o manipulador. Alguns pequenos ajustes em relação à disponibilidade diferente de propriedades para suporte ao navegador e o snippet final fica assim:

function checkboxChanged(evt, colId) {
    // for IE < 9 currentTarget is srcElement
    var element = evt.currentTarget || evt.srcElement;
    // get rowID where change occured:
    var rowId = $(element).data().rowid;
    var newValue;
    //IE doesn't have classList so check and use Name instead
    if (element.classList){
        newValue = element.classList.contains("ui-igcheckbox-small-on") ? false : true;
    }
    else{
        newValue = element.className.indexOf("ui-igcheckbox-small-on") >= 0 ? false : true;
    }
    $("#grid").igGridUpdating("setCellValue", rowId, colId, newValue);
}

A ideia é muito simples – se o clique ocorreu, significa que o valor deve mudar e deve ser o oposto do que era agora – então verificamos se o estilo 'on' é aplicado. Observe que mencionei que 'off' é o substituto, no entanto, neste caso, atualizar o valor da célula com um método Updating faz com que a interface do usuário seja atualizada e, portanto, o modelo é reaplicado e o estilo 'on' não estará lá se o valor for falso.

Ação de edição

Há mais uma parte incrível do recurso de coluna Caixa de seleção que pode ser reutilizada. No primeiro blog que mencionei, você pode definir seu próprio provedor de editores. Se você procurar a referência da API de atualização de grade, poderá ver um 'columnSetting' que permite definir um provedor de editor e "deve estender $.ig. EditorProviderDefault ou deve ter definições de todos os seus métodos". Agora isso pode exigir alguma codificação, mas adivinhe - a coluna Checkbox já tem uma definida! Então é assim que você o usa:

$.ig.loader(function () {
    $("#grid").igGrid({
        primaryKey: "BusinessEntityID",
        height: 550,
        dataSource: "@Url.Action("Employees")",
        autoGenerateColumns: false,
        columns: [
            { key: "BusinessEntityID", width: "50px", headerText: "ID", dataType: "number" , template: "<a style=\'font-size:20px;\' href=\'http://msdn.microsoft.com/en-us/library/ms124432(v=sql.100).aspx\'>${BusinessEntityID}</a>'},
            { key: "LoginID", width: "250px", headerText: "Login ID", dataType: "string" },
            { key: "JobTitle", width: "220px" , headerText: "Job Title", dataType: "string" },
            { key: "SalariedFlag", width: "150px", headerText: "SalariedFlag", dataType: "bool", template: checkboxTemplate}
        ],
        features: [
            { name: "Filtering", mode: "advanced", type: "local" },
            { name: "Sorting", type: "local" },
            { name: "Updating", columnSettings: [{ columnKey: "SalariedFlag", editorProvider: new $.ig.CustomEditorProviderCheckbox()} ]}]
    });
});

Na linha 16 – simples e muito eficaz. Agora, quando você entra no modo de edição, obtém uma experiência adequada (e consistente). E é realmente simples assim:

O editor criado pelo provedor de caixa de seleção.

Editor provider

O provedor padrão mostrado acima não atende aos requisitos? Em seguida, usaremos um personalizado e adicionaremos alguns valores não booleanos na mistura para uma boa medida. Conforme explicado, você tem um monte de provedores de editor para as necessidades de atualização, juntamente com um padrão recomendado para personalização. No nosso caso, no entanto, podemos estender o provedor da caixa de seleção e implementar apenas as diferenças. Deixe-me explicar o básico de um provedor - é uma classe com alguns métodos essenciais - um para criar um editor (este é chamado por Atualizando quando o modo de edição é ativado e retorna o elemento de edição real), um para obter e outro para definir valores. Então você tem foco, tamanho e gerenciamento de validação, mas eles são implementados ou não dizem respeito ao nosso tipo de provedor. Este é o fluxo básico de execução de métodos para dar uma ideia de por que cada método faz o que faz:

Fluxo generalizado de eventos e chamadas de método resultantes para os editores de atualização.

Por exemplo, se novamente você precisar suportar valores diferentes de Booleano, você pode usar seu modelo como de costume e substituir os métodos get e set value do provedor para ter um bom editor de caixa de seleção também –sem somente leitura e sem cintilação. Além disso, é até muito fácil de implementar também. Para o caso do último blog e qualquer outro caso de valores aleatórios 'aceitáveis' e falsos equivalentes, significa que não precisamos modificar o método setValue como.. Bem, números e strings serão avaliados como verdadeiros e null-s serão avaliados como falsos e funcionará bem para exibir o valor no editor. Portanto, é apenas o get e é quase divertidamente fácil:

$.ig.CustomEditorProviderCheckbox = $.ig.CustomEditorProviderCheckbox || $.ig.EditorProviderCheckbox.extend({
    getValue: function () {
        return this.value ? 10 : null;
    }
});

Agora, digamos que esses valores não serão avaliados conforme o esperado (embora atualmente o façam), você também terá que substituir o setValue e chamar o método da superclasse com a saída desejada:

$.ig.CustomEditorProviderCheckbox = $.ig.CustomEditorProviderCheckbox || $.ig.EditorProviderCheckbox.extend({
    getValue: function () {
        return this.value ? 10 : null;
    },
    setValue: function (val, updating) {
      val = parseInt(val) ? true : false;
      this._super(val, updating);
    }
});

E se tudo isso não for suficiente, você sempre pode ir mais longe – alterar a interface do usuário renderizada para o Editor no método create, alterar a maneira como a interação afeta o valor no método set e assim por diante. Mas esse é um tópico totalmente separado ou mais como um tópico por tipo de provedor, pois a maioria deles tem seus requisitos e implementações especiais.

O resto é bem claro - o mesmo estilo de modelo da parte 'Ação de edição' apenas com parseInt, como no blog anterior. E, novamente, usando as configurações de coluna para Atualização, você define o provedor da coluna desejada como um novo '$.ig. CustomEditorProviderCheckbox()'.

Comparação

PROS
  • Funcionará com outros modelos.
  • Fácil de implementar – 1 linha para cenários simples ou mais uma para definir o provedor.
  • Aparência consistente – se encaixa com o resto das partes da grade e combina com o tema.
  • Excelente edição reutilizando o provedor de editor de caixa de seleção padrão.
  • Novamente, não se limitando apenas a valores booleanos.
  • Também não se limitando a uma caixa de seleção de dois estados, uma caixa de seleção de três estados pode ser potencialmente implementada(JSFiddle mostrando uma implementação simples de caixa de seleção de 3 estados.)
CONTRAS
  • Pode exigir algum código para implementar com valores não booleanos, embora, como mostrado mesmo lá, você possa poupar a maior parte do trabalho.
  • Requer um pouco de trabalho para adicionar essa funcionalidade de 'atualização com um único clique'. Eu poderia argumentar que vale a pena.
  • Nada mais que eu possa ver, realmente.

Conclusão

Espero que isso tenha sido educativo e ocasionalmente útil. Também espero que tenha ficado claro que os padrões não são sua única opção e não apenas é fácil criar soluções personalizadas, mas também reciclar partes das disponíveis torna tudo muito melhor. A forma como os dados são representados é completamente arbitrária em relação aos valores reais e não apenas os bons e velhos elementos de formulários ou os modificados com aparência consistente podem ser usados - neste ponto, você pode substituir a caixa de seleção pelo botão deslizante / alternado e pode usar uma abordagem semelhante para modificar qualquer outro tipo de representação de dados. Porque, no final, o jQuery Grid e seus recursos provaram ser muito personalizáveis e, na maioria dos casos, sempre têm a propriedade, método ou evento certo para ajudar um desenvolvedor a criar experiências incríveis!

O projeto de demonstração está disponível para download. Como sempre, você pode nos seguir no Twitter@DamyanPeteve@ Infragisticse manter contato noFacebook,Google+eLinkedIn!

Solicite uma demonstração