Tabla con busqueda y paginación

Tema en 'Soporte' iniciado por Pedro, el 7 Ene 2018.

  1. Pedro

    Pedro New Member

    Registrado:
    7 Ene 2018
    Mensajes:
    4
    Me Gusta recibidos:
    0
    Puntos de trofeo:
    1
    Género:
    Masculino
    Buenos días, soy novato y estoy intentando usar este framework, pero de momento no he sabido la forma de integrar una tabla con una relación de registros con paginación y búsqueda. ¿podrían darme alguna referencia para poder crear una tabla para crud con paginación y busqueda de registros?

    muchas gracias de antemano
     
  2. Marco Corona

    Marco Corona New Member

    Registrado:
    29 Sep 2017
    Mensajes:
    19
    Me Gusta recibidos:
    4
    Puntos de trofeo:
    3
    Género:
    Masculino
    Hola Pedro, yo en lo personal utilizo datatables.js (https://datatables.net), generas tu tabla normal y está librería la renderiza, tiene muchas funciones entre algunas útiles, exportar a Excel, csv, etc. Yo lo he probado con tablas de hasta 1000 registros y funciona excelente, saludos.
     
  3. Pedro

    Pedro New Member

    Registrado:
    7 Ene 2018
    Mensajes:
    4
    Me Gusta recibidos:
    0
    Puntos de trofeo:
    1
    Género:
    Masculino
    Gracias Marcos por la sugerencia, en mi caso estaría bien Datatables pero usando server side ya que mi tabla tiene mas de 7000 registros. He localizado algún ejemplo en codeigniter buscare la forma de adaptarlo a Ocrend
    saludos
     
  4. Marco Corona

    Marco Corona New Member

    Registrado:
    29 Sep 2017
    Mensajes:
    19
    Me Gusta recibidos:
    4
    Puntos de trofeo:
    3
    Género:
    Masculino
    Hola, la verdad que no había considerado esta opción que es muy interesante, he buscado en la web de datatables, y creo que la documentación ahí incluida es suficiente;

    https://datatables.net/manual/server-side
    https://github.com/DataTables/DataTables/tree/master/examples/server_side

    Aunque veo que habría un trabajo considerable en adaptar la librería, creo que sería una buena inversión trabajar en adaptar esta opción al framework, yo me apunto si les interesa adaptarlo al framework.

    Aunque veo que también sería muy sencillo adaptarlo de manera rápida si limitas la opción de buscador a ciertas columnas, y apuntando la petición ajax a la API, espero nos compartas tus avances.
     
    Última edición: 8 Ene 2018
  5. Pedro

    Pedro New Member

    Registrado:
    7 Ene 2018
    Mensajes:
    4
    Me Gusta recibidos:
    0
    Puntos de trofeo:
    1
    Género:
    Masculino
    He intentado integrar el codigo de codeigniter http://mbahcoding.com/tutorial/php/codeigniter/codeigniter-simple-server-side-datatable-example.html en Ocrend y me estoy dando de tortas con la llamada Ajax que me devuelve el error de "invalid JSON response".

    Insertar CODE, HTML o PHP:
    <script type="text/javascript">
    
    var table;
    
    $(document).ready(function() {
    
       //datatables
       table = $('#table').DataTable({
    
           "processing": true, //Feature control the processing indicator.
           "serverSide": true, //Feature control DataTables' server-side processing mode.
           "order": [], //Initial no order.
    
           // Load data for the table's content from an Ajax source
           "ajax": {
               "url": "dbusers/ajax_list", // LLamada al metodo del controlador DbUsers/ajax_list
               "type": "POST"
           },
    
           //Set column definition initialisation properties.
           "columnDefs": [
           {
               "targets": [ 0 ], //first column / numbering column
               "orderable": false, //set not orderable
           },
           ],
    
       });
    
    });
    </script>
    En el metodo del controlador DbUsers tengo lo siguiente
    Insertar CODE, HTML o PHP:
      public function ajax_list()
       {
          global $http;  // para las peticiones POST de ajax
           $data = array();
    // relleno el arreglo de momento manualmente para solucionar funcionamiento.
           $row = array();
           $row[] = 1;
           $row[] = 'nombre';
           $row[] = 'email';
           $row[] = 'password';
           $data[] = $row;
           $row = array();
           $row[] = 2;
           $row[] = 'nombre2';
           $row[] = 'email2';
           $row[] = 'password2';
           $data[] = $row;
    
    
           $output = array(
                           "draw" => $http->request->get('draw')/*  $_POST['draw']*/,
                           "recordsTotal" => $this->d->count_all(),
                           "recordsFiltered" => $this->d->count_filtered(),
                           "data" => $data,
                   );
    
          return json_decode($output);  // no funciona 
    }
    
    ¿Alguna ayuda para llamar a un metodo de un controlador desde AJAX para que funcione?

    Gracias
     
  6. Marco Corona

    Marco Corona New Member

    Registrado:
    29 Sep 2017
    Mensajes:
    19
    Me Gusta recibidos:
    4
    Puntos de trofeo:
    3
    Género:
    Masculino
    Saludos

    Lo primero que deberías hacer es verificar que el array que retornas es correcto (y en mi opinión deberías de utilizar la API en lugar de una ruta comun)

    verifica primero con un dato array como este;
    PHP:
    array (
      
    'draw' => '1',
      
    'recordsTotal' => 122,
      
    'recordsFiltered' => 122,
      
    'data' =>
      array (
        
    =>
        array (
          
    => 1,
          
    => 'Carine ',
          
    => 'Schmitt',
          
    => '40.32.2555',
          
    => '54, rue Royale',
          
    => 'Nantes',
          
    => 'France',
        ),
        
    =>
        array (
          
    => 2,
          
    => 'Jean',
          
    => 'King',
          
    => '7025551838',
          
    => '8489 Strong St.',
          
    => 'Las Vegas',
          
    => 'USA',
        ),
        
    =>
        array (
          
    => 3,
          
    => 'Peter',
          
    => 'Ferguson',
          
    => '03 9520 4555',
          
    => '636 St Kilda Road',
          
    => 'Melbourne',
          
    => 'Australia',
        ),
        
    =>
        array (
          
    => 4,
          
    => 'Janine ',
          
    => 'Labrune',
          
    => '40.67.8555',
          
    => '67, rue des Cinquante Otages',
          
    => 'Nantes',
          
    => 'France',
        ),
      ),
    );
    de igual considera que la función es json_encode(array), ya que la función que utilizas es para pasar un json a array
     
  7. Pedro

    Pedro New Member

    Registrado:
    7 Ene 2018
    Mensajes:
    4
    Me Gusta recibidos:
    0
    Puntos de trofeo:
    1
    Género:
    Masculino
    Gracias a las pistas de Marco Corona y este manual http://mbahcoding.com/tutorial/php/codeigniter/codeigniter-simple-server-side-datatable-example.html , el uso de Datatables en Ocrend conectado a base de datos se ha conseguido.

    Las partes clave son la creación de la sentencia SQL dependiendo de los parámetros recibidos por datatables y la llamada Ajax desde la pagina html que se ha hecho a través del API.

    Creo que sería interesante añadirle al generador de codigo los titulos:columna para crear la tabla, la secuencia de campos de ordenación y los de búsqueda, o bien, una clase modelo que tome los datos a partir de un array.

    LLamada API en post.php
    PHP:
    /**
        * Recuperar datos datatables DbUsers
        *
        * @return json
    */
    $app->post('/clientes/post', function() use($app) {
        
    $u = new Model\DbUsers;

        return 
    $app->json($u->datos_post());
    });
    Modelo DbUsers.php
    PHP:
    <?php

    /*
     * This file is part of the Ocrend Framewok 2 package.
     *
     * (c) Ocrend Software <info@ocrend.com>
     *
     * For the full copyright and license information, please view the LICENSE
     * file that was distributed with this source code.
     */

    namespace app\models;

    use 
    app\models as Model;
    use 
    Ocrend\Kernel\Models\Models;
    use 
    Ocrend\Kernel\Models\IModels;
    use 
    Ocrend\Kernel\Models\ModelsException;
    use 
    Ocrend\Kernel\Models\Traits\DBModel;
    use 
    Ocrend\Kernel\Router\IRouter;

    /**
     * Modelo Dbusers
     *
     * @author Pedro Rivero <pedroriverofalo@gmail.com>
     */

    class Dbusers extends Models implements IModels {

      use 
    DBModel;

      var 
    $table 'customers';
      var 
    $columns_fields '*';
      var 
    $column_order = array(null'FirstName','LastName','phone','address','city','country'); // columnas de orden en la misma posicion de la tabla
      
    var $column_search = array('FirstName','LastName','phone','address','city','country'); // todas las columnas de busqueda

      
    var $order = array('id' => 'asc'); // orden por defecto

      
    var $filter='1'// filtro inicial opcional

      
    var $query// sentencia sql creada dinamicamente
      // Contenido del modelo...


        /**
          * __construct()
        */
        
    public function __construct(IRouter $router null) {
            
    parent::__construct($router);
            
    $this->startDBConexion();
        }


        
    // contruccion de la sentencia sql con los parametros de búsqueda y ordenación
        
    private function _get_datatables_query()
        {
            global 
    $http;

            
    $this->query 'select '.$this->columns_fields.' from '.$this->table.' where '.$this->filter;

            
    $i 0;
            
    $postvalue='';
            
    $abuscar='';

            foreach (
    $this->column_search as $item// loop column
            
    {
                
    $postvalue=$http->request->get('search');
                
    // RECOREMOS EL ARRAY DE CAMPOS DE BUSQUEDA CON EL VALOR INDICADO
                
    if(  $postvalue &&  $postvalue['value'] )
                {

                    if(
    $i===0// first loop
                    
    {
                        
    // SE AGRUPA CON PARENTESIS, APERTURA EN PRIMER ELEMENTO
                        
    $this->query.=' and (';
                        
    $this->query.=' '.$item.' like "%'.$postvalue['value'].'%"';
                    }
                    else
                    {
                        
    $this->query.=' or '.$item.' like "%'$postvalue['value'].'%"';
                    }

                    if(
    count($this->column_search) - == $i//last loop
                        
    $this->query.=')'// CIERRE PARENTESIS
                
    }
                
    $i++;
            }


            if( 
    $http->request->get('order') ) // crear order by multicolumna
            
    {
                
    // array con multiples ordenes de registro
                
    $ordsql=array();
                foreach( 
    $http->request->get('order') as $order)
                {
                    
    $ordsql[]=$this->column_order$order['column'] ].' '.$order['dir'];
                }
                
    $this->query.=' order by '.implode(","$ordsql);
            }
            else if(isset(
    $this->order))
            {
                
    $order $this->order;
                
    $this->query.=' order by '.key($order).' '.$order[key($order)];
            }

        }

        
    // Obtiene un array con los registros de la página actual
        
    function get_datatables()
        {
            global 
    $http;

            
    $this->_get_datatables_query();
            if( 
    $http->request->get('length') )
            {
                
    $this->query.=' LIMIT '.$http->request->get('start').','.$http->request->get('length');
            }
            
    $rows $this->db->query_select$this->query );

            return 
    $rows;
        }

        function 
    count_filtered()
        {
            
    $this->_get_datatables_query();
            
    $query $this->db->query$this->query );
            return 
    $this->db->rows($query);
        }

        public function 
    count_all()
        {
            
    $this->query='select '.$this->columns_fields.' from '.$this->table.' where '.$this->filter;
            
    $query$this->db->query($this->query);
            return 
    $this->db->rows($query);
        }

        public function 
    datos_post()
        {
            global 
    $http;
            
    $rows $this->get_datatables();
            
    $q=$this->query;
            
    $data = array();
            
    $no $http->request->get('start');

            if (
    $rows)
            foreach (
    $rows as $customers) {
                
    $no++;
                
    $row = array();
                
    $row[] = $no;
                
    $row[] = $customers['FirstName'];
                
    $row[] = $customers['LastName'];
                
    $row[] = $customers['phone'];
                
    $row[] = $customers['address'];
                
    $row[] = $customers['city'];
                
    $row[] = $customers['country'];
                
    $data[] = $row;
            }

            
    $output = array (
                
    'draw' =>  $http->request->get('draw') ,
                
    'recordsTotal' => $this->count_all(),
                
    'recordsFiltered' => $this->count_filtered(),
                
    /*'query' => $q,'start' => $http->request->get('start'),
                'length'=> $http->request->get('length'),'datos'=> $rows,
                'orden'=> $http->request->get('order'),
                'ordencol'=> ($http->request->get('order') ? $this->column_order[ $http->request->get('order')['0']['column'] ] : '' ), */
                
    'data' => $data );

          return 
    $output;
        }

        
    /**
          * __destruct()
        */
        
    public function __destruct() {
            
    parent::__destruct();
            
    $this->endDBConexion();

        }


    }
    Vista twig
    PHP:
    {% extends 'overall/layout' %}
    {% 
    block appHeader %}
    <
    link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs/dt-1.10.16/datatables.min.css"/>
    {% 
    endblock %}
    {% 
    block appBody %}
    <
    div class="container">
           <
    h1 style="font-size:20pt">Simple Serverside Datatable Ocrend</h1>

           <
    h3>Users Data</h3>
           <
    br />

           <
    table id="table" class="display" cellspacing="0" width="100%">
                <
    thead>
                    <
    tr>
                        <
    th>No</th>
                        <
    th>First Name</th>
                        <
    th>Last Name</th>
                        <
    th>Phone</th>
                        <
    th>Address</th>
                        <
    th>City</th>
                        <
    th>Country</th>
                    </
    tr>
                </
    thead>
                <
    tbody>
                </
    tbody>

                <
    tfoot>
                    <
    tr>
                        <
    th>No</th>
                        <
    th>First Name</th>
                        <
    th>Last Name</th>
                        <
    th>Phone</th>
                        <
    th>Address</th>
                        <
    th>City</th>
                        <
    th>Country</th>
                    </
    tr>
                </
    tfoot>
            </
    table>
       </
    div>
    {% 
    endblock %}

    {% 
    block appFooter  %}
    <
    script type="text/javascript" src="https://cdn.datatables.net/v/bs/dt-1.10.16/datatables.min.js"></script>

    <
    script type="text/javascript">

    var 
    table;

    $(
    document).ready(function() {

       
    //datatables
       
    table = $('#table').DataTable({

           
    "processing"true//Feature control the processing indicator.
           
    "serverSide"true//Feature control DataTables' server-side processing mode.
           
    "order": [], //Initial no order.

           // Load data for the table's content from an Ajax source
           
    "ajax": {
               
    "url""api/clientes/post",
               
    "type""POST"
           
    },

           
    //Set column definition initialisation properties.
           
    "columnDefs": [
           {
               
    "targets": [ ], //first column / numbering column
               
    "orderable"false//set not orderable
           
    },
           ],

       });

    });
    </
    script>
    {% 
    endblock %}
    Y finalmente el controlador
    PHP:
    <?php

    /*
     * This file is part of the Ocrend Framewok 2 package.
     *
     * (c) Ocrend Software <info@ocrend.com>
     *
     * For the full copyright and license information, please view the LICENSE
     * file that was distributed with this source code.
    */

    namespace app\controllers;

    use 
    app\models as Model;
    use 
    Ocrend\Kernel\Router\IRouter;
    use 
    Ocrend\Kernel\Controllers\Controllers;
    use 
    Ocrend\Kernel\Controllers\IControllers;

    /**
     * Controlador dbusers/
     *
     * @author Pedro Rivero <pedroriverofalo@gmail.com>
    */

    class dbusersController extends Controllers implements IControllers {

        public function 
    __construct(IRouter $router) {
            
    parent::__construct($router);
                echo 
    $this->template->render('dbusers/dbusers');
        }
    }

    muchas gracias
     

Compartir esta página