#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;
}
});
};