Me lo contaron y lo olvidé, lo leí y lo entendí, lo hice y lo aprendí.





viernes, 22 de septiembre de 2017

[JavaScript] Usar checkbox en Kendo Grid con valores booleanos

Introducción

El grid de KendoUI soporta datos del tipo booleano, pero su funcionalidad de edición para el usuario se representa en forma de un campo "select" (DropDown) con las opciones de "verdadero" y "falso". De forma nativa no permite poner un "CheckBox" que realice esta función y si se quiere hacer uso del template para poner el "CheckBox" éste no actualiza por sí solo la información del campo en el grid.
Para términos de la explicación

En los ejemplos de esta explicación se tiene el siguiente ambiente:

  • Un grid con ID: "div-monitor-data-grid"
  • El grid tiene como "DataSource" un arreglo llamado "resultadoFlujo".
  • Los objetos del DataSource tienen un atributo llamado "Seleccionada", el cual es el "booleano" que se quiere manipular con el checkbox; éste deberá ser sustituido por el atributo que se desea manipular en sus propios casos.
  • Los objetos del DataSource tienen un atributo que les sirve de llave primaria: IdDetalle; éste deberá ser reemplazado por el o los atributos que identifiquen de manera única los objetos en sus propios casos.

Solución

Debido a que la única forma (Hasta ahora conocida) de agregar un campo tipo CheckBox a un GRID en kendo es mediante del Template se hará uso de éste, poniendo una condición para que cuando el campo tenga el valor "true" el input esté seleccionado y deseleccionado para el caso contrario:

{
    title: "Seleccionar",
    field: "Seleccionada",
    template: "#if(Seleccionada){#<div class='text-center'><input  type='checkbox'  class='chkSeleccionada' checked/></div>#}else{#<div class='text-center'><input  type='checkbox'  class='chkSeleccionada'/></div>#}#",
},

Como se aprecia, el checkbox contiene una clase (En este caso: "chkSeleccionada"), la cual servirá para capturar el evento de éste al ser "clickeado" por el usuario; ésta función se "amarrará" al grid donde se encuentre el input, además de que se realizará en una función "anónima" para que se ejecute en cada momento:

$(function () {
  $('#id-del-grid').on('click', '.chkSeleccionada', function () { //Como se ve, el evento se da a la clase "chkSeleccionada"
    .......
  });
});

La lógica dentro del evento debe ser la siguiente:
Obtener el valor del checkbox (Si está o no seleccionado).
Recuperar el objeto del grid del cual obtendremos el objeto de la tupla que corresponde al checkbox clickeado.
Recorremos la lista que funge de "DataSource" para el "Grid". En cada iteración se compara con el objeto de la tupla seleccionada; y de ser ésta la tupla, al objeto del arreglo se le da el valor del checkbox (True o false).
Se refresca el grid al terminar de iterar.
El código final de ésta función quedaría así:

$(function () {
  $('#div-monitor-data-grid').on('click', '.chkSeleccionada', function () {
     var checked = $(this).is(':checked'); //Se obtiene el valor del checkbox
     var grid = $('#div-monitor-data-grid').data().kendoGrid; //Se obtiene el objeto del grid
     var dataItem = grid.dataItem($(this).closest('tr')); //Se obtiene la tupla que corresponde al checkbox
     for (var i = 0; i < vm.resultadoFlujo.length; i++)
    { //Se itera el datasource
       if (vm.resultadoFlujo[i].IdDetalle == dataItem.IdDetalle)
      { //Se pregunta si es el mismo objeto del checkbox
         vm.resultadoFlujo[i].Seleccionada = checked; //Se edita el valor del atributo por el del checkbox
      }
    }
    grid.dataSource.read(); // Se vuelve a "leer" el dataSource del grid.
    grid.refresh(); //Se refresca el GRID.
  });
});