Guía 94 – Campo de Selección en formato Tabla

Este ejemplo surge de la necesidad de un desarrollo donde se selecciona de una tabla de parámetros/condiciones una serie de opciones para la revisión de una maquinaria.

Esto es algo que se produce más o menos habitualmente, ya que en muchas ocasiones un código y título de una acción no se describe, completamente,  con esos 2 únicos datos, si no que se requiere un conjunto de información, normalmente estructurada en formato tabla.

El ejemplo que os muestro no es el caso real, pero me sirve para explicaros cuál es el tipo de solución. En este caso, funcionalmente, en la recepción de un vehículo en un taller, se recoge las acciones que hay que hacer a través de una tabla de servicios.

Objetivo

Mostrar una tabla de servicios con varias columnas que describen el mismo, para seleccionar qué acciones hay que realizar.

DEMO: https://fhumanes.com/seleccionTabla/st_vehiculo_list.php

Este es el aspecto de la opción de Añadir.

Solución Técnica

Se ha dado respuesta a las opciones de Add, Edit y View, dado que la lógica de la información a mostrar es diferente en cada caso.

Para la opción de LIST, se ha utilizado el plugin «Tags» que puedes descargar desde mi blog.

 

Para la presentación de la tabla de selección he utilizado la solución de JavaScript Toast UI GRID . Es una excelente solución para realizar presentaciones de información en interfaz WEB, y en este caso he utilizado una pequeña parte de ese potencial.

Para presentar la información he utilizado 3 SNIPPET, cuyos códigos os muestro:

MyCode/add_snippet.php
<?php
// echo $_SESSION['id_vehiculo'];
$sql= <<< EOT
SELECT
master.id_st_master id,
master.codigo,
master.titulo,
master.descripcion,
periodo.codigo periodoCodigo,
periodo.titulo periodoTitulo,
tipoRevision.codigo tipoRevisionCodigo,
tipoRevision.titulo tipoRevisionTitulo,
tiempo.codigo tiempoCodigo,
tiempo.titulo tiempoTitulo,
numOperarios.codigo numOperariosCodigo,
numOperarios.titulo numOperariosTitulo,
reqRepuesto.codigo reqRepuestoCodigo,
reqRepuesto.titulo reqRepuestoTitulo,
facturable.codigo facturableCodigo,
facturable.titulo facturableTitulo
FROM st_master master
JOIN st_periodo periodo on ( id_st_periodo = st_periodo_id)
JOIN st_tipo_revision tipoRevision on ( id_st_tipo_revision = st_tipo_revision_id)
JOIN st_tiempo tiempo on ( id_st_tiempo = st_tiempo_id)
JOIN st_num_operarios numOperarios on ( id_st_num_operarios = st_num_operarios_id)
JOIN st_req_repuesto reqRepuesto on ( id_st_req_repuesto = st_req_repuesto_id)
JOIN st_facturable facturable on ( id_st_facturable = st_facturable_id)  
ORDER BY master.codigo
EOT;
$data_arr = array();
$rs = DB::Query($sql);
while( $data = $rs->fetchAssoc() )
{
    $data_arr[] = $data;
}
$json_data = json_encode($data_arr,JSON_NUMERIC_CHECK);
$html = <<< EOT
<link rel="stylesheet" type="text/css" href="tuiGrid/tui-grid.css" />
<script type="text/javascript" src="tuiGrid/tui-grid.js"></script>

<div class="snippet_html">
  <div id="grid1"></div>
</div>

<script>
const gridData1 = $json_data;
const grid1 = new tui.Grid({
      el: document.getElementById('grid1'),
      data: gridData1,
      scrollX: false,
      scrollY: false,

      // width: 800,
      // bodyHeight: 200,
      rowHeight: 'auto',
      columnOptions: {
          resizable: true,
          minWidth: 50,
        },
      rowHeaders: ['checkbox'], 
      columns: [
        {
          header: 'Código',
          name: 'codigo',
          align: 'center',
          width: 50
        },
        {
          header: 'Título',
          name: 'titulo',
          align: 'left',
          width: 300,
          whiteSpace: 'normal'
        },
        {
          header: 'Periodo',
          name: 'periodoCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Revisión',
          name: 'tipoRevisionCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Tiempo',
          name: 'tiempoCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Operarios',
          name: 'numOperariosCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Repuesto',
          name: 'reqRepuestoCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Facturable',
          name: 'facturableCodigo',
          align: 'center',
          width: 80
        }
      ]
    });
    
    tui.Grid.applyTheme('striped');
    
        
</script>        
EOT;

echo $html;
MyCode/edit_snippet.php
<?php
$id_vehiculo = $_SESSION['id_vehiculo'];
$sql = "SELECT * from st_vehiculo WHERE id_st_vehiculo = $id_vehiculo";
$rs = DB::Query($sql);
$data_vehiculo = $rs->fetchAssoc();
$codigos = $data_vehiculo['revision'];
$codigo_arr = explode(',', $codigos); // Array de todos los código de Acciones


$sql= <<< EOT
SELECT
master.id_st_master id,
master.codigo,
master.titulo,
master.descripcion,
periodo.codigo periodoCodigo,
periodo.titulo periodoTitulo,
tipoRevision.codigo tipoRevisionCodigo,
tipoRevision.titulo tipoRevisionTitulo,
tiempo.codigo tiempoCodigo,
tiempo.titulo tiempoTitulo,
numOperarios.codigo numOperariosCodigo,
numOperarios.titulo numOperariosTitulo,
reqRepuesto.codigo reqRepuestoCodigo,
reqRepuesto.titulo reqRepuestoTitulo,
facturable.codigo facturableCodigo,
facturable.titulo facturableTitulo
FROM st_master master
JOIN st_periodo periodo on ( id_st_periodo = st_periodo_id)
JOIN st_tipo_revision tipoRevision on ( id_st_tipo_revision = st_tipo_revision_id)
JOIN st_tiempo tiempo on ( id_st_tiempo = st_tiempo_id)
JOIN st_num_operarios numOperarios on ( id_st_num_operarios = st_num_operarios_id)
JOIN st_req_repuesto reqRepuesto on ( id_st_req_repuesto = st_req_repuesto_id)
JOIN st_facturable facturable on ( id_st_facturable = st_facturable_id)  
ORDER BY master.codigo
EOT;
$data_arr = array();
$rs = DB::Query($sql);
while( $data = $rs->fetchAssoc() )
{   
    if ( in_array($data['codigo'],$codigo_arr)) {
        $data['_attributes'] = ['checked' => true];
    }          
    $data_arr[] = $data;
}
$json_data = json_encode($data_arr,JSON_NUMERIC_CHECK);
$html = <<< EOT
<link rel="stylesheet" type="text/css" href="tuiGrid/tui-grid.css" />
<script type="text/javascript" src="tuiGrid/tui-grid.js"></script>

<div class="snippet_html">
  <div id="grid1"></div>
</div>

<script>
const gridData1 = $json_data;
const grid1 = new tui.Grid({
      el: document.getElementById('grid1'),
      data: gridData1,
      scrollX: false,
      scrollY: false,

      // width: 800,
      // bodyHeight: 200,
      rowHeight: 'auto',
      columnOptions: {
          resizable: true,
          minWidth: 50,
        },
      rowHeaders: ['checkbox'], 
      columns: [
        {
          header: 'Código',
          name: 'codigo',
          align: 'center',
          width: 50
        },
        {
          header: 'Título',
          name: 'titulo',
          align: 'left',
          width: 300,
          whiteSpace: 'normal'
        },
        {
          header: 'Periodo',
          name: 'periodoCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Revisión',
          name: 'tipoRevisionCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Tiempo',
          name: 'tiempoCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Operarios',
          name: 'numOperariosCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Repuesto',
          name: 'reqRepuestoCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Facturable',
          name: 'facturableCodigo',
          align: 'center',
          width: 80
        }
      ]
    });
    
    tui.Grid.applyTheme('striped');
    
        
</script>        
EOT;

echo $html;
MyCode/view_snippet.php
<?php
$id_vehiculo = $_SESSION['id_vehiculo'];
$sql = "SELECT * from st_vehiculo WHERE id_st_vehiculo = $id_vehiculo";
$rs = DB::Query($sql);
$data_vehiculo = $rs->fetchAssoc();
$codigos = $data_vehiculo['revision'];
$codigo_arr = explode(',', $codigos); // Array de todos los código de Acciones


$sql= <<< EOT
SELECT
master.id_st_master id,
master.codigo,
master.titulo,
master.descripcion,
periodo.codigo periodoCodigo,
periodo.titulo periodoTitulo,
tipoRevision.codigo tipoRevisionCodigo,
tipoRevision.titulo tipoRevisionTitulo,
tiempo.codigo tiempoCodigo,
tiempo.titulo tiempoTitulo,
numOperarios.codigo numOperariosCodigo,
numOperarios.titulo numOperariosTitulo,
reqRepuesto.codigo reqRepuestoCodigo,
reqRepuesto.titulo reqRepuestoTitulo,
facturable.codigo facturableCodigo,
facturable.titulo facturableTitulo
FROM st_master master
JOIN st_periodo periodo on ( id_st_periodo = st_periodo_id)
JOIN st_tipo_revision tipoRevision on ( id_st_tipo_revision = st_tipo_revision_id)
JOIN st_tiempo tiempo on ( id_st_tiempo = st_tiempo_id)
JOIN st_num_operarios numOperarios on ( id_st_num_operarios = st_num_operarios_id)
JOIN st_req_repuesto reqRepuesto on ( id_st_req_repuesto = st_req_repuesto_id)
JOIN st_facturable facturable on ( id_st_facturable = st_facturable_id)  
ORDER BY master.codigo
EOT;
$data_arr = array();
$rs = DB::Query($sql);
while( $data = $rs->fetchAssoc() )
{   
    if ( in_array($data['codigo'],$codigo_arr)) {
        $data['_attributes'] = ['checked' => true, 'checkDisabled' => true];
        $data_arr[] = $data;
    } else {
        $data['_attributes'] = ['checkDisabled' => true];
    }        
    // $data_arr[] = $data;
}
$json_data = json_encode($data_arr,JSON_NUMERIC_CHECK);
$html = <<< EOT
<link rel="stylesheet" type="text/css" href="tuiGrid/tui-grid.css" />
<script type="text/javascript" src="tuiGrid/tui-grid.js"></script>

<div class="snippet_html">
  <div id="grid1"></div>
</div>

<script>
const gridData1 = $json_data;
const grid1 = new tui.Grid({
      el: document.getElementById('grid1'),
      data: gridData1,
      scrollX: false,
      scrollY: false,

      // width: 800,
      // bodyHeight: 200,
      rowHeight: 'auto',
      columnOptions: {
          resizable: true,
          minWidth: 50,
        },
      rowHeaders: ['checkbox'], 
      columns: [
        {
          header: 'Código',
          name: 'codigo',
          align: 'center',
          width: 50
        },
        {
          header: 'Título',
          name: 'titulo',
          align: 'left',
          width: 300,
          whiteSpace: 'normal'
        },
        {
          header: 'Periodo',
          name: 'periodoCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Revisión',
          name: 'tipoRevisionCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Tiempo',
          name: 'tiempoCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Operarios',
          name: 'numOperariosCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Repuesto',
          name: 'reqRepuestoCodigo',
          align: 'center',
          width: 80
        },
        {
          header: 'Facturable',
          name: 'facturableCodigo',
          align: 'center',
          width: 80
        }
      ]
    });
    
    tui.Grid.applyTheme('striped');
    
        
</script>        
EOT;

echo $html;

Como podéis observar, los datos de la tabla se facilitan a través de un formato de datos JSON, fácil de construir. En dicho formato se incorpora el atributo de si el check está activo o no.

Las casillas de check se recuperan  y transforma al formato del campo que almacena la información a través del evento «Javascript Onload», se muestra el código del evento de ADD.

JavaScript Onload event (Add)
var ctrl_revision = Runner.getControl(pageid, 'revision');
ctrl_revision.hide();

this.on('beforeSave', function(formObj, fieldControlsArr, pageObj){
  // console.log("he inciado SAVE");
  var list1 = grid1.getCheckedRows();
  // console.log("rows seleccionados",list1);
  var codigo_arr = [];

  list1.forEach((item , i) => codigo_arr[i] = item.codigo ); // Guardamos los ID's de los registros chequeados.

  // console.log("Arrays de Codigo's: ",codigo_arr);
  ctrl_revision.setValue(codigo_arr.join(",")); // pone el valor en su campo
  
  return true;
});

Creo que es un método sencillo y potente de mejorar la selección de acciones y espero que os guste.

Como siempre, os dejo los fuentes del ejemplo para que lo podáis instalar en vuestros PC’s y podáis hacer las pruebas que requiráis.

Adjuntos

Archivo Tamaño de archivo Descargas
zip PHPRunner 10.91 + backup BD 435 KB 33

Blog personal para facilitar soporte gratuito a usuarios de React y PHPRunner