multiselect
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>multiSelect.js example</title>
<!-- you can add this style for hide the selects in first load -->
<style>
[multiSelect] [parent]{
display: none;
}
</style>
</head>
<body>
<h1>multiSelect.js example</h1>
<p>This is a sample of how multiSelect.js works by a mechanic workshop example</p>
<!-- ==================== HTML ===================== -->
<!-- multiSelect container, in this case a <form/> -->
<form multiSelect onsubmit="return false">
<div>
<label>email</label>
<input name="email" type="email" />
</div>
<!-- this is a fixed <select/> container, you don't need a 'parent' attribute -->
<div visibleId="myFixedSelect">
<label>select a service</label>
<select name="serviceChoice">
<option value="nothingHere">please select a option</option>
<option makeVisible="fix-selection" value="fix">fix vehicle</option>
<option makeVisible="buy-parts" value="buy">buy car parts</option>
</select>
</div>
<!-- parent container -->
<!-- this container have all the first <select/> child <options/> -->
<!-- the 'parent' attribute has the parent visibleId value -->
<div parent="myFixedSelect">
<!-- the visibleId is the corresponding 'makeVisible' <option/> -->
<div visibleId="fix-selection"> <!-- first <option/> child from 'myFixedSelect' -->
<label>fix service</label>
<select name="fixChoice">
<option value="nothingHere">please select a fix service</option>
<option makeVisible="engines-selection" value="fix-engine">fix my car engine</option>
<option makeVisible="paint-selection" value="fix-paint">fix my car paint</option>
</select>
</div>
<!-- sub <select/> container of 'fix-selection' -->
<!-- the 'parent' attribute has the parent visibleId value -->
<div parent="fix-selection">
<!-- the visibleId is the corresponding 'makeVisible' <option/> -->
<div visibleId="engines-selection"> <!-- first...
CSS
body {
background: white;
color: rgb(5, 5, 5);
font-weight: 300;
/* height: 100vh; */
margin: 0;
display: flex;
padding: 20px;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
font-family: Helvetica neue, roboto;
}
img {
width: 56px;
height: 48px;
}
h1 {
font-weight: 200;
font-style: 26px;
margin: 10px;
}
form{
padding: 30px;
display: flex;
flex-direction: column;
border: 3px solid black;
border-radius: 7px;
background: #dadada;
}
form div{
display: flex;
flex-direction: column;
text-align: left;
margin-bottom: 12px;
}
label{
font-size: 16px;
font-weight: bold;
font-family: arial;
text-align: left;
}
select{
padding: 5px;
}
input{
padding: 5px;
}
button{
padding: 5px;
border-radius: 8px;
outline: none;
border: 2px solid black;
margin-top: 12px;
font-weight: bold;
font-family: arial;
background: royalblue;
}
JavaScript
/*
* MultiSelect.js
* A small library to manage multiple select tags in forms
*
* Carlos MartĂnez 2019
* my github: https://github.com/carlosEdua
*
* repo code: https://github.com/carlosEdua/multiSelect.js
* License: ( MIT ) https://github.com/carlosEdua/multiSelect.js/blob/master/LICENSE
*
* You can modify the code and make it better, send me a pull request
*/
class MultiSelect{
constructor({ pleaseSelectOptionValue = '' }){
// get the multiSelect container
this.multiSelectContainer = document.querySelector('[multiSelect]');
// the tipical <option value=""> please select a option <option/>
this.pleaseSelectOptionValue = pleaseSelectOptionValue;
// get all the posible inputs in a <form/> tag
this.allInputs = [...this.multiSelectContainer.querySelectorAll('input')];
this.allSelects = [...this.multiSelectContainer.querySelectorAll('select')];
this.allTextArea = [...this.multiSelectContainer.querySelectorAll('textarea')];
// add onchange listener to all <select/>
this.addSelectListeners(this.allSelects);
}
// ========== add listener to <select/> ==========
addSelectListeners(selectHTMLElements){
// agregar eventListener a todos los <select />
selectHTMLElements.map( select => select.addEventListener('change', (ev) => this.showHideIt(ev)) );
}
// ========== show/hide logic ==========
showHideIt(ev){
const { multiSelectContainer, pleaseSelectOptionValue } = this;
const select = ev.target;
const selectValue = select.value;
// if the <option/> is not the "please select a option" with value=""
if(
// check if isn't invalid value
selectValue!== pleaseSelectOptionValue
&&
// check if the parent has a 'visibleId' attribute
select.parentElement.getAttribute('visibleId')
&&
// check if the option has the 'makeVisible' attribute
select.querySelector(`option[value=${selectValue}]`).getAttribute('makeVisible')
){
// get the makeVisible attribute of <option/>
const makeVisible =...