I have a page with many checkboxes, each of which are tied to a product with a price. I'm trying to use jQuery to give a real-time readout of the 1) number of products, and 2) total price of the user's selections.
This should be very easy: I would have done something like:
$(input).change( function(){
var sum = $(input:checked).length
var price_total = $(input:checked).length * 1.99
})
The Complication
The element or elements being changed are NOT counted in the above code. It seems that when clicking a blank checkbox to check it, jQuery will consider the current element 'not checked' rather than 'checked', i.e. it reflects the checkbox before the change. As a result, my code gets significantly more complicated to accept the changed items.
Is there an elegant and simple way to get around this?
Not sure if the code you posted is what you're actually running, but among other things, your code is missing quotes in your $ selectors. However, this is working for me:
$(':checkbox').change( function(){
var sum = $(':checked').length;
var price_total = sum*1.99;
})
jsFiddle DEMO
Without out your html i can only guess it.
My solution would be to use a data entity like data-price.
HTML
<input type="checkbox" data-price="1.99" />
<input type="checkbox" data-price="1.95" />
<input type="checkbox" data-price="3.60" />
<input type="checkbox" data-price="2.10" />
<div id="total"></div>
JQuery
$('input').change(function() {
recalcTotal();
});
function recalcTotal() {
var total = 0;
$('input:checked').each(function() {
total += $(this).data('price');
});
$('#total').html(total);
}
fiddle
Note: I made the assumption the price may vary between different products unsure if this would be correct
You can select checked boxes like this:
$(input).change( function(){
var sum = $('input[type=checkbox]:checked').length
var price_total = sum * 1.99
})
I also used your value of sum for the second calculation. Why not - it makes it faster and more readable. And it works.
Related
I would like to calculate the total price of the if check box is checked by using JavaScript
I'm not allow to separate the id to 2 section of by adding div
for example.
<form id="bookingForm">
<section id = "checkcost">
<h2>Total cost</h2>
Total <input type="text" name="total" value="$0.00" size="10" readonly />
</section>
</form>
First, i use this method get the id
var frm = document.getElementById('bookingForm')
i m trying to do by using the following code but this is not the correct method
frm.checkcost.total = calculate()
Since the input area to shows the total cost is inside the id="bookingForm", how should i display the total cost once the check box is checked??
ps: here is the link i had try but it didn't work, and now i'm trying other method
onclick in php echo with error invalid unexpected token
If there's only one field named total in the form, you don't need to worry about the section at all:
var frm = document.getElementById('bookingForm');
frm.total = calculate();
or
document.querySelector("#bookingForm [name=total]").value = calculate();
If you have multiple fields named total, then you just use the ID of the section:
document.querySelector("#checkcost [name=total]").value = calculate();
// ----------------------^
document.querySelector finds the first element that matches a given CSS selector. You can use the full power of CSS to find elements in the document. There's also document.querySelectorAll which finds a list of matching elements. Finally, individual elements also have both methods, which look only within those elements. So for instance, we could also do this:
var frm = document.getElementById('bookingForm');
frm.querySelector("#checkcost [name=total]").value = calculate();
(But that's just an example, not a suggestion; it's more round-about than necessary.)
I am creating a form that will calculate the total of each row of an item.
I have used a piece of javascript already to calculate each row individually but i want to know if i can use .each() to calculate every row with the same classes rather than having a piece of script for each row with a unique ID.
The script should be: (the price in the p element with class "price1")*(value in the input element with class "qty1"). The result needs to go into the input element with the class "total1"
My page is http://www.catering-equipment.co.uk/portal1/
I have created a JSFiddle here --> https://jsfiddle.net/1y7kudtv/4/
$(".qty1").on('keyup', function () {
// alert('pressed')
var total = $(".price1").html() * $(this).val()
$(".total1").val(total);
})
You can see my attempt at the javascript code but it will only work if i use it with unique ID's rather than a class.
Thank you in advance.
Use .closest():
$(this).closest('.itemrow').find('.total1').val(total);
DEMO
Yes, you can do that. Use find to only look for elements in the current selector:
$('.itemrow').each(function() {
var price = $(this).find('.price1').html();
var quantity = $(this).find('.qty1').val();
var total = price * quantity;
$(this).find('.total1').val(total);
});
Also notice that you're dealing with float arithmetics here, so it's better to round the total, to avoid it displaying something like 10.99999999:
var total = (price * quantity).toFixed(2);
I've few similar textboxes. When i run the validation script given below, One of them isn't affected the first time, even though it's empty. I'd like to know why.
Following is the HTML:
<input type='text' class='txt' value="" />
<input type='text' class='txt' value="" />
<input type='text' class='txt' value="" />
<input type='button' onclick='validate()' value='validate' />
JS:
function validate() {
var txts = document.getElementsByClassName('txt');
for (var i = 0; i < txts.length; i++) {
if(txts[i].value === "")
txts[i].className = 'txtError';
}
}
and CSS:
.txt {
border:1 px solid green;
}
.txtError {
border:1 px solid blue;
background:red;
}
This might be a dumb mistakes but i stared at it many times and my eyes isn't catching anything at the moment. I also tried it in different browsers.
Here's a JSfiddle demonstrating the problem.
Side note: i'm not looking for another validation script, i just want to know why the second textbox escapes the validation.
Because getElementsByClassName returns a live collection. Meaning it is updated underneath you as you change the DOM. So when you remove the txt class from the first box (replacing it with txtError you suddenly have an enumerable of size 2 instead of 3.
To fix it you can convert the live collection to a regular array using the array slicing trick
var txts = Array.prototype.slice.call(document.getElementsByClassName('txt'), 0);
However there are better ways to achieve pretty much everything that you're doing here. SO isn't really the place to discuss this but once you get it working go ahead and post it on the codereview stackexchange for feedback.
This seems like a strange issue and I cannot fully explain the issue. But when debugging and stepping though the code, every time you update the classname of one of the elements, your collection of txts decrements. Therefore, this is the only way I can think of to fix it. Basically the same thing you have, but instead I start with the last element of the txts array, instead of the first.
function validate() {
var txts = document.getElementsByClassName('txt');
for (var i = txts.length - 1; i >= 0; i--) {
if (txts[i].value === "") txts[i].className = 'txtError';
}
}
I think the problem arose because you were changing the class entirely instead of just adding a class; at least, it fixed the problem for me.
Here's a jsfiddle I created from yours that works fine by changing the behaviour to something more like jQuery's .addClass() method - I set .className = 'txt txtError' instead of just changing it to txtError.
I'm developing a website which must display particular forms for various products depending on the value that the user selects (in <select>) - so a number various forms are created dynamically in a loop by means of a javascript function (buildform() ). The code does not work, e.g. the forms are not created/appended to the wrappers. I narrowed down the problem where i think the problem relates to a different values for the jquery selectors/div-id's (#ecorpproductwrapper"+ecorp_eprodselectid).
When I use (just as a test) #ecorpproductwrapper" (without the variable ecorp_eprodselectid; see also in code below under ALTERNATIVE WORKS) the code works fine, e.g. the forms are built. I checked by means of the console that the ecorpproductwrapper"+ecorp_eprodselectid values are the same for the div-id's and jquery selectors, so I dont understand what goes wrong?
Pls see the simplified code below:
for(var i=0;i<5;i==){
var ecorp_eprodselectid; //will have various values
//function to build form depending on selected value in <select class= eprodtype"+ecorp_eprodselectid >
$(".eprodtype"+ecorp_eprodselectid).focus(function () {
var previous;
// Store the current value on focus and on change
previous = this.value; //old select value
}).change(function() {
var optionsform = buildform(this.value);
console.log('append form'+optionsform);
//NEXT 2 lines doe NOT WORK
$("#ecorpproductwrapper"+ecorp_eprodselectid).children().remove(); //remove previous form
$("#ecorpproductwrapper"+ecorp_eprodselectid).append(optionsform);
//ALTERNATIVE works: $('#ecorpproductwrapper').children().remove(); //remove previous tariif struct form
//ALTERNATIVE works: $('#ecorpproductwrapper').append(optionsform);
var str = "#ecorpproductwrapper"+ecorp_eprodselectid;
console.log('STRING ECORP PRODUCT APPEND: '+str);
console.log('change eprod val: '+this.value);
previous = this.value;
});//$("").focus(function () {
}//for i
//function to build form
var buildform = function(ecorp_eproductid) {
//some code here
//NEXT LINE does not work:
form += '<td> <div id="ecorpproductwrapper'+ ecorp_eprodselectid+'"> </div> </td> </tr>'; //cell with wrapper for ecorp product info
//ALTERNATIVE WORKS: form += '<td> <div id="ecorpproductwrapper"> </div> </td> </tr>'; //cell with wrapper for ecorp product info
//some code here; returns form
}//function buildform
I think you forgot to add ecorp_eprodselectid in your function.
var buildform = function(ecorp_eprodselectid ) {
Few things we assume concerning given text above:
You know this.value works
console.log shows optionsform have HTML that it should have. Not said in OP but if not, the function does not work. function seems to be missing already var buildform = function(someVar) as noted by buysDB
As I cannot see your code, I would try first clear everything 100% by chaning this:
$("#ecorpproductwrapper"+ecorp_eprodselectid).children().remove();
to:
$("#ecorpproductwrapper"+ecorp_eprodselectid).html("");
Then:
$("#ecorpproductwrapper"+ecorp_eprodselectid).html(optionsform);
No need for append if you have no intention to keep anything in DIV.
If you have text also in (#ecorpproductwrapper"+ecorp_eprodselectid) which is why you use children(), consider selecting the DIV that can be cleared.
If that still does not work, something is left out that needs consideration.
I have this code in jquery :
$("#order_btn").click(function(){
var totalprice = $(".price_amount").text();
$("#totalprice").val(totalprice);
});
When I submit this form with a hidden value i will get the totalprice value two times, if its 200000 i will get 200000200000. why ?
<input type="hidden" value="" name="totalprice" id="totalprice">
<input id="order_btn" type="submit" class="submit" name="submit" value="submit">
the price amout will defined here :
<span class="price_amount">75000</span>
I have this span tag two times, but I need both of them, is there a way to get one value only ?
you most probably have more than one span tag with class "price_amount"
try using
var totalprice = $(".price_amount:first").text();
or
var totalprice = $(".price_amount:eq(0)").text();
// therefore you can access the second span tag like this
var totalprice = $(".price_amount:eq(1)").text();
// and so on...
if this makes it work, check your code for a superfluous span tag
EDIT:
should be right now
EDIT 2:
if your totalprice variable should be the sum of all you "price_amount" spans, consider following:
var totalprice = 0;
$.each($('.price_amount'),
function()
{
totalprice += parseInt($(this).text());
});
Are you sure there's only one element on your page with the price_amount class? If you put a breakpoint (or an alert) on the value of totalprice after it's been assigned what do you get?
One other thing - and I'm not sure if this matters or not, but I would put this code in a handler for your form submit instead of click.
Because you have two <span> elements with the class "price_amount".
It's this line in particular
var totalprice = $(".price_amount").text();
When you call .text() from a jQuery set, it will aggregate that value for all selected nodes and return it.
So, either make sure you have only one span w/that classname, or make your selector more specific/granular so that you only retrieve the desired node.