I'm building a shopping cart using javascript and html with the goal of merging this into a database after more progress. I have the following HTML for radio buttons:
<!--------------------------------HTML START---------------------------------->
<div class="shop-item">
<span class="shop-item-title">Steak</span>
<div class="shop-item-details">
<span class="shop-item-price">$12.99</span>
<button class="modalbtn-primary shop-item-button-header" type="button" data-modal-target="#modal">ADD TO CART</button> <!--btn btn-primary shop-item-button--->
<div class="modal" id="modal">
<div class="title">How would you like it cooked?
<div class="shop-items">
<div class="shop-item">
<div data-toggle="buttons">
<div class="row">
<input type="radio" class="shop-item-temp" id="temp" name = "temp" value="Wrong">Rare
<input type="radio" class="shop-item-temp" id="temp" name = "temp" value="Medium Rare">Medium Rare
<input type="radio" class="shop-item-temp" id="temp" name = "temp" value="Medium" checked>Medium
<input type="radio" class="shop-item-temp" id="temp" name = "temp" value="Medium Well">Medium Well
<input type="radio" class="shop-item-temp" id="temp" name = "temp" value="Well">Well
</div>
</div>
<!--------------------------------HTML END---------------------------------->
//Then I have the following Javascript to try to get the values
//start javascript for click event to add items to cart. Popup for selecting temperature of meat
function addToCartClicked(event) {
var button = event.target
var shopItem = button.parentElement.parentElement
var title = shopItem.getElementsByClassName('shop-item-title')[0].innerText
//var temp = shopItem.getElementsByClassName('shop-item-temp')[0].checked -- this works but only adds the 1st value Rare
document.getElementById('temp').innerHTML = "";
var temp = document.getElementsByTagName("input");
for(i = 0; i < temp.length; i++) {
if(temp[i].type="radio") {
if(temp[i].checked)
document.getElementById("temp").innerHTML
+= temp[i].name +
+ temp[i].value + "<br>";
}
}
var price = shopItem.getElementsByClassName('shop-item-price')[0].innerText
addItemToCart(title,temp, price)
updateCartTotal()
}
function addItemToCart(title, temp, price) {//temp, , , imageSrc
var cartRow = document.createElement('div')
cartRow.classList.add('cart-row')
var cartItems = document.getElementsByClassName('cart-items')[0]
var cartItemNames = cartItems.getElementsByClassName('cart-item-title')
for (var i = 0; i < cartItemNames.length; i++) {
if (cartItemNames[i].innerText == title) {
alert('This item is already added to the cart')
return
}
}
//end javascript
I get the Steak, price and quantity but I get [object HTMLCollection] instead of the temperature of the steak.
Any help would be appreciated. Thanks!
The "temperature" is the attribute "value" of your radio items.
<input type="radio" class="shop-item-temp" id="temp" name = "temp" value="Medium Rare">Medium Rare
Right after checking that the attribute is "checked" if (temp[i].checked) you can have your temperature like this:
temperature = temp[i].getAttribute("value");
Extra remark, on my code I would prefer using forEach for this kind of for loop.
Related
I'm working on a TO DO List.
here's the HTML body-
<div class="cardDiv">
<input type="text" class="titleText" placeholder="Today's Battle Plans🤠">
<div class="taskList">
<div class="indiv-task task1">
<input type="checkbox" class="checkBox">
<input type="text" class="textBox" placeholder="task1">
</div>
</div>
<button class="addTask-btn" onclick="addTask()">Add More Tasks</button>
</div>
<script src="index.js"></script>
Basically, the button at the end adds a code block for a new task each time the button gets pressed as per this JS code-
let taskList = document.querySelector(".taskList");
let taskCode = '<div class="indiv-task"> <input type="checkbox" class="checkBox"> <input type="text" class="textBox" placeholder="task1"> </div>';
function addTask() {
taskList.innerHTML += taskCode;
let taskListLength = document.querySelectorAll(".indiv-task").length;
for(i=0; i<taskListLength; i++) {
document.querySelectorAll(".textBox")[i].placeholder = "task"+(i+1);
document.querySelectorAll(".indiv-task")[i].classList.add("task"+(i+1));
}
}
But the problem is that whenever the button is pressed all the input text in textBox(es) gets erased. Is there a way I can avoid that, or is it possible only with databases?
PS- I'm still on my learning path...
Like what epascarello said we need to create an element and add it to the taskList element and not use innerHTML to add elements.
let taskList = document.querySelector(".taskList");
let taskHTML = '<input type="checkbox" class="checkBox"> <input type="text" class="textBox" placeholder="task1">';
function addTask() {
let taskCode = document.createElement("DIV");
taskCode.innerHTML = taskHTML;
taskCode.classList.add("indiv-task")
taskList.appendChild(taskCode)
let taskListLength = document.querySelectorAll(".indiv-task").length;
for(i=0; i<taskListLength; i++) {
document.querySelectorAll(".textBox")[i].placeholder = "task"+(i+1);
document.querySelectorAll(".indiv-task")[i].classList.add("task"+(i+1));
}
}
This means that the innerHTML for the taskList element is not reset to have empty text boxes, rather, it just adds another element.
This is because the innerHTML will replace the current html of the element. You can try with:
function addTask() {
const taskList = document.querySelector(".taskList");
const taskCode = '<div class="indiv-task"> <input type="checkbox" class="checkBox"> <input type="text" class="textBox" placeholder="task1"> </div>';
const taskCodeDocument = new DOMParser().parseFromString(taskCode, "text/html");
const taskCodeChild = taskCodeDocument.body.firstChild;
taskList.appendChild(taskCodeChild);
let taskListLength = document.querySelectorAll(".indiv-task").length;
for (i = 0; i < taskListLength; i++) {
document.querySelectorAll(".textBox")[i].placeholder = "task" + (i + 1);
document.querySelectorAll(".indiv-task")[i].classList.add("task" + (i + 1));
}
}
ref: https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
& https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
let addonCheckboxes = document.querySelectorAll(".custom-checkbox")
let priceSection = document.getElementById("priceSection")
let customProductPricing = document.getElementById("customProductPricing")
for (let i = 0; i < addonCheckboxes.length; i++) {
addonCheckboxes[i].addEventListener("change", function() {
if (addonCheckboxes[i].checked != false) {
priceSection.textContent = parseInt(customProductPricing) + parseInt(addonCheckboxes[i].getAttribute("price"));
} else {
priceSection.textContent = parseInt(customProductPricing)
}
})
}
<input class="custom-checkbox" type="checkbox" price="150"></input>
<input class="custom-checkbox" type="checkbox" price="150"></input>
<input class="custom-checkbox" type="checkbox" price="150"></input>
<div id="priceSection">
</id>
<div id="customProductPricing">"150"</div>
I want to get the total of all the checkboxes if they are all checked. So far it gives only one value. And need to deduct the prices if the checkbox is unchecked.
This one has fixed all the errors you made in your markup, and simplified the code by alot.
const output = document.getElementById('priceSection');
const totalPrice = () => [...document.querySelectorAll('#prices input[type=checkbox]:checked')]
.reduce((acc, {
dataset: {
price
}
}) => acc + +price, 0);
document.getElementById('prices').addEventListener('change', () => output.textContent = totalPrice());
<div id="prices">
<input type="checkbox" data-price="10" />
<input type="checkbox" data-price="20" />
<input type="checkbox" data-price="30" />
</div>
<div id="priceSection"></div>
You are overwriting instead of summing. When you are iterating through an array of checkboxes and you find that more than one is checked your function fails.
You should firstly count the sum of checked checkboxes and then send it to priceSection, and when your sum is equal to zero you should set it parseInt(customProductPricing) like you did in else.
When the change event of the <input> elements is triggered, the update() method is called and the values in the page are collected and printed on the page. I don't understand the issue of lowering the price if the checkbox is not selected. Update the update() method to subtract unselected values from the total using the following approach; Add an else statement to the if block.
(function() {
let addonCheckboxes = document.querySelectorAll(".custom-checkbox");
function update()
{
let total = parseInt(document.getElementById("customProductPricing").textContent);
for(let i = 0 ; i < addonCheckboxes.length ; ++i)
if(addonCheckboxes[i].checked == true)
total += parseInt(addonCheckboxes[i].value);
document.getElementById("priceSection").innerHTML = "Result: " + total;
}
for(let i = 0 ; i < addonCheckboxes.length ; ++i)
addonCheckboxes[i].addEventListener("change", update);
})();
<input class="custom-checkbox" type="checkbox" value="10"/>
<label>10</label>
<input class="custom-checkbox" type="checkbox" value="20"/>
<label>20<label>
<input class="custom-checkbox" type="checkbox" value="30"/>
<label>30<label>
<!-- Static Value -->
<div id="customProductPricing">40</div>
<br><div id="priceSection" style="color: red;">Result: </div>
Using data set you can access price
let addonCheckboxes = document.querySelectorAll(".custom-checkbox")
let priceSection = document.getElementById("priceSection")
let customProductPricing = document.getElementById("customProductPricing")
let sum = 0
for (let i = 0; i < addonCheckboxes.length; i++) {
addonCheckboxes[i].addEventListener("change", function(e) {
console.log(e.target.dataset.price)
if (addonCheckboxes[i].checked != false) {
sum = sum +Number(e.target.dataset.price)
} else {
sum = sum -Number(e.target.dataset.price)
}
customProductPricing.innerHTML = sum
})
}
<input class="custom-checkbox" type="checkbox" data-price="150"></input>
<input class="custom-checkbox" type="checkbox" data-price="150"></input>
<input class="custom-checkbox" type="checkbox" data-price="150"></input>
<div id="priceSection">
</id>
<div id="customProductPricing">"150"</div>
As #Sercan has mentioned... I am also not sure about the issue of loweing the sum but I've whipped up something for you.
Hopefully it'll lead you to what you want to achieve.
let addonCheckboxes = document.querySelectorAll(".custom-checkbox")
let priceSection = document.getElementById("priceSection")
let customProductPricing = document.getElementById("customProductPricing");
var checkboxes = document.getElementsByClassName("custom-checkbox");
function sum(){
var total = 0;
for(let x = 0; x < checkboxes.length; x++){
let price = document.getElementsByClassName(x);
if(price[0].checked){
total = total + Number(price[0].dataset.price);
}
}
console.log('Sum = ' + total)
}
<input class="custom-checkbox 0" onclick="sum()" type="checkbox" data-price="150"></input>
<input class="custom-checkbox 1" onclick="sum()" type="checkbox" data-price="150"></input>
<input class="custom-checkbox 2" onclick="sum()" type="checkbox" data-price="150"></input>
<div id="priceSection"></id>
<div id="customProductPricing">"150"</div>
I've built a small game using checkboxes with images. When the user comes across the item in the picture they select the checkbox and the message changes on screen. Because this is a tourist guide website and game, the user will leave the page to look at other pages, selecting the pictures as they come across the item. Therefore I needed to save the checked boxes in localstorage so that the data persists. I have some javascript that dsave the checked boxes.
Each picture has a value and when the image is clicked it adds to an overall total. I can't get this total to persist if the page is refreshed or closed and reopened.
My javascript for calculating the total and storing the checkboxes is below.
$('.dp-spotter-switch input[type="checkbox"]').click(function () {
if (!$(this).is(':checked')) {
$(this).parent('.dp-spotter-switch').removeClass('spotter-scale');
} else {
$(this).parent('.dp-spotter-switch').addClass('spotter-scale');
}
});
function showDiv() {
document.getElementById('getScoreLabel').style.display = "block";
}
// Total values
function totalIt() {
var input = document.getElementsByName("product");
var total = 0;
for (var i = 0; i < input.length; i++) {
if (input[i].checked) {
total += parseFloat(input[i].value);
}
}
document.getElementById("total").value = "" + total.toFixed(0);
}
// Store checkbox state
(function () {
var boxes = document.querySelectorAll("input[type='checkbox']");
for (var i = 0; i < boxes.length; i++) {
var box = boxes[i];
if (box.hasAttribute("store")) {
setupBox(box);
}
}
function setupBox(box) {
var storageId = box.getAttribute("store");
var oldVal = localStorage.getItem(storageId);
console.log(oldVal);
box.checked = oldVal === "true" ? true : false;
box.addEventListener("change", function () {
localStorage.setItem(storageId, this.checked);
});
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="dp-spotter-container">
<div class="dp-top-paragraph">
<p>Some text</p>
<p>Click on the photos once you have spotted, and at the end click on <strong>Get Your Score</strong> to see how you've done</p>
<div id="getScoreLabel" style="display:none; text-align: center;">
<div class="dp-your-score-text" id="getScore">Your Score</div>
<input value="0" readonly="readonly" type="text" id="total" class="dp-scores dp-floating"/>
</div>
</div>
<br/>
<br/>
<!-- Spotter 1 -->
<div class="dp-switch-container">
<label class="dp-spotter-switch">
<img class="dp-spotter-img" src="image.jpg">
<input type="checkbox" name="product" value="3" id="cb1" class="spotter-check" onclick="totalIt()" store="checkbox1">
<span class="dp-spotter-slider"></span>
<span class="dp-spotter-text-label">Item 1- 3 Points</span>
</label>
</div>
<!-- Spotter 2 -->
<div class="dp-switch-container">
<label class="dp-spotter-switch">
<img class="dp-spotter-img" src="image.jpg">
<input type="checkbox" name="product" value="3" id="cb2" class="spotter-check" onclick="totalIt()" store="checkbox2">
<span class="dp-spotter-slider"></span>
<p class="dp-spotter-text-label">Item 2 - 3 Points</p>
</label>
</div>
<!-- Spotter 3 -->
<div class="dp-switch-container">
<label class="dp-spotter-switch">
<img class="dp-spotter-img" src="image.jpg">
<input type="checkbox" name="product" value="5" id="cb3" class="spotter-check" onclick="totalIt()" store="checkbox3">
<span class="dp-spotter-slider"></span>
<p class="dp-spotter-text-label">ITem 3 - 5 Points</p>
</label>
</div>
<!-- Spotter 4 -->
<div class="dp-switch-container">
<label class="dp-spotter-switch">
<img class="dp-spotter-img" src="image.jpg">
<input type="checkbox" name="product" value="10" id="cb4ß" class="spotter-check" onclick="totalIt()" store="checkbox4">
<span class="dp-spotter-slider"></span>
<p class="dp-spotter-text-label">Item 4 - 10 Points</p>
</label>
</div>
Get Your Score
</div>
I'm looking for a way to add to the existing function for the checkboxes if possible.
Unfortunately we can't use local storage in StackOverflow runnable code snippets, so you'll have to head over to my repl.it to see this working in action.
Since you're using jQuery, I've gone ahead and provided a jQuery solution:
Used .attr() to set the checkbox based on local storage
Called totalIt when showing showDiv
If you want to use your existing code, just change box.checked = oldVal === "true" ? true : false; to box.setAttribute('checked', oldVal === "true" ? true : false) and add totalIt to your showDiv function
Demo
https://repl.it/#AnonymousSB/SO53500148
Solution
function showDiv() {
totalIt();
document.getElementById('getScoreLabel').style.display = "block";
}
// Total values
function totalIt() {
var input = document.getElementsByName("product");
var total = 0;
for (var i = 0; i < input.length; i++) {
if (input[i].checked) {
total += parseFloat(input[i].value);
}
}
document.getElementById("total").value = "" + total.toFixed(0);
}
// Store checkbox state
function setupBox(box) {
var storageId = box.attr("store");
var oldVal = localStorage.getItem(storageId);
box.attr('checked', oldVal === "true" ? true : false)
box.change(function() {
localStorage.setItem(storageId, this.checked);
});
}
$(document).ready(function () {
$( "input[type='checkbox'][store]" ).each(function( index ) {
setupBox($( this ));
});
})
You can open Chrome Dev Tools, go to Application, and see your local storage
I am trying to sum or subtract price into total price as you can see in below working script. Following script is working properly but I want to minus previous clicked radio price from total price.
Suppose If i clicked on Wrap which price is 3 so total price become 8. But when i clicked on any other radio button the Wrap price should minus from total. For that task i tried a lot and looking for solution. Is there any way to store previous clicked price? I would like to thanks if someone guide me.
$('.SECOND_POP_PRICE').on('click', function() {
if ($(this).is(':checked')) {
var PRICE_Product_ID = $(this).parent().attr('data-product_id');
var SECOND_SECTION_PRICE = parseFloat($(this).parent().attr('data-second_section_price'));
var SECOND_SECTION_POP_PRICE = parseFloat($('#pop_price_' + PRICE_Product_ID).text());
if (SECOND_SECTION_PRICE != 0) {
var SECOND_SECTION_UPDATED_PRICE = +SECOND_SECTION_PRICE + +SECOND_SECTION_POP_PRICE;
$('#pop_price_' + PRICE_Product_ID).text(SECOND_SECTION_UPDATED_PRICE);
}
} // if checkbox is checked
/* if($(this).prop('checked')==false){ */
else {
var PRICE_Product_ID = $(this).parent().attr('data-product_id');
var SECOND_SECTION_PRICE = parseFloat($(this).parent().attr('data-second_section_price'));
var SECOND_SECTION_POP_PRICE = parseFloat($('#pop_price_' + PRICE_Product_ID).text());
if (SECOND_SECTION_PRICE != 0) {
var SECOND_SECTION_UPDATED_PRICE = parseFloat(SECOND_SECTION_POP_PRICE - SECOND_SECTION_PRICE);
$('#pop_price_' + PRICE_Product_ID).text(SECOND_SECTION_UPDATED_PRICE);
}
} // if checkbox is un-checked
}); /* END PRICE OF SECOND SECTION 1 */
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<small class="pop_price"><span id="pop_price_2">5</span> AED</small>
<br />
<label data-product_id="2" data-second_section_price="3.00">
<input type="radio" class=" toggle_section_3 SECOND_POP_PRICE" name="section_two" value="Wrap">
Wrap (3.00 AED)</label>
<label data-product_id="2" data-second_section_price="4.00">
<input type="radio" class=" toggle_section_3 SECOND_POP_PRICE" name="section_two" value="Roll">
Roll (4.00 AED)</label>
<label data-product_id="2" data-second_section_price="5.00">
<input type="radio" class="hide_section_3 toggle_section_3 SECOND_POP_PRICE" name="section_two" value="Open">
Open (5.00 AED)</label>
Don't add the clicked radio button to the total. Add it to the base price, which is stored somewhere other than the text of the span that you display the total in. In my code below I put it in the data-price attribute of the span.
There's also no need for the if, since you can't uncheck a radio button.
$('.SECOND_POP_PRICE').on('click', function() {
var PRICE_Product_ID = $(this).parent().attr('data-product_id');
var SECOND_SECTION_PRICE = parseFloat($(this).parent().attr('data-second_section_price'));
var SECOND_SECTION_POP_PRICE = parseFloat($('#pop_price_' + PRICE_Product_ID).data("price"));
if (SECOND_SECTION_PRICE != 0) {
var SECOND_SECTION_UPDATED_PRICE = +SECOND_SECTION_PRICE + +SECOND_SECTION_POP_PRICE;
$('#pop_price_' + PRICE_Product_ID).text(SECOND_SECTION_UPDATED_PRICE);
}
}); /* END PRICE OF SECOND SECTION 1 */
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<small class="pop_price"><span id="pop_price_2" data-price="5.00">5</span> AED</small>
<br />
<label data-product_id="2" data-second_section_price="3.00">
<input type="radio" class=" toggle_section_3 SECOND_POP_PRICE" name="section_two" value="Wrap">
Wrap (3.00 AED)</label>
<label data-product_id="2" data-second_section_price="4.00">
<input type="radio" class=" toggle_section_3 SECOND_POP_PRICE" name="section_two" value="Roll">
Roll (4.00 AED)</label>
<label data-product_id="2" data-second_section_price="5.00">
<input type="radio" class="hide_section_3 toggle_section_3 SECOND_POP_PRICE" name="section_two" value="Open">
Open (5.00 AED)</label>
// here that refers to the context which is you can use to store the last value, you need to find out that context
$('.SECOND_POP_PRICE').on('change',function(event,that){
var updatedValue = that.lastValue - this.value;
$('#pop_price_'+PRICE_Product_ID).text(updatedValue);
that.lastValue = updatedValue
})
I recently changed my code to make it more responsive and as such messed up my jQuery code to record correct vs incorrect answers to a small quiz. The javascript that I posted below used to work just fine when the question was located in an HTML form tag. How can I modify the jQuery code in the second line (where the 'answer1' variable is declared) to work properly now that a form tag no longer surrounds my question? Thanks very much.
HTML
<div class="intro-header2">
<div class="container">
<h1>The capital of Croatia is ...</h1>
<p> </p>
<div class="radio" style="margin-top: 0px;">
<label><input type="radio" name="capital" value="zagreb" id="zagrebID"> Zagreb</label>
</div>
<div class="radio" style="margin-top: 10px;">
<label><input type="radio" name="capital" value="debrovnik"> Debrovnik</label>
</div>
<div class="radio" style="margin-top: 10px;">
<label><input type="radio" name="capital" value="makarska"> Makarska</label>
</div>
<div class="radio" style="margin-top: 10px;">
<label><input type="radio" name="capital" value="moscow"> Moscow</label>
</div>
<div class="radio" style="margin-top: 20px;">
<input type="button" class="btn btn-info" value=" Next " id="NextID">
</div>
</div> <!--/.container-->
</div> <!--/.intro-header2-->
JS
$("#NextID").click(function(){
var answer1 = ($('input[name=capital]:checked', '#myForm').val());
if (answer1 == "zagreb") {
var QuestionNumber = "Question 1, The capital of Croatia.";
var QuizDesc = "Quiz questions on the country of Croatia.";
var name = localStorage.getItem('name');
var email = localStorage.getItem('email');
//pulls the current counter from local storage
var counter = localStorage.getItem('counter');
//adds one to it
var counter = parseInt(localStorage.getItem('counter')) + 1;
//updates the global variable for counter
setCounter(counter);
passedQues(email, name, QuestionNumber, QuizDesc);
document.location.replace("page3.html");
}
else if (!$("input[name='capital']:checked").val()) {
alert('Nothing is checked!');
return false;
}
else {
var QuestionNumber = "Question 1, The capital of Croatia.";
var QuizDesc = "Quiz questions on the country of Croatia.";
var name = localStorage.getItem('name');
var email = localStorage.getItem('email');
//pulls the current counter from local storage
var counter = localStorage.getItem('counter');
//adds one to it
var counter = parseInt(localStorage.getItem('counter')) + 0;
//updates the global variable for counter
setCounter(counter);
failedQues(email, name, QuestionNumber, QuizDesc);
document.location.replace("page3.html");
}
});
You no longer have the form element, and I assume that it has an id attribute with the value myForm
This line looks for the value of an input inside a an element with id myForm
var answer1 = ($('input[name=capital]:checked', '#myForm').val());
This element no longer exists, so the input value is not found. Try changing this line to:
var answer1 = ($('input[name=capital]:checked').val());