javascript

JavaScript – Asociar información a elementos dinámicos con data-*

Uso de los atributos data en HTML y JavaScript

Los atributos data de HTML son atributos personalizados que ayudan a asociar información a un elemento HTML (incluso si es creado de manera dinámica) con JavaScript.

Estos atributos vienen de maravilla cuando tenemos elementos dinámicos y queremos acceder a ellos en el click de un botón o de ellos mismos.

Lo que haremos hoy es ver cómo asociar información de una variable de JavaScript a un elemento HTML para después recuperarla en el click del botón:

Demostración de click del botón al agregar información con los atributos data

Cómo funcionan los atributos data

Estos atributos son para guardar información en elementos HTML. Si queremos definirlos en HTML se hace así:

<elemento data-id="1"/>

Solo ponemos data-* en donde el asterisco es cualquier dato.

También se puede con JavaScript. Para establecerlos hacemos:

elemento.dataset.id = 1;

Y para recuperarlos:

let id = elemento.dataset.id;

Restricciones de atributos data

Estos atributos solo pueden guardar cadenas, justo como lo hace localStorage.

Pero recordemos que cualquier cosa se puede serializar en una cadena usando JSON. Así que si queremos guardar datos complejos como un objeto o arreglo simplemente establecemos el dato usando JSON.stringify y después al recuperarlo usamos JSON.parse.

No hay límite de atributos. Es decir, podemos establecer muchos atributos data. Por ejemplo:

<img data-id="1" data-otro-valor="hola"/>

Lo mismo pasa con JavaScript.

Ejemplo de atributos data con datos dinámicos

Voy a mostrarte cómo lograr lo que se ve en la imagen del encabezado, es decir, ligar información a un botón y luego recuperarla en el click.

Recuerda que recomiendo ampliamente ver primero cómo dibujar una tabla dinámica.

La vista

La tabla HTML se ve así:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <title>Asociar información a elementos dinámicos</title>
        <link href="style.css" rel="stylesheet" type="text/css" />
    </head>

    <body>
        <h1>Asociar información a elementos dinámicos</h1>
        <a href="//parzibyte.me/blog">By Parzibyte</a>
        <table>
            <thead>
                <tr>
                    <th>Nombre</th>
                    <th>Precio</th>
                    <th>Código</th>
                    <th>Acción</th>
                </tr>
            </thead>
            <tbody id="cuerpoTabla">

            </tbody>
        </table>
        <script src="script.js">
 </script>
    </body>

</html>

No definimos el cuerpo de la tabla porque ese será dibujado de manera dinámica.

Los productos

Voy a basarme en un ejemplo anterior en donde dibujamos una tabla dinámica a partir de un arreglo.

Ahora cada que agregamos una fila a la tabla, agregamos también un botón.

Tenemos el arreglo de productos:

const productos = [{
        id: 1,
        nombre: "Mouse Logitech",
        precio: 20,
        codigo: "123",
    },
    {
        id: 2,
        nombre: "Xiaomi Mi A1",
        precio: 5000,
        codigo: "123444",
    },
    {
        id: 3,
        nombre: "Galletas",
        precio: 10,
        codigo: "20205",
    },
    {
        id: 4,
        nombre: "Computadora portátil",
        precio: 30000,
        codigo: "7700545",
    },
];

Establecer datos

Lo vamos a recorrer y en cada paso del ciclo vamos a asignar el producto (codificado como JSON) al botón. Así:

// El td del botón
let $tdBoton = document.createElement("td");
let $boton = document.createElement("button");
// dataset solo permite guardar cadenas, por eso codificamos como JSON
$boton.dataset.producto = JSON.stringify(producto);
$boton.textContent = "Acción";
// En el click llamamos a la función definida anteriormente
$boton.addEventListener("click", accionProducto);
$tdBoton.appendChild($boton);
$tr.appendChild($tdBoton);

Presta atención a la línea 5 pues en ella estamos accediendo al dataset. Lo demás es agregar elementos de manera dinámica para dibujar una tabla como vimos en el tutorial anterior.

También mira la línea 8 pues en ella escuchamos el click y llamamos a la función accionProducto cuya definición veremos más adelante.

No olvides que ese fragmento de código está dentro de un forEach por lo que se agrega el listener y el producto al botón por cada iteración o paso.

Acceder a los datos

En el click del botón vamos a llamar a la función llamada accionProducto. Ahí, a través de this, tenemos una referencia al elemento.

Por lo tanto solo accedemos a los datos, los decodificamos y a partir de ahí tenemos acceso a cada producto.

// Esta función será llamada cada que se haga clic en el botón
const accionProducto = function() {
    // Recuerda: "this" se refiere al elemento
    const productoComoJson = this.dataset.producto;
    // Debemos decodificarlo
    const producto = JSON.parse(productoComoJson);
    // Y ahora ya podemos acceder a las propiedades del producto
    console.log("El nombre: ", producto.nombre);
    console.log("El id: ", producto.id);
};

Poniendo todo junto

Entonces el script completo queda así:

/**
 * Asociar información a elemento HTML
 * en JavaScript con los atributos de
 * data-*
 * 
 * @author parzibyte
 * 
 * @see https://parzibyte.me/blog
 */const productos = [{
        id: 1,
        nombre: "Mouse Logitech",
        precio: 20,
        codigo: "123",
    },
    {
        id: 2,
        nombre: "Xiaomi Mi A1",
        precio: 5000,
        codigo: "123444",
    },
    {
        id: 3,
        nombre: "Galletas",
        precio: 10,
        codigo: "20205",
    },
    {
        id: 4,
        nombre: "Computadora portátil",
        precio: 30000,
        codigo: "7700545",
    },
];

// Esta función será llamada cada que se haga clic en el botón
const accionProducto = function() {
    // Recuerda: "this" se refiere al elemento
    const productoComoJson = this.dataset.producto;
    // Debemos decodificarlo
    const producto = JSON.parse(productoComoJson);
    // Y ahora ya podemos acceder a las propiedades del producto
    console.log("El nombre: ", producto.nombre);
    console.log("El id: ", producto.id);
};

// Ahora dibujamos la tabla
const $cuerpoTabla = document.querySelector("#cuerpoTabla");
// Recorrer todos los productos
productos.forEach(producto => {
    // Crear un <tr>
    const $tr = document.createElement("tr");
    // Creamos el <td> de nombre y lo adjuntamos a tr
    let $tdNombre = document.createElement("td");
    $tdNombre.textContent = producto.nombre; // el textContent del td es el nombre
    $tr.appendChild($tdNombre);
    // El td de precio
    let $tdPrecio = document.createElement("td");
    $tdPrecio.textContent = producto.precio;
    $tr.appendChild($tdPrecio);
    // El td del código
    let $tdCodigo = document.createElement("td");
    $tdCodigo.textContent = producto.codigo;
    $tr.appendChild($tdCodigo);
    // El td del botón
    let $tdBoton = document.createElement("td");
    let $boton = document.createElement("button");
    // dataset solo permite guardar cadenas, por eso codificamos como JSON
    $boton.dataset.producto = JSON.stringify(producto);
    $boton.textContent = "Acción";
    // En el click llamamos a la función definida anteriormente
    $boton.addEventListener("click", accionProducto);
    $tdBoton.appendChild($boton);
    $tr.appendChild($tdBoton);
    // Finalmente agregamos el <tr> al cuerpo de la tabla
    $cuerpoTabla.appendChild($tr);
    // Y el ciclo se repite hasta que se termina de recorrer todo el arreglo
});

La vista no se modificó en ningún momento.

Nota: los estilos de la tabla fueron tomados de aquí.

Conclusión

Con este enfoque podemos ligar información a elementos, la cual podemos recuperar en otro lugar.

En este caso agregamos el objeto completo, aunque en la vida real recomiendo solo agregar el id o índice para hacer más ligeras las cosas.

Te invito a leer más sobre JS o HTML en mi blog.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

1 semana hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

2 semanas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

2 semanas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

2 semanas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

2 semanas hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

2 semanas hace

Esta web usa cookies.