var productsByCategory = {
A: ["Select sub-product", "CNC 1", "CNC 2", "CNC 3", "CNC 4"],
B: ["Select sub-product", "LASER 1", "LASER 2", "LASER 3", "LASER 4"],
C: ["Select sub-product", "RUBBER 1", "RUBBER 2", "RUBBER 3", "RUBBER 4", "RUBBER 5"],
D: ["Select sub-product", "PRECISION 1", "PRECISION 2", "PRECISION 3"]
},
valuesByCategory = {
A: ["", "A1", "A2", "A3", "A4"],
B: ["", "B1", "B2", "B3", "B4"],
C: ["", "C1", "C2", "C3", "C4", "C5"],
D: ["", "D1", "D2", "D3"]
},
/**
* create a clone element using 'querySelector' method
* which DOESN'T return a 'live node' (it returns a 'static node'), thus gain performance.
**/
clone = document.querySelector('.product').cloneNode(true);
/**
* add event listeners to the body rather than the specific elements
* thus the dynamically created elements are also supported and catchable by the events.
* using some checking to get the desired handler function to be called.
* using the 'call' method, we specify to which element in the handler functions the 'this' keyword refers to.
**/
document.addEventListener('change', function(e) {
(e.target instanceof HTMLSelectElement && ((e.target.classList.contains('first_select') && dropdown.call(e.target)) || (e.target.classList.contains('second_select') && dropdown2.call(e.target))));
/**
* the above code is the same as the next but it's faster.
if (e.target instanceof HTMLSelectElement && e.target.classList.contains('first_select')) {
dropdown.call(e.target)
} else if (e.target instanceof HTMLSelectElement && e.target.classList.contains('second_select')) {
dropdown2.call(e.target)
}
**/
});
document.addEventListener('click', function(e) {
(e.target instanceof HTMLButtonElement && e.target.classList.contains('add_btn') && new_products.call(e.target));
/**
* the above code is the same as the next but it's faster.
if(e.target instanceof HTMLButtonElement && e.target.classList.contains('add_btn')) {
new_products.call(e.target);
}
**/
})
/**
* from now on, the handler function use the 'this' keyword to reference the desired element, even the dynamically created ones are supporyted.
* So, 'this' === the argument that passed to the 'call' method.
**/
function dropdown() {
var selected = this.value;
var target = this.parentNode.getElementsByClassName('second_select')[0];
var targetLength = target.length;
for (var i = targetLength; i >= 0; i--) {
target.remove(i);
}
if (selected == 0) {
var option = document.createElement("option");
option.text = "Select Product first";
option.value = "";
target.add(option);
/**
* you missed to disable the 'button' and the 'input' if the selected value is '0'.
**/
this.parentNode.querySelector('.s_btn').disabled = true;
this.parentNode.querySelector('.add_btn').disabled = true;
target.disabled = true;
} else if (selected == 1) {
for (var i in productsByCategory['A']) {
var option = document.createElement("option");
option.text = productsByCategory['A'][i];
option.value = valuesByCategory['A'][i];
target.add(option);
target.disabled = false;
}
} else if (selected == 2) {
for (var i in productsByCategory['B']) {
var option = document.createElement("option");
option.text = productsByCategory['B'][i];
option.value = valuesByCategory['B'][i];
target.add(option);
target.disabled = false;
}
} else if (selected == 3) {
for (var i in productsByCategory['C']) {
var option = document.createElement("option");
option.text = productsByCategory['C'][i];
option.value = valuesByCategory['C'][i];
target.add(option);
target.disabled = false;
}
} else {
for (var i in productsByCategory['D']) {
var option = document.createElement("option");
option.text = productsByCategory['D'][i];
option.value = valuesByCategory['D'][i];
target.add(option);
target.disabled = false;
}
}
}
function dropdown2() {
this.parentNode.getElementsByClassName('s_btn')[0].disabled = false;
this.parentNode.getElementsByClassName('add_btn')[0].disabled = false;
}
function new_products() {
var order = document.getElementById('order_now'),
/**
* create a 'div' element which will hold the cloned element's 'innerHTML'.
**/
product = document.createElement('div');
/**
* give that 'div' element the 'product' class.
**/
product.className = 'product';
/**
* append that 'div' to the 'div#order_now' element.
* it's now the last child of the 'div#order_now' element.
**/
order.appendChild(product);
/**
* assign the cloned element's 'innerHTML' to the newly created 'div' using the 'lastChild' attribute.
* with that we eliminate the possibility of directly appending the cloned element to 'div#order_now' to run only once.
**/
order.lastChild.innerHTML = clone.innerHTML;
this.parentNode.removeChild(this)
}
body {
height: 100vh;
margin: 0px;
overflow-y: auto;
font-family: 'Roboto';
}
#clear {
clear: both;
}
.content {
display: flex;
background-color: white;
height: auto;
margin-top: 0px;
font-family: 'Roboto';
z-index: -1;
min-height: 88%;
}
.link-contents {
position: relative;
display: block;
float: left;
left: 0px;
width: 100%;
}
.option-links {
display: block;
font-size: 30px;
cursor: pointer;
}
#op1 {
background-color: #cccccc;
}
select,
button,
input {
position: relative;
top: 5em;
display: block;
width: 12em;
height: 2em;
}
button {
width: 8em;
}
.first_select {
position: relative;
float: left;
left: 10%;
}
.second_select {
position: relative;
float: left;
left: 20%;
}
.s_btn {
position: relative;
float: left;
left: 30%;
}
.add_btn {
float: left;
top: 6em;
width: 10em;
left: 5em;
}
.footer {
display: block;
max-height: 4%;
}
.option-contents {
display: none;
}
#order_now {
display: block;
}
select,
input {
display: block !important;
}
<div class="content">
<div class="link-contents">
<div class="option-contents" id="order_now">
<div class="product">
<select class="first_select">
<option value="0">Select</option>
<option value="1">CNS</option>
<option value="2">Laser Cut</option>
<option value="3">Rubber roller</option>
<option value="4">Fixture</option>
</select>
<select class="second_select" disabled>
<option>Select Product first</option>
</select>
<input class="s_btn" type="number" min='1' value="1" disabled />
<br/>
<button type="button" class="add_btn" disabled>Add more products</button>
<div id="clear"></div>
</div>
</div>
</div>
<div id="clear"></div>