Cómo mantener la opción seleccionada en un select tras cargar la página

Imagina que estás utilizando un elemento select para navegar entre páginas. Por regla general, el select volverá a su opción por defecto tras cargar otra vez la página. En este artículo veremos cómo mantener la opción que ha seleccionado el usuario, asegurándonos de que cualquier página que haya escogido el usuario permanezca seleccionada incluso una vez haya aterrizado en la nueva. Para verlo, crearemos un proyecto con algunas páginas estáticas. ¡Empecemos!

Estructura del proyecto

La estructura del proyecto es tal que así: 

animals.html
cars.html
index.html
motorcycles.html
plants.html
assets/   
   css/      
      style.css   
   img/      
      down.svg   
   js/      
      main.js 

El HTML 

Dentro de cada página HTML habrá un elemento select. 

<select class="myselect">
  <option data-url="index.html">All</option>
  <option data-url="animals.html">Animals</option>
  <option data-url="cars.html">Cars</option>
  <option data-url="motorcycles.html">Motorcycles</option>
  <option data-url="plants.html">Plants</option>
</select>

 

Cada opción está asociada a una página estática. El enlace a cada página se almacena en el atributo data-url. 

En un caso real nuestro menú select tendría que contener las categorías de todas las publicciones del blog. Así que imaginemos que, al seleccionar la opción All, aparecen todas las publicaciones del blog. Luego, si seleccionamos la opción Animals, aparecerán las publicaciones que pertenecen a la categoría Animales, y así sucesivamente. 

El atributo data-url podría contener una url absoluta en lugar de una relativa, como esta: 

<option data-url="http://yoursite.com/category/animals">Animals</option>

El CSS 

Por defecto, existen limitaciones en el navegador con respecto a los estilos que podemos aplicar a un elemento select. Con eso en mente, vamos a agregar unas cuantas reglas CSS que mejorarán la apariencia del select en todos los navegadores: 

.myselect {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  width: 100%;
  max-width: 400px;
  padding: 6px 12px;
  border-radius: 4px;
  border: 1px solid #cbd1d8;
  font-size: 1rem;
  line-height: 1.5;
  background: #fff url(../img/down.svg) no-repeat center right 12px / 18px 18px;
  transition: all .2s ease-in-out;
}
 
/*IE*/
.myselect::-ms-expand {
  display: none;
}
 
.myselect:focus {
  outline: 0;
  border-color: #7bbaff;
  box-shadow: 0 0 0 3px rgba(0, 121, 250, .3);
}

 

El JavaScript 

Cada vez que se selecciona una opción, debe cargarse la página relacionada y la opción de destino debe marcarse como seleccionada. Para ello tenemos que hacer lo siguiente:

  • Recuperar la URL de la página relacionada con la opción seleccionada y forzar una redirección a esta página.     
  • Recorrer todas las opciones, tomar su atributo data-url, y comprobar si este valor es parte de la url de la página o no. Si es así, marcamos la opción relacionada como seleccionada y saltamos fuera del bucle. 

Aquí está el código requerido: 

const select = document.querySelector(".myselect");
const options = document.querySelectorAll(".myselect option");
 
// 1
select.addEventListener("change", function() {
  const url = this.options[this.selectedIndex].dataset.url;
  if(url) {
    location.href = url;
  }
});
 
// 2
for(const option of options) {
  const url = option.dataset.url;
  if(location.href.includes(url)) {
    option.setAttribute("selected", "");
    break;
  }
}

 

Como he dicho antes, en un proyecto real, el valor del atributo data-url podría ser una url absoluta. En tal escenario, podemos actualizar la segunda parte de nuestro código de la siguiente manera: 

// 2
for(const option of options) {
  const url = option.dataset.url;
  if(url === location.href) {
    option.setAttribute("selected", "");
    break;
  }
}

 

Ojo, en lugar de agregar el atributo selected a la opción correspondiente a través de JavaScript, podríamos haberlo establecido estáticamente en el HTML. Entonces, por ejemplo, en la página Animals podríamos haber agregado el atributo selected a la opción Animals. Sin embargo, este no es un enfoque flexible porque en un sitio dinámico todas las opciones (que podrían contener categorías de publicaciones) posiblemente compartirán la misma página / plantilla.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP