Filtrado del lado del servidor con jQuery, Ajax, PHP y MySQL

Los filtros ayudan al usuario a ordenar un conjunto de registro de un listado de datos. Utilizando las búsquedas y filtros, el usuario puede encontrar datos relevantes de entre una gran cantidad de información. En una aplicación web, es muy útil el hecho de poder ordenar o filtrar datos, sobre todo si manejamos mucha información. En este tutorial, te mostraremos cómo implementar una función de filtrado del lado del servidor utilizando jQuery, Ajax, PHP y MySQL.

Nuestro script proporciona la característica de búsqueda y filtrado dentro de un listado de datos. Es decir, un usuario podrá encontrar registros concretos entre todos los que alberga la base de datos MySQL. En este script, el usuario no necesitará actualizar la página para mostrar los resultados. Para ello nos valeremos de jQuery y Ajax.

En este script leeremos y mostraremos toda la información de usuarios de la base de datos MySQL. Una vez el usuario introduzca la búsqueda, el listado de usuarios se filtrará basándose en si el concepto introducido por el usuario coincide con algún email o nombre de la base de datos. Utilizando el desplegable de ordenar, el usuario puede filtrar aún más los resultados mediante una condición específica. En el desplegable estarán disponibles estas opciones:

  • Newest: Ordenará los resultados del registro más nuevo, al más antiguo.
  • Ascending: Ordenará los resultados basándose en el nombre del usuario, comenzando con la A y terminando con la Z.
  • Descending: Ordenará los resultados basándose en el nombre del usuario, comenzando con Z y terminando por la A.
  • Active: Filtrará por usuarios activos basándose en su estado.
  • Inactive: Filtrará por usuarios inactivos basándose en su estado.

Antes de empezar, échale un vistazo a la estructura de ficheros del lado del servidor.

> DB.php
> getData.php
> index.php

Creación de la base de datos

Para este script de ejemplo crearemos una simple tabla de usuarios (users) con algunas columnas básicas, donde almacenaremos la información de los usuarios.

CREATE TABLE `users` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `phone` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
 `created` datetime NOT NULL,
 `modified` datetime NOT NULL,
 `status` enum('1','0') COLLATE utf8_unicode_ci NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Clase DB

La clase DB gestiona todas las operaciones relacionadas con la base de datos. Por ejemplo, conectarse a la base de datos y obtener registros. Debes cambiar las variables $dbHost, $dbUsername, $dbPassword y $dbName por las credenciales de tu propia base de datos.

<?php
/*
 * DB Class
 * This class is used for database related (connect and fetch) operations
 * @author    CodexWorld.com
 * @url       http://www.codexworld.com
 * @license   http://www.codexworld.com/license
 */
class DB{
    private $dbHost     = "localhost";
    private $dbUsername = "root";
    private $dbPassword = "";
    private $dbName     = "codexworld";
    
    public function __construct(){
        if(!isset($this->db)){
            // Connect to the database
            $conn = new mysqli($this->dbHost, $this->dbUsername, $this->dbPassword, $this->dbName);
            if($conn->connect_error){
                die("Failed to connect with MySQL: " . $conn->connect_error);
            }else{
                $this->db = $conn;
            }
        }
    }
    
    /*
     * Returns rows from the database based on the conditions
     * @param string name of the table
     * @param array select, where, search, order_by, limit and return_type conditions
     */
    public function getRows($table,$conditions = array()){
        $sql = 'SELECT ';
        $sql .= array_key_exists("select",$conditions)?$conditions['select']:'*';
        $sql .= ' FROM '.$table;
        if(array_key_exists("where",$conditions)){
            $sql .= ' WHERE ';
            $i = 0;
            foreach($conditions['where'] as $key => $value){
                $pre = ($i > 0)?' AND ':'';
                $sql .= $pre.$key." = '".$value."'";
                $i++;
            }
        }
        
        if(array_key_exists("search",$conditions)){
            $sql .= (strpos($sql, 'WHERE') !== false)?'':' WHERE ';
            $i = 0;
            foreach($conditions['search'] as $key => $value){
                $pre = ($i > 0)?' OR ':'';
                $sql .= $pre.$key." LIKE '%".$value."%'";
                $i++;
            }
        }
        
        if(array_key_exists("order_by",$conditions)){
            $sql .= ' ORDER BY '.$conditions['order_by']; 
        }
        
        if(array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
            $sql .= ' LIMIT '.$conditions['start'].','.$conditions['limit']; 
        }elseif(!array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
            $sql .= ' LIMIT '.$conditions['limit']; 
        }
        
        $result = $this->db->query($sql);
        
        if(array_key_exists("return_type",$conditions) && $conditions['return_type'] != 'all'){
            switch($conditions['return_type']){
                case 'count':
                    $data = $result->num_rows;
                    break;
                case 'single':
                    $data = $result->fetch_assoc();
                    break;
                default:
                    $data = '';
            }
        }else{
            if($result->num_rows > 0){
                while($row = $result->fetch_assoc()){
                    $data[] = $row;
                }
            }
        }
        return !empty($data)?$data:false;
    }
}

getData.php

En este fichero, leemos los datos de los usuarios utilizando la clase DB basándonos en la búsqueda o en la condición del filtro.Mediante type y val, obtendremos los datos de los usuarios y los mostraremos en un listado HTML. Las siguiente operaciones pueden ocurrir según el type.

search: devuelve el listado de usuarios basándose en la búsqueda por palabras
sort: ordena el listado basándose en la condición del desplegable

<?php
include 'DB.php';
$db = new DB();
$tblName = 'users';
$conditions = array();
if(!empty($_POST['type']) && !empty($_POST['val'])){
    if($_POST['type'] == 'search'){
        $conditions['search'] = array('name'=>$_POST['val'],'email'=>$_POST['val']);
        $conditions['order_by'] = 'id DESC';
    }elseif($_POST['type'] == 'sort'){
        $sortVal = $_POST['val'];
        $sortArr = array(
            'new' => array(
                'order_by' => 'created DESC'
            ),
            'asc'=>array(
                'order_by'=>'name ASC'
            ),
            'desc'=>array(
                'order_by'=>'name DESC'
            ),
            'active'=>array(
                'where'=>array('status'=>'1')
            ),
            'inactive'=>array(
                'where'=>array('status'=>'0')
            )
        );
        $sortKey = key($sortArr[$sortVal]);
        $conditions[$sortKey] = $sortArr[$sortVal][$sortKey];
    }
}else{
    $conditions['order_by'] = 'id DESC';
}
$users = $db->getRows($tblName,$conditions);
if(!empty($users)){
    $count = 0;
    foreach($users as $user): $count++;
        echo '<tr>';
        echo '<td>'.$user['name'].'</td>';
        echo '<td>'.$user['email'].'</td>';
        echo '<td>'.$user['phone'].'</td>';
        echo '<td>'.$user['created'].'</td>';
        $status = ($user['status'] == 1)?'Active':'Inactive';
        echo '<td>'.$status.'</td>';
        echo '</tr>';
    endforeach;
}else{
    echo '<tr><td colspan="5">No user(s) found...</td></tr>';
}
exit;

index.php

Contiene la vista principal del proyecto y es lo que va a ver el usuario. Cuando la página se carga por primera vez, todos los datos del usuario se listan con las opciones de búsqueda y filtrado. Una vez ejecutado el filtrado, utilizamos Ajax para obtener los datos requeridos por el usuario mediante el archivo getData.php. Para que lo entiendas mejor, hemos dividido el archivo index.php en dos partes.

Bootstrap y Javascript

Utilizamos jQuery y Ajax para hacer el filtrado de datos sin necesidad de actualizar la página, es por eso que necesitamos incluir la librería jQuery. Puedes omitir la librería Bootstrap si no quieres seguir su estructura.

<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

Utilizamos la función getUsers() para obtener la información de los usuarios del archivo getData.php utilizando Ajax y mostramos lo recibido en el listado HTML. La función getUsers() acepta dos parámetros, type y val. Basándonos en estos dos parámetros, mostraremos los resultados.

function getUsers(type,val){
    $.ajax({
        type: 'POST',
        url: 'getData.php',
        data: 'type='+type+'&val='+val,
        beforeSend:function(html){
            $('.loading-overlay').show();
        },
        success:function(html){
            $('.loading-overlay').hide();
            $('#userData').html(html);
        }
    });
}

Codigo HTML

Inicialmente, todos los datos de los usuarios los leemos de la tabla users y los listamos con el buscador y el desplegable de filtros.

<div class="container">
    <h2>Users Search & Filter by CodexWorld</h2>
    <div class="form-group pull-left">
        <input type="text" class="search form-control" id="searchInput" placeholder="By Name or Email">
        <input type="button" class="btn btn-primary" value="Search" onclick="getUsers('search',$('#searchInput').val())"/>
    </div>
    <div class="form-group pull-right">
        <select class="form-control" onchange="getUsers('sort',this.value)">
          <option value="">Sort By</option>
          <option value="new">Newest</option>
          <option value="asc">Ascending</option>
          <option value="desc">Descending</option>
          <option value="active">Active</option>
          <option value="inactive">Inactive</option>
        </select>
    </div>
    <div class="loading-overlay" style="display: none;"><div class="overlay-content">Loading.....</div></div>
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Name</th>
                <th>Email</th>
                <th>Phone</th>
                <th>Created</th>
                <th>Status</th>
            </tr>
        </thead>
        <tbody id="userData">
            <?php
                include 'DB.php';
                $db = new DB();
                $users = $db->getRows('users',array('order_by'=>'id DESC'));
                if(!empty($users)){ $count = 0;
                    foreach($users as $user){ $count++;
            ?>
            <tr>
                <td><?php echo $user['name']; ?></td>
                <td><?php echo $user['email']; ?></td>
                <td><?php echo $user['phone']; ?></td>
                <td><?php echo $user['created']; ?></td>
                <td><?php echo ($user['status'] == 1)?'Active':'Inactive'; ?></td>
            </tr>
            <?php } }else{ ?>
            <tr><td colspan="5">No user(s) found...</td></tr>
            <?php } ?>
        </tbody>
    </table>
</div>

Código CSS

El siguiente CSS lo utilizaremos para alinear la caja de búsqueda y diseñar el overlay de cargando.

.form-control{float: left;width: 70%;}
.btn{float: left;margin-left: 5px;}
/* For Loading Overlay by CodexWorld */
.container{position: relative;}
.loading-overlay{
    position: absolute;
    left: 0; 
    top: 0; 
    right: 0; 
    bottom: 0;
    z-index: 2;
    background: rgba(255,255,255,0.7);
}
.overlay-content {
    position: absolute;
    transform: translateY(-50%);
     -webkit-transform: translateY(-50%);
     -ms-transform: translateY(-50%);
    top: 50%;
    left: 0;
    right: 0;
    text-align: center;
    color: #555;
}

Fuente: codexworld.com

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP