I am creating a very basic shopping cart.
It has dependent drop down menus and a button "Add more products"
which will add one more row of the same drop down menus.
There are 2 drop down menus 2nd menu must remain disabled
until an option is selected in 1st menu. The quantity input must be disabled
until an option is selected in 2nd menu. The Add more products
is enabled quantity is add
I am using cloneNode()
to add code for new row.
Since it works only once I am creating clone each time "Add more products"
button is clicked which calls new_products();
I am using last added row for creating new Clone
The new row gets added but the problem is 2nd menu and quantity input in this row are already enabled
.
Please try giving a solution in Vanilla(pure) JavaScript.
EDIT 1: I have came half way.
Before appending the clone I tried to access those elements and change the disabled
attribute value.
In function new_products()
:
var order = document.getElementById('order_now');
var product = document.getElementsByClassName('product');
var clone = product[no_of_products-1].cloneNode(true);
clone.getElementsByClassName('second_select')[0].disabled=true;
clone.getElementsByClassName('add_btn')[0].disabled=true;
But this only worked for 2nd drop down menu.
It's not working for quantity input
control.
Code snippet:
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"]
}
var valuesByCategory = {
A: ["", "A1", "A2", "A3", "A4"],
B: ["", "B1", "B2", "B3", "B4"],
C: ["", "C1", "C2", "C3", "C4", "C5"],
D: ["", "D1", "D2", "D3"]
}
var no_of_products = 1;
function dropdown() {
var select = document.getElementsByClassName('first_select');
var selected = select[no_of_products - 1].value;
var target = document.getElementsByClassName('second_select');
var targetLength = target[no_of_products - 1].length
/*console.log("Length"+target.length);*/
for (var i = targetLength; i >= 0; i--) {
/*console.log(i);*/
target[no_of_products - 1].remove(i);
}
if (selected == 0) {
var option = document.createElement("option");
option.text = "Select Product first";
option.value = "";
target[no_of_products - 1].add(option);
target[no_of_products - 1].disabled = true;
}
if (selected == 1) {
for (var i in productsByCategory['A']) {
var option = document.createElement("option"); //If this is outside the lopp then only last option gets included.
option.text = productsByCategory['A'][i];
option.value = valuesByCategory['A'][i];
target[no_of_products - 1].add(option);
target[no_of_products - 1].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[no_of_products - 1].add(option);
target[no_of_products - 1].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[no_of_products - 1].add(option);
target[no_of_products - 1].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[no_of_products - 1].add(option);
target[no_of_products - 1].disabled = false;
}
}
}
function dropdown2() {
var select = document.getElementsByClassName('second_select');
var selected = select[no_of_products - 1].value;
/*console.log(selected);*/
var submit = document.getElementsByClassName('s_btn');
submit[no_of_products - 1].disabled = false;
var add = document.getElementById('add_button');
add.disabled = false;
}
function new_products() {
var order = document.getElementById('order_now');
var product = document.getElementsByClassName('product');
var clone = product[no_of_products - 1].cloneNode(true);
clone.getElementsByClassName('second_select')[0].disabled = true;
clone.getElementsByClassName('add_btn')[0].disabled = true;
var add = document.getElementById('add_button');
product[no_of_products - 1].removeChild(add);
/*console.log(clone);*/
order.appendChild(clone);
no_of_products += 1;
}
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;
}
<!DOCTYPE html>
<html>
<head>
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
<link rel="stylesheet" type="text/css" href="profile.css">
<title></title>
</head>
<body>
<div class="content">
<div class="link-contents">
<div class="option-contents" id="order_now">
<div class="product">
<select class="first_select" onchange="dropdown();">
<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" onchange="dropdown2();" disabled>
<option>Select Product first</option>
</select>
<input class="s_btn" type="number" min='1' value="1" disabled />
<br/>
<button class="add_btn" id="add_button" onclick="new_products();" disabled>Add more products</button>
<div id="clear"></div>
</div>
</div>
</div>
<div id="clear"></div>
</div>
<div class="footer">
A big thank you to all of you.
</div>
</body>
<script type="text/javascript" src="profile.js"></script>
</html>
Unfortunately you have to much mistakes in your code. Because of this I will describe only important mistakes:
id
attribute from an element must be unique in a full HTML page. If you clone some element and it has an id attribute then you have to create a new id. And because your wish is to remove id
attribute from the button – so I did it for you.element.disable
to disable an element. The most of browsers support it, but it is not standart. If you see the documentation for Element
and for Node
then you will see that they do not have this property. Some browser would not support it. Use for this case Element.setAttribute()
and Element.removeAttribute()
functions.float: left
if you do not need it. In your case you do not need it because you have inline-block
elements. I have changed a lot of your CSS code too.addEventListener
method instead of inline event listeners, but in your case it is disputable and because of this I do not use addEventListener
– so you can better understand my code. But I add one parameter in your functions – note it.I wrote the new code so that you do not have any type of errors. Enjoy it!
Complete solution
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"]
};
var valuesByCategory =
{
A: ["", "A1", "A2", "A3", "A4"],
B: ["", "B1", "B2", "B3", "B4"],
C: ["", "C1", "C2", "C3", "C4", "C5"],
D: ["", "D1", "D2", "D3"]
};
//var no_of_products = 1; //WE DO NOT NEED IT
function selectHelper(category, targetObj)
{
for(var i in productsByCategory[category])
{
var option = document.createElement("option");
option.text = productsByCategory[category][i];
option.value = valuesByCategory[category][i];
targetObj.add(option);
}
setEnabled(targetObj);
}
function dropdown(obj)
{
var selected = obj.value,
//second select:
target = obj.nextElementSibling;
for(var i = target.length; i--; )
target.remove(i);
if(selected == 0)
{
var option = document.createElement("option");
option.text = "Select Product first";
option.value = "";
target.add(option);
setDisabled(target);
//set disabled input field:
setDisabled(target.nextElementSibling)
}
else
{
if(selected == 1)
selectHelper('A', target);
else if(selected == 2)
selectHelper('B', target);
else if(selected == 3)
selectHelper('C', target);
else
selectHelper('D', target)
}
}
function dropdown2(obj)
{
setEnabled(obj.nextElementSibling);
setEnabled(document.getElementsByClassName('add_btn')[0]);
}
function new_products()
{
var allProducts = document.getElementsByClassName('product');
lastProduct = allProducts[allProducts.length - 1],
clone = lastProduct.cloneNode(true);
setDisabled(clone.getElementsByClassName('second_select')[0]);
//set disabled input field:
setDisabled(clone.getElementsByClassName('s_btn')[0]);
setDisabled(document.getElementsByClassName('add_btn')[0]);
//may be "insertBefore" is weird, but we do here insert new product after the last product:
document.getElementById('order_now').insertBefore(clone, lastProduct.nextSibling);
}
function setDisabled(obj)
{
obj.setAttribute("disabled", "disabled");
}
function setEnabled(obj)
{
obj.removeAttribute("disabled");
}
body
{
height: 100vh;
margin: 0px;
overflow-y: auto;
font-family: 'Roboto';
}
.content
{
background-color: white;
height: auto;
margin-top: 0px;
z-index: -1;
min-height: 88%;
}
.link-contents
{
position: relative;
left: 0px;
width: 100%;
}
.option-links
{
display: block;
font-size: 30px;
cursor: pointer;
}
#op1 {background-color: #cccccc}
select, button, input
{
position: relative;
top: 5em;
width: 12em;
height: 2em;
}
button {width: 8em}
.first_select
{
position: relative;
left: 10%;
}
.second_select
{
position: relative;
left: 20%;
}
.s_btn
{
position: relative;
left: 30%;
}
.add_btn
{
top: 6em;
width: 10em;
}
.footer
{
display: block;
max-height: 4%;
}
.option-contents {display: none}
#order_now {display: block}
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
<link rel="stylesheet" type="text/css" href="profile.css">
<div class="content">
<div class="link-contents">
<div class="option-contents" id="order_now">
<div class="product">
<select class="first_select" onchange="dropdown(this)">
<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" onchange="dropdown2(this)" disabled>
<option>Select Product first</option>
</select>
<input class="s_btn" type="number" min='1' value="1" disabled />
</div>
<center><button class="add_btn" onclick="new_products()" disabled>Add more products</button></center>
</div>
</div>
</div>
<div class="footer">A big thank you to all of you.</div>