Ordenar elementos con SortableJS y guardar el orden en localStorage
Hace bien poco he estado hablando de lo hermoso que es encontrarse con herramientas como SortableJS, una extensión de JavaScript que vas a poder utilizar en tus desarrollos para ofrecer a tus ususarios la posibilidad de arrastrar y soltar elementos con el objetivo de cambiarlos de posición.
Para saber que es SortableJS y como poder empezar, puedes ver el siguiente tutorial:
En este artículo vas a descubrir como arrastrar y soltar elementos para posicionarlos en otro lugar y que las nuevas posiciones de los elementos queden registradas en localStorage para una próxima sesión.
El objeto localStorage te permite almacenar datos de manera local en el navegador del usuario sin necesidad de realizar una conexión a una base de datos.
Lista de elementos a ordenar
En el ejemplo en funcionamiento estoy usando una lista de tarjetas de Bootstrap para darles a cada elemento un aspecto agradable, rápido y diferente.
En el cuerpo de la página o dentro del <body> puedes incluir el código HTML de los elementos que voy a ordenar:
<div class="row sortable">
<div class="col-lg-3" data-id="1">
<div class="card text-white bg-primary mb-3" style="max-width: 18rem;">
<div class="card-header">Header</div>
<div class="card-body">
<h5 class="card-title">Primary card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
</div>
</div>
<div class="col-lg-3" data-id="2">
<div class="card text-white bg-secondary mb-3" style="max-width: 18rem;">
<div class="card-header">Header</div>
<div class="card-body">
<h5 class="card-title">Secondary card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
</div>
</div>
<div class="col-lg-3" data-id="3">
<div class="card text-white bg-success mb-3" style="max-width: 18rem;">
<div class="card-header">Header</div>
<div class="card-body">
<h5 class="card-title">Success card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
</div>
</div>
<div class="col-lg-3" data-id="4">
<div class="card text-white bg-danger mb-3" style="max-width: 18rem;">
<div class="card-header">Header</div>
<div class="card-body">
<h5 class="card-title">Danger card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
</div>
</div>
<div class="col-lg-3" data-id="5">
<div class="card text-white bg-warning mb-3" style="max-width: 18rem;">
<div class="card-header">Header</div>
<div class="card-body">
<h5 class="card-title">Warning card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
</div>
</div>
<div class="col-lg-3" data-id="6">
<div class="card text-white bg-info mb-3" style="max-width: 18rem;">
<div class="card-header">Header</div>
<div class="card-body">
<h5 class="card-title">Info card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
</div>
</div>
<div class="col-lg-3" data-id="7">
<div class="card bg-light mb-3" style="max-width: 18rem;">
<div class="card-header">Header</div>
<div class="card-body">
<h5 class="card-title">Light card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
</div>
</div>
<div class="col-lg-3" data-id="8">
<div class="card text-white bg-dark mb-3" style="max-width: 18rem;">
<div class="card-header">Header</div>
<div class="card-body">
<h5 class="card-title">Dark card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
</div>
</div>
</div>
Sobre este código debes prestar especial atención a que cada elemento o tarjeta tiene un identificador o el atributo data-id que será el que utilizaremos para guardarlo en una lista ordenada en localStorage.
Inclusión del objeto SortableJS
Antes de la etiqueta de cierre del <body> puedes agregar el script:
Estoy utilizando la opción CDN para ir rápido pero tu podrías ir a la página oficial de SortableJS para descargar y depositar los archivos en tu proyecto.
Creación del objeto SortableJS
A continuación, también antes de la etiqueta de cierre del <body> pero después de la inclusión de la clase SortableJS debes crear la instancia del objeto con el que vas a trabajar.
Fíjate a continuación:
<script>
var items = document.querySelector('.sortable');
Sortable.create(items, {
animation: 150,
chosenClass: "seleccionado",
ghostClass: "fantasma",
dragClass: "drag",
onEnd: () => {
console.log('se insertó un elemento');
},
group: "cards",
store: {
set:(sortable) => {
const orden = sortable.toArray();
localStorage.setItem(sortable.options.group.name, orden.join('|'));
},
//obtener orden de la lista
get: (sortable) => {
const orden = localStorage.getItem(sortable.options.group.name);
return orden ? orden.split('|') : [];
}
}
});
</script>
Con querySelector selecciono el contenedor que contiene los elementos que tendrán este comportamiento y luego paso el elemento como primer parámetro de la función Sortable.create().
En el segundo parámetro de esta función puedes definir las opciones.
En el caso del ejemplo:
- Defino una animación estableciendo una duración de 150ms.
- Establezco la clase «chosen» para personalizar mediante CSS como será el aspecto del elemento seleccionado.
- Declaro la clase «ghost» para personalizar mediante CSS el elemento fantasma.
- Defino la clase «drag» para personalizar mediante CSS el elemento arrastrado.
- Uso la función onEnd() para mostrar un mensaje en consola.
Parámetros de SortableJS para guardar en localStorage
Definir el group de SortableJS es clave para poder guardarlo. En el caso del ejemplo, le he puesto el nombre de «cards».
SortableJS tiene un objeto Store que permite guardar el estado de los elementos ordenables.
Utilizo la función set() para obtener el array de elementos o tarjetas y guardarlo en localStorage con setItem().
Esta función setItem() tiene 2 parámetros:
- El nombre del grupo de elementos. En este caso, sería lo mismo poner «cards».
- Cadena con los identificadores de los elementos separados por el símbolo «|».
Para recuperar el orden de la lista se puede emplear la función get() del objeto Store pasándole como argumento el objeto sortable.
Con la función getItem() de localStorage recupero la lista de elementos ordenados y lo retorno como un array.
Conclusiones
Como podrás observar es bastante sencillo y rápido guardar los elementos ordenados de la lista en localStorage.
Guardar información en localStorage puede ser muy útil cuando necesitas guardar pequeñas informaciones del usuario para mantenerlas activas mientras navega por el sitio web.
Para guardar el orden de una lista con JavaScript puede ser de gran utilidad.
Sin embargo, quizás estás más bien acostumbrado a guardar los registros en la base de datos.
Pronto publicaré una nueva entrada para que veas como sería guardar los movimientos de SortableJS y guardarlos en una base de datos. Estate atento a las novedades.
Espero tambien ese tutorial!
Gran aporte! ¿Subirás el ejemplo para guardarlo en base de datos? Seria de gran utilidad para mi
Tomo nota para crear un ejemplo igual pero guardando en base de datos ajax y php