Как сортировать столбцы таблицы PHP, MySQL, JavaScript AJAX

#javascript #php #mysql #ajax #crud

#javascript #php #mysql #ajax #crud

Вопрос:

Это часть кода CRUD, которая позволяет мне создавать, читать, обновлять и удалять страницы без обновления, используя AJAX, PHP, MySQL и JavaScript. Я хотел бы знать, есть ли какой-либо способ отсортировать результаты без обновления страницы при нажатии на th thead столбец с помощью AJAX?

index.php

 include 'inc/funciones/funciones.php';
<table id="listado-contactos" class="listado-contactos">
    <thead>
        <tr>
            <th>Nombre</th>
            <th>Empresa</th>
            <th>Teléfono</th>
            <th>Acciones</th>
        </tr>
    </thead>
    <tbody>
        <?php $contactos = obtenerContactos();
        if ($contactos->num_rows) :
            foreach ($contactos as $contacto) : ?>
                <tr>
                    <td><?php echo $contacto['nombre']; ?></td>
                    <td><?php echo $contacto['empresa']; ?></td>
                    <td><?php echo $contacto['telefono']; ?></td>
                    <td>
                        <a href="editar.php?id=<?php echo $contacto['id_contacto']; ?>" class="btn btn-editar">
                            <i class="fas fa-pen-square"></i>
                        </a>
                        <button data-id="<?php echo $contacto['id_contacto']; ?>" type="button" class="btn btn-borrar">
                            <i class="fas fa-trash-alt"></i>
                        </button>
                    </td>
                </tr>
            <?php endforeach; ?>
        <?php endif; ?>
    </tbody>
</table>
  

db.php

 <?php
define('DB_USUARIO', 'root');
define('DB_PASWORD', '');
define('DB_HOST', 'localhost');
define('DB_NOMBRE', 'agendaphp');
define('DB_PORT', '3306');

$conn = new mysqli(DB_HOST, DB_USUARIO, DB_PASWORD, DB_NOMBRE, DB_PORT);
// echo $conn->ping();
?>
  

funciones.php

 <?php
function obtenerContactos() {
    include 'db.php';
    try {
        return $conn->query("SELECT id_contacto, nombre, empresa, telefono FROM contactos");

    } catch (Exception $e) {
        echo "error" . $e->getMessage() . "<br>";
        return false;
    }
}
  

Комментарии:

1. Да, используя плагин, подобный этому jQuery TableSorter

2. Привет, Джей, я только что внедрил плагин, который вы мне предложили, и он работает, он очень прост в использовании, большое вам спасибо за ответ. Но теперь я хотел бы знать, есть ли какой-либо способ отсортировать результаты с помощью mysql (ПОРЯДОК по ASC). я объясняю мне, сначала результаты sohw в таблице с порядком из базы данных, после нажатия на th столбца thead снова вызываются в базу данных и без обновления страницы показывают результат в порядке возрастания, используя ajax, я думаю…

3. Вы имеете в виду нажатие на заголовок столбца и выполнение AJAX-запроса к MySQL с другим видом? Если это так, это будет много работы.

4. Да, я имею в виду это, я знаю, что это более сложное, но и более элегантное решение. может быть, проблема в том, что у меня пока нет знаний. Мне нужно больше учиться. Тем не менее, я поделился всем кодом моего проекта на случай, если вы увидите возможное решение.

5. Что делает его более элегантным? Решение jQuery очень элегантное и не требует дополнительных обходов к базе данных, которые, как правило, являются крупнейшими ресурсными боровами в веб-дизайне.

Ответ №1:

методом Ajax вы можете запросить сервер для получения данных из этого: поскольку Ajax — это код javascript, вам нужен код js, и после этого вам нужно вызвать код сервера PHP с помощью вашего ajax, чтобы вам также понадобился код файла PHP, чтобы PHP-код взаимодействовал с базой данных для вас и возвращал данные на ваш сервер.файл javascript. итак, сначала мы создадим PHP-файл, который будет готов к ajax:

server.php :

 <?php 
$db=mysqli_connect("localhost","root","pass","db_name");
$u_sent_from_ajax = mysqli_real_escape_string($conn, $_POST['sendAnythingToPhp']); //20

    $select_query = "SELECT * FROM your_table";
$data_query = $db->query($select_query);
if ($data_query ->num_rows > 0) {
  
    $i=0;
    while($row = $data_query->fetch_assoc()) { // march the row array
       $result_array[$i]= $row;
       
          $i=$i 1;
    }
}
mysqli_close($db);

echo json_encode($result_array); // it sends $result_array to ajax request as a data
  ?>
  

теперь: ваш файл запроса на стороне клиента -> ajax.js:

     $.ajax({                                      
      url: 'sendMe.php',                  //the script to call to get data   
        
      sendAnythingToPhp: "20",      //you can send  your desire value to server also and then get there and use
      //sendAnythingToPhp_1: "21",    
        
      dataType: 'json',                //data format    JSON  
      success: function(data)          //on recieve of reply
      {

 console.log(data); // use your retured data from above php code to your html file
          
    });
  

Комментарии:

1. вам нужно работать шаг за шагом, сначала вам нужно иметь данные в ваших руках, затем сортировать и использовать события нажатия, чтобы достичь вашего желания. это следует делать постепенно.

2. Не используйте mysqli_real_escape_string()

3. Привет, Фернан, большое спасибо за ответ. У меня нет знаний, чтобы реализовать ваш ответ в моем коде. Я вставляю весь код из своего проекта, поэтому, возможно, вы сможете дать мне более конкретный ответ, связанный с моим проектом.

Ответ №2:

Полный код, кроме файлов css:

header.php

 <!doctype html>
<html class="no-js" lang="es-ES">

<head>
    <meta charset="utf-8">
    <title>Agenda de Contactos</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <meta property="og:title" content="">
    <meta property="og:type" content="">
    <meta property="og:url" content="">
    <meta property="og:image" content="">

    <link rel="manifest" href="site.webmanifest">
    <link rel="apple-touch-icon" href="icon.png">
    <link rel="icon" href="favicon.ico" type="image/x-icon" sizes="16x16">

    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900amp;family=Roboto:wght@100;300;400;500;700;900amp;display=swap" rel="stylesheet">
    <link rel="stylesheet" href="css/normalize.css">
    <link rel="stylesheet" href="css/fontawesome.css">
    <link rel="stylesheet" href="css/main.css">

    <meta name="theme-color" content="#fafafa">
</head>

<body>
  

footer.php

     <script src="js/vendor/modernizr-3.11.2.min.js"></script>
    <script src="js/plugins.js"></script>
    <script src="js/main.js"></script>

    <script>
        window.ga = function() {
            ga.q.push(arguments)
        };
        ga.q = [];
        ga.l =  new Date;
        ga('create', 'UA-XXXXX-Y', 'auto');
        ga('set', 'anonymizeIp', true);
        ga('set', 'transport', 'beacon');
        ga('send', 'pageview')
    </script>
    <script src="https://www.google-analytics.com/analytics.js" async></script>
</body>

</html>
  

index.php

 <?php
include 'inc/funciones/funciones.php';
include 'inc/layout/header.php';
?>

<div class="contenedor-barra">
    <h1>Agenda de Contactos</h1>
</div>

<div class="contenedor bg-amarillo sombra">
    <form action="#" id="contacto">
        <legend>Añada un contacto <span>Todos los campos son obligatorios</span></legend>
        <?php include 'inc/layout/formulario.php'; ?>
    </form>
</div>

<div class="contenedor bg-blanco sombra contactos">
    <div class="contenedor-contactos">
        <h2>Contactos</h2>
        <input type="text" id="buscar" class="buscador sombra" placeholder="Buscar contactos...">
        <p class="total-contactos"><span></span> Contactos</p>
        <div class="contenedor-tabla">
            <table id="listado-contactos" class="listado-contactos">
                <thead>
                    <tr>
                        <th>Nombre</th>
                        <th>Empresa</th>
                        <th>Teléfono</th>
                        <th>Acciones</th>
                    </tr>
                </thead>
                <tbody>
                    <?php $contactos = obtenerContactos();
                    if ($contactos->num_rows) :
                        foreach ($contactos as $contacto) : ?>
                            <tr>
                                <td><?php echo $contacto['nombre']; ?></td>
                                <td><?php echo $contacto['empresa']; ?></td>
                                <td><?php echo $contacto['telefono']; ?></td>
                                <td>
                                    <a href="editar.php?id=<?php echo $contacto['id_contacto']; ?>" class="btn btn-editar">
                                        <i class="fas fa-pen-square"></i>
                                    </a>
                                    <button data-id="<?php echo $contacto['id_contacto']; ?>" type="button" class="btn btn-borrar">
                                        <i class="fas fa-trash-alt"></i>
                                    </button>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </tbody>
            </table>
        </div>
    </div>
</div>

<?php include 'inc/layout/footer.php'; ?>
  

editar.php

 <?php
include 'inc/funciones/funciones.php';
include 'inc/layout/header.php';

$id = filter_var($_GET['id'], FILTER_VALIDATE_INT);

if(!$id) {
    die('No es valido');
}

$resultado = obtenerContacto($id);
$contacto = $resultado->fetch_assoc();
?>

<div class="contenedor-barra">
    <div class="contenedor barra">
        <a href="index.php" class="btn volver">Volver</a>
        <h1>Editar Contacto</h1>
    </div>
</div>

<div class="contenedor bg-amarillo sombra">
    <form action="#" id="contacto">
        <legend>Edite el contacto</span></legend>
        <?php include 'inc/layout/formulario.php'; ?>
    </form>
</div>

<?php include 'inc/layout/footer.php'; ?>
  

formulario.php

 <div class="campos">
    <div class="campo">
        <label for="nombre">Nombre:</label>
        <input 
            type="text" 
            placeholder="Nombre contacto" 
            id="nombre" 
            value="<?php echo (isset($contacto['nombre'])) ? $contacto['nombre'] : '';?>"
            >
    </div>
    <div class="campo">
        <label for="empresa">Empresa:</label>
        <input 
            type="text" 
            placeholder="Nombre empresa" 
            id="empresa"
            value="<?php echo (isset($contacto['empresa'])) ? $contacto['empresa'] : '';?>"
            >
    </div>
    <div class="campo">
        <label for="telefono">Teléfono:</label>
        <input 
            type="tel" 
            placeholder="Teléfono contacto" 
            id="telefono"
            value="<?php echo (isset($contacto['telefono'])) ? $contacto['telefono'] : ''; ?>"
        >
    </div>
</div>
<div class="boton enviar">
    <?php
    $textoBtn = isset($contacto['telefono']) ? 'Guardar' : 'Añadir';
    $accion = isset($contacto['telefono']) ? 'editar' : 'crear';
    ?>
    <input type="hidden" id ="accion" value="<?php echo $accion; ?>">
    <?php if(isset($contacto['id_contacto'])) {?>
        <input type="hidden" id ="id" value="<?php echo $contacto['id_contacto']; ?>">
    <?php } ?>
    <input type="submit" value="<?php echo $textoBtn; ?>">
</div>
  

modelo-contacto.php

 <?php
if($_POST) {
    if($_POST['accion'] == 'crear') {
        // Creará un nuevo rgistro en la base de datos
        require_once('../funciones/bd.php');
    
        // Validar las entradas
        $nombre = filter_var($_POST['nombre'], FILTER_SANITIZE_STRING);
        $empresa = filter_var($_POST['empresa'], FILTER_SANITIZE_STRING);
        $telefono = filter_var($_POST['telefono'], FILTER_SANITIZE_STRING);
        
        try {
            $stmt = $conn->prepare("INSERT INTO contactos (nombre, empresa, telefono) VALUES (?, ?, ?)");
            $stmt->bind_param("sss", $nombre, $empresa, $telefono);
            $stmt->execute();
            if($stmt->affected_rows == 1) {
                $respuesta = array(
                    'respuesta' => 'correcto',
                    'info' => $stmt->affected_rows,                
                    'datos' => array(
                        'id_insertado' => $stmt->insert_id,
                        'nombre' => $nombre,
                        'empresa' => $empresa,
                        'telefono' => $telefono
                    )
                );
            } else {
                $respuesta = array(
                    'respuesta' => 'error'
                );
            }
            $stmt->close();
            $conn->close();
        } catch(Exception $e) {
            $respuesta = array(
                'error' => $e->getMessage()
            );
        }
        echo json_encode($respuesta);
        // echo json_encode($_POST);
    }
}

if ($_GET) {
    if($_GET['accion'] == 'borrar') {
        require_once('../funciones/bd.php');

        $id = filter_var($_GET['id'], FILTER_SANITIZE_NUMBER_INT);
        try {
            $stmt = $conn->prepare("DELETE FROM contactos WHERE id_contacto = ?");
            $stmt->bind_param("i", $id);
            $stmt->execute();
            if($stmt->affected_rows == 1) {
                $respuesta = array(
                    'respuesta' => 'correcto'
                );
            } else {
                $respuesta = array(
                    'respuesta' => 'error'
                );
            }
            $stmt->close();
            $conn->close();
        } catch(Exception $e) {
            $respuesta = array(
                'error' => $e->getMessage()
            );
        }
        echo json_encode($respuesta);
    }
}

if ($_POST) {
    if($_POST['accion'] == 'editar') {
        // echo json_encode($_POST);

        require_once('../funciones/bd.php');

        // Validar las entradas
        $nombre = filter_var($_POST['nombre'], FILTER_SANITIZE_STRING);
        $empresa = filter_var($_POST['empresa'], FILTER_SANITIZE_STRING);
        $telefono = filter_var($_POST['telefono'], FILTER_SANITIZE_STRING);
        $id = filter_var($_POST['id'], FILTER_SANITIZE_NUMBER_INT);

        try {
            $stmt = $conn->prepare("UPDATE contactos SET nombre = ?, empresa = ?, telefono = ? WHERE id_contacto = ?");
            $stmt->bind_param("sssi", $nombre, $empresa, $telefono, $id);
            $stmt->execute();
            if($stmt->affected_rows >= 0) { // En el proyecto original era == 1 pero daba error al no modificar datos
                $respuesta = array(
                    'respuesta' => 'correcto'
                );
            } else {
                $respuesta = array(
                    'respuesta' => 'error'
                );
            }
            $stmt->close();
            $conn->close();
        } catch(Exception $e) {
            $respuesta = array(
                'error' => $e->getMessage()
            );
        }
        echo json_encode($respuesta);
    }
}
?>
  

bd.php

 <?php

// Credenciales de la base de datos
define('DB_USUARIO', 'root');
define('DB_PASWORD', '');
define('DB_HOST', 'localhost');
define('DB_NOMBRE', 'agendaphp');
define('DB_PORT', '3306');

$conn = new mysqli(DB_HOST, DB_USUARIO, DB_PASWORD, DB_NOMBRE, DB_PORT);
// echo $conn->ping();

?>
  

funciones.php

 <?php
function obtenerContactos() {
    include 'bd.php';
    try {
        return $conn->query("SELECT id_contacto, nombre, empresa, telefono FROM contactos ORDER BY nombre ASC");

    } catch (Exception $e) {
        echo "error" . $e->getMessage() . "<br>";
        return false;
    }
}

// Obtiene un contacto y toma un id
function obtenerContacto($id) {
    include 'bd.php';
    try {
        return $conn->query("SELECT id_contacto, nombre, empresa, telefono FROM contactos WHERE id_contacto = $id");

    } catch (Exception $e) {
        echo "error" . $e->getMessage() . "<br>";
        return false;
    }
}
?>
  

main.js

 const formularioContactos = document.querySelector('#contacto'),
      listadoContactos = document.querySelector('#listado-contactos tbody'),
      inputBuscador = document.querySelector('#buscar');

eventListeners();

function eventListeners() {
    // Cuando el formulario de crear o editar se ejecuta
    formularioContactos.addEventListener('submit', leerFormulario);

    // Listener para eliminar el boton
    if(listadoContactos) {
        listadoContactos.addEventListener('click', eliminarContacto);
    }

    // Buscador
    if(inputBuscador) {
        inputBuscador.addEventListener('input', buscarContactos);
    };
    
    numeroContactos();
};

function leerFormulario(e) {
    e.preventDefault();
    // Leer los datos de los inputs
    const nombre = document.querySelector('#nombre').value,
          empresa = document.querySelector('#empresa').value,
          telefono = document.querySelector('#telefono').value,
          accion = document.querySelector('#accion').value;

    if(nombre === '' || empresa === '' || telefono === '') {
        mostrarNotificacion('Todos los campos son obligatorios', 'error');

    } else {
        // Pasa la validación, crear llamado a ajax
        const infoContacto = new FormData();
        infoContacto.append('nombre', nombre);
        infoContacto.append('empresa', empresa);
        infoContacto.append('telefono', telefono);
        infoContacto.append('accion', accion);
        // console.log(...infoContacto); // (...) Spread Operator -> transforma un array en una lista de argumentos
        if(accion === 'crear') {
            // Creamos un nuevo contacto
            insertarBD(infoContacto);
        } else {
            // Editar el contacto
            // Leer el id
            const idRegistro = document.querySelector('#id').value;
            infoContacto.append('id', idRegistro);
            actualizarRegistro(infoContacto);
        };
    }
};

// Inserta en la base de datos via Ajax
function insertarBD(datos) {
    // Llamar a ajax
    // Crear el objeto
    const xhr = new XMLHttpRequest();

    // Abrir la conexion
    xhr.open("POST", "inc/modelos/modelo-contacto.php", true);

    // Pasar los datos
    xhr.onload = function() {
        if(this.status === 200) {
            console.log(JSON.parse(xhr.responseText));
            // Leemos la respuesta de PHP
            const respuesta = JSON.parse(xhr.responseText);
            
            // Inserta un nuevo elemento a la tabla
            const nuevoContacto = document.createElement('tr');
            nuevoContacto.innerHTML = `
            <td>${respuesta.datos.nombre}</td>
            <td>${respuesta.datos.empresa}</td>
            <td>${respuesta.datos.telefono}</td>
            `;

            // Crear contenedor para los botones
            const contenedorAcciones = document.createElement('td');
            
            // Crear el icono de editar
            const iconoEditar = document.createElement('i');
            iconoEditar.classList.add('fas', 'fa-pen-square');
            // Crear el enlace para el icono de editar
            const btnEditar = document.createElement('a');
            btnEditar.appendChild(iconoEditar);
            btnEditar.href = `editar.php?id=${respuesta.datos.id_insertado}`;
            btnEditar.classList.add('btn', 'btn-editar');
            // Agregarlo al padre
            contenedorAcciones.appendChild(btnEditar);
            
            // Crear el icono de borrar
            const iconoBorrar = document.createElement('i');
            iconoBorrar.classList.add('fas', 'fa-trash-alt');
            // Crear el boton para el icono de borrar
            const btnBorrar = document.createElement('button');
            btnBorrar.appendChild(iconoBorrar);
            btnBorrar.setAttribute('data-id', respuesta.datos.id_insertado);
            btnBorrar.classList.add('btn', 'btn-borrar');
            // Agregarlo al padre
            contenedorAcciones.appendChild(btnBorrar);

            // Agregarlo al <tr>
            nuevoContacto.appendChild(contenedorAcciones);

            // Agregarlo con los contactos
            listadoContactos.appendChild(nuevoContacto);

            // Resetear el formulario
            document.querySelector('form').reset();

            // Mostrar la notificación
            mostrarNotificacion('Contacto creado correctamente', 'correcto');

            // Actualizar el número
            numeroContactos();
        }
    }

    // Enviar los datos
    xhr.send(datos); 
}

// Actualiza el registro de la base de datos
function actualizarRegistro(datos) {
    // Crear el objeto
    const xhr = new XMLHttpRequest();
    // Abrir la conexion
    xhr.open('POST', 'inc/modelos/modelo-contacto.php', true);
    // Leer la respuesta
    xhr.onload = function() {
        if(this.status === 200) {
            const respuesta = JSON.parse(xhr.responseText);
            console.log(respuesta);
            
            if(respuesta.respuesta === 'correcto') {
                // Mostrar notificación de correcto
                mostrarNotificacion('Contacto editado correctamente', 'correcto');
            } else {
                // Mostrar notificación de error
                mostrarNotificacion('Hubo un error', 'error');
            }
            // Despues de tres segundos redireccionar
            setTimeout(() => {
                window.location.href = 'index.php';
            }, 3000);
        }
    }
    // Enviar la petición
    xhr.send(datos);
};

// Eliminar el contacto
function eliminarContacto(e) {
    if(e.target.parentElement.classList.contains('btn-borrar')) {
        // Toamr el ID
        const id = e.target.parentElement.getAttribute('data-id');
        // Preguntar al usuario
        const confiramcion = confirm('¿Estás seguro (a)?');
        if(confiramcion) {
            // Llamado a ajax
            // Crear el objeto
            const xhr = new XMLHttpRequest();
            // Abrir la conexion
            xhr.open('GET', `inc/modelos/modelo-contacto.php?id=${id}amp;accion=borrar`, true);
            // Leer la respuesta
            xhr.onload = function() {
                if(this.status === 200) {
                    const respuesta = JSON.parse(xhr.responseText);
                    
                    if(respuesta.respuesta === 'correcto') {
                        // Eliminar registro del DOM
                        e.target.parentElement.parentElement.parentElement.remove();
                        // Mostrar notificación
                        mostrarNotificacion('Contacto eliminado', 'correcto');
                        // Actualizar el número
                        numeroContactos();
                    } else {
                        // Mostrar notificación
                        mostrarNotificacion('Hubo un error', 'error');
                    }
                }
            }
            // Enviar la petición
            xhr.send();
        } 
        // console.log(id);
    }
    
}

// Notificación en pantalla
function mostrarNotificacion(mensaje, clase) {
    const notificacion = document.createElement('div');
    notificacion.classList.add(clase, 'notificacion', 'sombra');    
    notificacion.textContent = mensaje;
    const legend = document.querySelector('form legend');
    formularioContactos.insertBefore(notificacion, legend);
    setTimeout(() => {
        notificacion.classList.add('visible');
        setTimeout(() => {
            notificacion.classList.remove('visible');
            setTimeout(() => {
                notificacion.remove();
            }, 500);            
        }, 5000);
    }, 100);
}

// Buscador de registros
function buscarContactos(e) {
    // console.log(e.target.value);
    const expresion = new RegExp(e.target.value, "i"),
          registros = document.querySelectorAll('tbody tr');
    
    registros.forEach(registro => {
        registro.style.display='none';
        if(registro.childNodes[1].textContent.replace(/s/g, " ").search(expresion) != -1
        || registro.childNodes[3].textContent.replace(/s/g, " ").search(expresion) != -1
        || registro.childNodes[5].textContent.replace(/s/g, " ").search(expresion) != -1) {
            registro.style.display='table-row'
        }
        numeroContactos();
    });
};

// Muestra el número de contactos
function numeroContactos() {   
    const totalContactos = document.querySelectorAll('tbody tr'),
          contenedorNumero = document.querySelector('.total-contactos span');
    let total = 0;
    totalContactos.forEach(contacto => {
        if(contacto.style.display === '' || contacto.style.display === 'table-row') {
            contenedorNumero.textContent =   total;
        }
    });
};