如何对表列进行排序PHP、MySQL、javaScript和AJAX
这是CRUD的代码部分,允许我使用AJAX、PHP、MySQL和JavaScript创建、读取、更新和删除页面,而无需刷新页面。我想知道,当使用AJAX单击如何对表列进行排序PHP、MySQL、javaScript和AJAX,javascript,php,mysql,ajax,crud,Javascript,Php,Mysql,Ajax,Crud,这是CRUD的代码部分,允许我使用AJAX、PHP、MySQL和JavaScript创建、读取、更新和删除页面,而无需刷新页面。我想知道,当使用AJAX单击thead列的th时,是否有任何方法可以在不刷新页面的情况下对结果进行排序 index.php include 'inc/funciones/funciones.php'; <table id="listado-contactos" class="listado-contactos">
thead
列的th
时,是否有任何方法可以在不刷新页面的情况下对结果进行排序
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>
<?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'; ?>
包括'inc/functiones/functiones.php';
名义
埃普雷萨酒店
特莱福诺酒店
疫苗
通过Ajax方法,您可以请求服务器从中获取数据:因为Ajax是一个javascript代码,所以您需要js代码,然后,您需要使用Ajax调用PHP服务器代码,以便您也需要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
?>
除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;900&family=Roboto:wght@100;300;400;500;700;900&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>
window.ga=函数(){
ga.q.push(参数)
};
ga.q=[];
ga.l=+新日期;
ga(“创建”、“UA-XXXXX-Y”、“自动”);
ga('set','anonymizeIp',true);
ga(“集合”、“传输”、“信标”);
ga('send','pageview')
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>
<?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>
名义:
是的,使用一个像这样的插件嗨,杰伊,我刚刚实现了你给我建议的插件,它很好用,非常感谢你的回答。但是现在我想知道是否有任何方法可以使用mysql(按ASC排序)对结果进行排序。我解释一下,首先是表中的结果,以及来自数据库的顺序,在再次单击thead列调用数据库的th之后,在没有页面刷新的情况下,使用ajax以ASC顺序显示结果,我想…你是说单击列标题并以不同的排序向MySQL发出ajax请求?如果是这样,那将是一个很大的工作。是的,我的意思是,我知道这是一个更复杂但也更优雅的解决方案。可能问题是我还不知道。我必须多学习。即使如此,我还是分享了我项目的所有代码,以防你看到一个可能的解决方案。是什么让它更优雅?jQuery解决方案非常优雅,不需要更多的往返访问数据库,而数据库往往是web设计中最大的资源消耗。您需要一步一步地工作,首先需要手头有数据,然后排序并使用单击事件来达到您的要求。应该循序渐进。不要使用mysqli\u real\u escape\u string()
Hi Fernando,非常感谢您的回答。我不知道如何在我的代码中实现你的答案。我粘贴了我项目中的所有代码,所以也许你可以给我一个与我的项目相关的更具体的答案。
<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>
<?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);
}
}
?>
<?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();
?>
<?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;
}
}
?>
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}&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;
}
});
};