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 =...