Explicaciones detalladas y ejemplos sobre los métodos data() y removeData() del core de jQuery, usados para almacenar datos en los elementos de la página, en pares clave/valor.
Seguimos viendo componentes interesantes del "Core" de jQuery, donde están las clases y métodos más básicos de esta librería Javascript. En esta entrega del manual de jQuery de DesarrolloWeb.com, explicaremos el uso del método data() y removeData(), que sirven para almacenar, consultar y eliminar cualquier set de datos en elementos de la página.
Por qué necesitamos almacenar datos en elementos
En algunas ocasiones resulta útil almacenar variables u objetos en determinados elementos de la página, es decir, en las etiquetas del propio documeto HTML. Aunque quizás no es una acción muy corriente en los primeros pasos con jQuery, en el futuro encontraréis que resulta útil y veréis herramientas y plugins que utilizan este mecanismo para su operativa.
De manera genérica, algunos casos que se nos pueden ocurrir son:
- Almacenar el estado de una aplicación
- Compartir datos entre varios scripts
- Incializar datos escritos en el HTML, que luego podrán ser leídos con Javascript
- Enviar datos desde lenguajes del servidor como PHP hacia Javascript
De modo que conviene al menos saber que esto es posible y conocer de qué manera podemos utilizar los elementos de la página para guardar cosas en ellos.
Para ello vamos a comentar dos métodos distintos que forman parte del core de jQuery:
Método data()
Este método del objeto jQuery sirve tanto para guardar un dato en un elemento como para consultarlo. Según el número de parámetros que reciba, realiza una u otra acción.- Si recibe un parámetro
data(nombre)
: devuelve el valor que haya en el dato cuyo nombre se pasa por parámetro. - Si recibe dos parámetros
data(nombre, valor)
: almacena un dato, cuyo nombre recibe en el primer parámetro, con el valor que recibe en el segundo parámetro.
Veamos un caso de uso simple. Por ejemplo tenemos un elemento de la página como este:
<div id="capa">
En esta división (elemento id="capa") voy a guardar y leer datos sobre este elemento.
</div>
Ahora podríamos usar le método data()
de la siguiente manera:
$("#capa").data("midato","mivalor");
Con esta línea hemos guardado un dato llamado "midato
" con el valor "mivalor
", en el elemento con identificador (atributo id) "capa
".
Ahora podríamos leer ese dato en cualquier momento para acceder a su valor, de la siguiente manera:
alert($("#capa").data("midato"));
En esta línea de código extraemos el dato "midato
" del elemento con identificador "capa
" y lo mostramos en una caja de alerta.
Método removeData()
Este método sirve para eliminar un dato de un elemento y su funcionamiento es tan simple como enviar por parámetro el dato que se quiere eliminar del elemento.
$("#capa").removeData("midato")
Con esta línea habríamos eliminado el dato llamado "midato
" del elemento con identificador "capa
".
Ejemplo completo de los métodos data() y removeData() del Core de jQuery
Veamos un ejemplo completo del uso de estos métodos que acabamos de aprender. Se trata de una página que tiene un elemento sobre el que vamos a guardar datos. Además tiene tres botones para guardar un dato, leerlo y borrarlo. El dato que se guardará tendrá como valor lo que se haya escrito en un campo de texto que aparece también en la página.
Tenemos, para comenzar, un elemento de la página, que es donde vamos a guardar los pares dato-valor con data()
.
<div id="division">
En esta división (elemento id="division") voy a guardar datos con la función data y luego los voy a leer.
</div>
Luego tendremos este formulario, que contiene el campo de texto así como los tres botones de los que hemos hablado.
Ahora se trata de asignar los comportamientos a estos botones con Javascript, haciendo uso de jQuery.
Este sería el script para agregar el evento click al botón de guardar datos.
$("#guardar").click(function(evento){
let valor = document.formul.valor.value;
// Esta misma línea de código se puede codificar así también con jQuery
// let valor = $("#valor").attr("value");
$("#division").data("midato",valor);
$("#division").html('He guardado en este elemento (id="division") un dato llamado "midato" con el valor "' + valor + '"');
});
Como se puede ver, primero se recibe el texto del campo de texto que había en el formulario. Para ello se muestran dos maneras de hacerlo:
- A través de la jerarquía de objetos del navegador, con
document.formul.valor.value
- A través de su identificador, con un método de jQuery llamado
attr()
que sirve para recuperar el valor de un atributo HTML pasado por parámetro sobre el elemento que recibe el método. Este modo de obtener el atributo value del campo de texto está comentado, pues sólo lo quería señalar, para que se vea el modo de acceder a un elemento de formulario utilizando las funciones de la librería Javascript jQuery.
midato
" con el valor que se recuperó del atributo value del campo de texto. Para ello utilizamos el método data()
tal como comentábamos.
Por último se muestra un mensaje en el HTML del elemento con id="division"
, por medio del método html()
de jQuery, para informar sobre la acción que acabamos de realizar.
Ahora mostramos el código para asignar un comportamiento al evento click sobre el segundo botón:
$("#leer").click(function(evento){
let valor = $("#division").data("midato");
$("#division").html('En este elemento (id="division") leo un dato llamado "midato" con el valor "' + valor + '"');
});
Como se puede ver, se recupera el valor del dato "midato
" guardado sobre el elemento "#division
" (etiqueta HTML con id="division"
), y se almacena en una variable. Luego se crea un mensaje para mostrar el valor del dato.
Para acabar, tenemos el código del evento click sobre el botón de eliminar el contenido de un dato, que hace uso de removeData()
.
$("#eliminar").click(function(evento){
$("#division").removeData("midato");
$("#division").html('Acabo de eliminar del elemento (id="division") el dato llamado "midato"');
});
Como se verá, el método removeData()
se invoca sobre el elemento que tiene el dato que pretendemos eliminar. Más tarde se muestra un mensaje informando sobre la acción que se ha realizado.
Para comprobar el funcionamiento de estos métodos habría que crear un dato, escribiendo el valor en el campo de texto y pulsando el botón "guardar dato". Luego podríamos leer ese dato con el botón "leer dato". Por último podríamos eliminar el dato con el botón "eliminar dato". Si, una vez eliminado pulsamos sobre el botón de "leer dato" veremos que el valor del dato aparece como "undefined
", puesto que ese dato ha sido borrado (esto también ocurre si no se ha guardado ningún dato todavía, por ejemplo cuando se acaba de cargar la página).
Sería interesante ver el código fuente completo de esta página, para hacernos una idea más exacta de cómo se integrarían todos estos elementos.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ejemplo completo de data y removedata</title>
</head>
<body>
<div id="division">
En esta división (elemento id="division") voy a guardar datos con la función data y luego los voy a leer
</div>
<br>
<form name="formul">
Escribe un valor a guardar, leer o eliminar:
<input type="text" name="valor" id="valor">
<br>
<input type="button" value="guardar dato" id="guardar">
<input type="button" value="leer dato" id="leer">
<input type="button" value="eliminar dato" id="eliminar">
</form>
<script src="../../js/jquery-3.6.3.js"></script>
<script>
$(document).ready(function () {
$("#guardar").click(function (evento) {
var valor = document.formul.valor.value;
//Esta misma línea de código se puede codificar así también con jQuery
//var valor = $("#valor").attr("value");
$("#division").data("midato", valor);
$("#division").html('He guardado en este elemento (id="division") un dato llamado "midato" con el valor "' + valor + '"');
});
$("#leer").click(function (evento) {
valor = $("#division").data("midato");
$("#division").html('En este elemento (id="division") leo un dato llamado "midato" con el valor "' + valor + '"');
});
$("#eliminar").click(function (evento) {
$("#division").removeData("midato");
$("#division").html('Acabo de eliminar del elemento (id="division") el dato llamado "midato"');
});
});
</script>
</body>
</html>
Consideraciones interesantes de data() y removeData()
Existen algunos puntos que debemos conocer sobre el funcionamiento de estos métodos que no hemos explicado todavía. Veamos a continuación una serie de consideraciones:
Admite cualquier tipo de dato
Podemos guardar lo que deseemos por medio del método data()
. Los ejemplos anteriores hemos guardado simplemente cadenas de texto, pero soportaría cualquier tipo de variable, numérica, un array o incluso un objeto Javascript o jQuery.
let datoComplejo = {
dato: "valor",
numero: 99
}
$("#elem").data('obj', datoComplejo);
Si consultamos el tipo del dato que hemos guardado nos dirá que es un object
.
typeof ($("#elem").data('obj')) // devuelve object
Se guarda un dato por cada ítem seleccionado en el objeto jQuery
Si ocurre que tengo varios elementos seleccionados dentro de un objeto jQuery y uso la función data() para almacenar un valor, ese valor se introduce en cada uno de los elementos que tenga seleccionados.
Recordemos que, según lo explicado anteriormente en desarrolloweb.com, un objeto jQuery puede tener seleccionados varios elementos de la página, como todos los enlaces presentes, los elementos de una determinada clase CSS, etc. Esto puede ocurrir dependiendo del selector escogido al hacer uso de la función dólar.
Vamos a ver un ejemplo cuando tenemos varios elementos en un objeto. Dado este HTML:
<ul id="lista">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
Ahora, si seleccionamos todos los elementos <li>
de esta lista y les asignamos un dato, como se puede ver en este código.
let elementosLista = $("li", "#lista");
elementosLista.data('numero', 99);
Esto se lo hemos asignado a cada uno de los elementos del objeto jQuery. Por lo tanto, si hacemos un recorrido con each sobre el objeto jQuery podremos ver que cada uno de esos elementos tiene almacenado el mismo valor.
Es relevante que, si intentas acceder a los elementos <li>
por separado, no vamos a encontrar en ellos el dato guardado anteriormente.
elementosLista.each(function() {
item = $(this);
console.log("dato en el item:", item.data('numero'));
});
Los valores almacenados en cada elemento son independientes
En el caso de los tipos de datos primitivos, números, cadenas o boleanos, los valores que se almacenaron en cada uno de los elementos son independientes. Esto significa que, si modificamos uno de ellos, en realidad se modificará solamente ese:
let contador = 1;
elementosLista.each(function () {
item = $(this);
item.data('numero', item.data('numero') + contador);
contador++;
});
Depués del código anterior, en el que hemos variado el dato en un valor distinto, si realizamos un nuevo recorrido para mostrar cada uno de sus valores, apreciaremos que cada elemento mantiene una copia distinta, con valores independientes.
Los objetos se almacenan por referencia
Sin embargo, en el caso que estemos almacenando un objeto Javascript con data()
, sobre uno o varios elementos, no se clona el objeto, sino que se asigna una referencia al mismo objeto. Esto quiere decir que no se harían copias independientes del objeto a guardar, sino que permanecería tal cual y lo que se asignaría como dato es una referencia a ese único objeto.
Ejemplo con data() más complejo
Ahora, para investigar un poco sobre estas posibilidades, hemos creado un par de ejemplos un poco más complejos que hacen uso de los métodos data()
y removeData()
. Son ejemplos más avanzados, que hacen uso de algunas cosas que no hemos explicado todavía en este manual de jQuery. No obstante, vendrá bien verlos para aprender algunos usos de estas funcionalidades.
Para empezar, quiero mostrar una página de ejemplo donde existen tres enlaces y dos botones. Al pulsar cualquiera de los enlaces mostraremos el contenido de un dato almacenado en ellos con data()
. Los botones, por su parte, servirán para almacenar contenidos en datos sobre esos enlaces. Además tendremos una capa con id="mensaje" que nos servirá para mostrar cosas por pantalla.
Podemos ver el ejemplo en marcha en una página aparte.
El código de los elementos HTML será el siguiente:
<section>
<a href="#" id="enlace1">Enlace 1</a>
<br>
<a href="#" id="enlace2">Enlace 2</a>
<br>
<a href="#" id="enlace3">Enlace 3</a>
</section>
<p class="help">Haz clic en los enlaces para ver el valor</p>
<div id="mensaje">
Mensaje...
</div>
<p>
<button id="guardar">guardar "midato" con valor "mivalor" en todos los enlaces</button>
<br>
<button id="guardarenlace1">guardar "midato" con valor "otro valor" en el enlace 1</button>
</p>
Ahora veamos cómo aplicar eventos a los elementos de la página, para almacenar datos y mostrarlos.
Comencemos por el código de los eventos de los botones.
$("#guardar").click(function (evento) {
$("a").data("midato", "mivalor");
$("#mensaje").html('He guardado en todos los enlaces un dato llamado "midato" con el valor "mivalor"');
});
Con este código estamos almacenando datos en todos los enlaces. Cabe fijarse que con la función jQuery $("a")
obtenemos un objeto jQuery donde están todos los enlaces de la página. Luego, al invocar data()
sobre ese objeto, estamos almacenado ese dato en todos los enlaces existentes.
$("#guardarenlace1").click(function (evento) {
$("#enlace1").data("midato", "otro valor");
$("#mensaje").html('He guardado en el enlace1 un dato llamado "midato" con el valor "otro valor"');
});
En este otro código del evento click para el segundo botón, almacenamos "otro valor
" sobre el dato de antes, pero sólo lo hacemos sobre el enlace 1, dado que hemos utilizado el selector $("#enlace1")
, con el identificador único del primer enlace.
Y ahora podríamos ver el código para asignar un evento a todos los enlaces, para que al pulsarlos nos muestre lo que haya en el dato almacenado con data()
, si es que hay algo.
$("a").click(function (evento) {
evento.preventDefault();
valorAlmacenado = $(this).data("midato");
$("#mensaje").html("En el enlace <b>" + $(this).attr("id") + "</b> tiene el dato 'midato' como '" + valorAlmacenado + "'");
});
Como se puede ver, estamos creando un evento click, pero lo estamos haciendo sobre los tres enlaces que hay en la página a la vez, dado el selector utilizado en la función jQuery $("a")
. Luego el código del evento será el mismo para los tres enlaces.
Lo primero que se hace es un evento.preventDefault()
que permite que el enlace no tenga el comportamiento típico (ir a la URL del href). A continuación hacemos:
valorAlmacenado = $(this).data("midato");
Como se puede ver, se está extrayendo el valor almacenado en el enlace actual, que recibe el evento. Con $(this)
obtenemos el objeto jQuery del elemento que ha recibido el evento, que es el enlace sobre el que se ha pulsado y no todos los enlaces. Con el método data("midato")
, invocado sobre $(this)
, obtenemos el valor del dato "midato
" almacenado en el enlace que fue pulsado solamente.
Luego se muestra un mensaje para indicar el valor que había en el dato. Pero claro, este código, como es común para todos los enlaces, tiene que acceder también a $(this)
para saber qué enlace en concreto fue el que se pulsó. Para identificar el enlace se hace $(this).attr("id")
, que devuelve el atributo "id
" del enlace sobre el que se hizo clic.
A continuación se puede ver el código completo de esta página.
<html>
<head>
<title>Ejemplos de uso de la función data del core de jQuery</title>
<style>
.help {
margin-top: 0.5rem;
opacity: 0.6;
font-size: 0.85rem;
}
#mensaje {
padding: 0.5rem 1rem;
background-color: bisque;
border: 2px solid #666;
border-radius: 1rem;
}
button {
margin: 0.2rem 0;
}
</style>
</head>
<body>
<h1>Ejemplo data() con enlaces</h1>
<section>
<a href="#" id="enlace1">Enlace 1</a>
<br>
<a href="#" id="enlace2">Enlace 2</a>
<br>
<a href="#" id="enlace3">Enlace 3</a>
</section>
<p class="help">Haz clic en los enlaces para ver el valor</p>
<div id="mensaje">
Mensaje...
</div>
<p>
<button id="guardar">guardar "midato" con valor "mivalor" en todos los enlaces</button>
<br>
<button id="guardarenlace1">guardar "midato" con valor "otro valor" en el enlace 1</button>
</p>
<script src="../../js/jquery-3.6.3.js"></script>
<script>
$(document).ready(function () {
$("a").click(function (evento) {
evento.preventDefault();
valorAlmacenado = $(this).data("midato");
$("#mensaje").html("En el enlace <b>" + $(this).attr("id") + "</b> tiene el dato 'midato' como '" + valorAlmacenado + "'");
});
$("#guardar").click(function (evento) {
$("a").data("midato", "mivalor");
$("#mensaje").html('He guardado en todos los enlaces un dato llamado "midato" con el valor "mivalor"');
});
$("#guardarenlace1").click(function (evento) {
$("#enlace1").data("midato", "otro valor");
$("#mensaje").html('He guardado en el enlace1 un dato llamado "midato" con el valor "otro valor"');
});
});
</script>
</body>
</html>
Ejemplo de almacenamiento de objeto
En este ejemplo vamos a realizar el almacenamiento de un dato de tipo objeto, para que veamos que podemos guardar cosas distintas de simples cadenas.
El objetivo es crear un formulario que tenga la opción de guardar su estado. Una vez guardado el estado el usuario es capaz de recuperar ese estado en cualquier momento.
El ejemplo es un poco rústico, porque hemos hecho algunas cosas un poco "manualmente", como la recuperación de los datos del formulario. Pero como idea de aplicación de data() puede estar bien, porque con esta técnica podríamos hacer una utilidad para que los estados del formulario se puedan almacenar, para poder recuperarse más adelante.
Os dejamos el código completo.
<html>
<head>
<title>Ejemplos de uso de la función data() y removeData() del core de jQuery</title>
</head>
<body>
<h1>Ejemplo data() con enlaces</h1>
<form id="formul">
<p>
<label for="name">Nombre:</label>
<input type="text" id="name" name="name" value="Miguel">
</p>
<p>
<label for="surname">Apellidos:</label>
<input type="text" id="surname" name="surname" value="Alvarez">
</p>
<p>
<label for="sex">Sexo:</label>
<select id="sex" name="sex">
<option value="h" selected>Hombre</option>
<option value="m">Mujer</option>
</select>
</p>
</form>
<p>
<button id="guardar">Guardar estado</button>
<button id="restaurar">Restaurar estado</button>
<button id="eliminar">Borrar</button>
</p>
<div id="mensaje">
Mensaje...
</div>
<script src="../../js/jquery-3.6.3.js"></script>
<script>
$(document).ready(function () {
let formulario = $("#formul");
let mensaje = $("#mensaje");
$("#guardar").click(function (evento) {
let dataObject = {
name: $('#name', formulario).prop('value'),
surname: $('#surname', formulario).prop('value'),
sex: $('#sex', formulario).prop('value'),
}
formulario.data("estado", dataObject);
mensaje.html('He guardado el estado actual del formulario: ');
});
$("#restaurar").click(function (evento) {
let estado = formulario.data('estado');
if(estado) {
for(let index in estado) {
let valor = estado[index];
if(valor) {
$('#' + index).prop('value', estado[index]);
}
}
mensaje.html('He restaurado el valor del formulario guardado');
} else {
mensaje.html('No hay datos almacenados');
}
});
$("#eliminar").click(function (evento) {
formulario.removeData("estado");
mensaje.html('Hemos borrado cualquier dato guardado anteriormente');
});
});
</script>
</body>
</html>
Conclusión
Creo que hemos visto ejemplos suficientes de data() y removeData() con los que podrás aprender no solo el uso de estos métodos, sino también situaciones en los que los podrías aplicar. Puede que ahora no se les encuentre mucha utilidad, pero nos servirán para resolver problemas futuros y entender cómo funcionan diversos plugins o componentes más avanzados de jQuery.
Más adelante en el manual sin duda echaremos mano de estos métodos para desempeñar otros ejemplos.
Por lo que respecta al Core de jQuery, ya hemos visto diversas funcionalidades en desarrolloweb.com en artículos de este manual. Por ahora lo vamos a dejar por aquí, aunque hay diversos métodos del Core que no hemos llegado a ver. En los próximos artículos pasaremos página y comenzaremos a ver otros temas interesantes que nos permitirán explotar un poco más nuestra creatividad, poniendo en marcha utilidades más cercanas a lo que pueden ser nuestras necesidades del día a día.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...