This is a somewhat simplified version of the problem to make it easier to explain and a shorter question.
I have X checkboxes:
<input type="checkbox" class="checker" value="1" />
<input type="checkbox" class="checker" value="2" />
<input type="checkbox" class="checker" value="3" />
...
I have 2 columns, cert and cost, of Y number of input fields (X > Y) then a total at the bottom:
<input type="text" class="cert" /><input type="text" class="cost">
<input type="text" class="cert" /><input type="text" class="cost">
<input type="text" class="cert" /><input type="text" class="cost">
...
<input type="text" id="total" />
The user can select any combination of checkboxes (up to limit Y). When a checkbox is selected, it's value is entered into the first empty cert input. Depending on the cert value, the corresponding cost is then put into the adjacent cost input (e.g. cert 1 = cost 50, cert 2 = cost 100, etc).
If a checkbox is unticked, the corresponding cert is cleared, as is the cost.
The total at the bottom keeps a running total on a change to any thing.
A few additional notes:
The checkboxes are spaced throughout the form, not in one continual sequence.
Similarly the cert and cost inputs are not actually side by side in the html (although do appear to be on the screen), there is other code between them.
Any help / input is greatly appreciated as I'm mostly just producing a mess!
Here is something to start you out with. I'm not sure if your cert 1 cert 2 is going inside the textbox or there are labels or something. Same with your cost. But that's the way I did it in the example. This is assuming you have the same amount of checkboxes as the set of inputs(cert & cost);
$('input.checker').change(function(){
// store the current index so we can pick which text input to change
var $i = $(this).index('input.checker');
// put val in corresponding cert text input
$('input.cert').eq($i).val(this.checked ? 'cert ' + ($i+1) : '');
// put val in corresponding .cost text input
$('input.cost').eq($i).val(this.checked ? 'cost ' + (50 * ($i+1)) : '');
var total = 0;
// loop through the cost inputs and add up total
$('input.cost').each(function(i,v){
total += (+$(v).val().replace('cost ',''));
});
// insert total
$('#total').val(total);
});
EXAMPLE FIDDLE
Related
I'm building a multiple quantity selector for my store. Image below:
On the site, the price of the product updates based on the quantity added. 10 products = 10% off etc. I'd like to be able to display this price change as and when the user edits any one of the input boxes in the quantity selector.
The input fields are built like this:
<div data-value="S" data-varientid="8195426353207" class="swatch-element swatch-element-2 size s available">
<input id="swatch-0-s" data-variant-id="variant_8195426353207" type="checkbox" name="option-0" value="S">
<label for="swatch-0-s">
S
<img class="crossed-out" src="//cdn.shopify.com/s/files/1/0020/2188/3959/t/2/assets/soldout.png?5180939831627851747" alt="">
</label>
<input id="qty" name="quantity" class="swatchinput" placeholder="0" value="0" type="text">
</div>
I'm able to watch the input boxes for change by doing the below:
var qty = $('.swatchinput');
$('.swatchinput').on('paste keyup', function() {
console.log(qty);
});
However, this returns the information about the element rather than the contents. I'm also unsure of the best way to then add the contents of the various input fields together to reach the total quantity.
You could also use the Array reduce method to do this. Select all the inputs, get the array, then reduce their values into the sum.
var total = $('.swatchinput').get().reduce(function(total, input){
return total + parseInt(input.value || '0');
}, 0);
console.log(total);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input name="quantity" class="swatchinput" placeholder="0" value="1" type="text">
<input name="quantity" class="swatchinput" placeholder="0" value="2" type="text">
<input name="quantity" class="swatchinput" placeholder="0" value="3" type="text">
<input name="quantity" class="swatchinput" placeholder="0" value="4" type="text">
This needs to be
var qty = $('.swatchinput').val();
not
var qty = $('.swatchinput');
As for your second question,
loop each of these inputs, getting the value, then add them up with a total. Initialize the total OUTSIDE of the loop also so it doesn't overwrite it.
Something like this?
var total = 0;
$('.switchinput').each(function(){
total += $(this).val();
});
console.log(total);
To get the value of an element in jQuery, use .val():
http://api.jquery.com/val/
.each loops through each matched element and runs a function on that element (accessible through 'this')
http://api.jquery.com/each/
Sincere apologies if this has been asked and answered elsewhere, I struggled with finding accurate search terms for this.
Working in jQuery I have a var called total. I need to add the value of other vars to total. All the vars in question have numerical values.
This is what I've tried:
var total = total+rocketspend;
$(".totalamount").html(total);
and
var newtotal = total+rocketspend;
var total = newtotal;
$(".totalamount").html(total);
Both have resulted in .totalamount being emptied and replaced with nothing. I have theories around why this might be going wrong - it could be that in the first example a var isn't allowed to be self defining, and it could be that in in the second example the browser attempts to define both newtotal and total at the same time, ending in mystery. Or it could be something else entirely. The rocketspend var works fine on its own, as does total before the attempted addition.
Thoughts?
You only need to use var when you first define a variable. It looks like you're trying to access a variable that already exists. Example:
var total = 0;
var rocketspend = 10;
total = total + rocketspend;
$(".totalamount").html(total);
Additionally, try checking your console for any errors. In most browsers, you can right click and inspect an element or click Ctrl + Shift + I and clicking on the Console tab. You can use Ctrl + Shift + K in Firefox.
You are using jQuery and have referenced an element (i.e. .totalamount) so assuming you are using normal webpage (i.e. HTML, CSS, JS/jQ etc..), this Snippet has 2 <forms>. The first one uses only JavaScript and HTML5. The second form uses jQuery and HTML5.
When using form fields such as <input>, the value you type in them will be a string (i.e. text) value. So when "3" is typed in, the <input> will treat it as text not a real number value. So convert the string to a number, use parseFloat(), parseInt(), or Number().
To get <input> values use .val() (jQuery) or .value (JavaScript).
SNIPPET
$('#calc1').on('input', function() {
var rocket1 = $('#rocket1').val();
var sub1 = $('#sub1').val();
var total1 = parseFloat(sub1) + parseFloat(rocket1);
$("#total1").val(total1);
});
input {width: 8ex;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Using only plain JavaScript and HTML5 form fields</p>
<form id="calc" name="calc" oninput="total.value = parseFloat(sub.value, 10) + parseFloat(rocket.value, 10)">
<fieldset>
<legend>Rocket Expenditure</legend>
<label for="sub">
<b>Sub Total:</b>
<input type="number" id="sub" name="sub" value="0">
</label> +
<label for="rocket">
<b>Rocket:</b>
<input type="number" id="rocket" name="rocket" value="0">
</label>
<label>
<b>Total:</b>
<output name="total" for="sub rocket">0</output>
</label>
</fieldset>
</form>
<p>Using jQuery and HTML5 form fields</p>
<form id="calc1" name="calc1">
<fieldset>
<legend>Rocket Expenditure 1</legend>
<label for="sub1">
<b>Sub Total 1:</b>
<input type="number" id="sub1" name="sub1" value="0">
</label> +
<label for="rocket1">
<b>Rocket 1:</b>
<input type="number" id="rocket1" name="rocket1" value="0">
</label>
<label>
<b>Total 1:</b>
<output id="total1" name="total1" for="sub1 rocket1">0</output>
</label>
</fieldset>
</form>
Overview:
This is my first time using javascript. I'm trying to use a combination of Radio Buttons and Check Boxes to adjust the "Total Cost" & "Listed Price" of an Item under a number of different conditions. The JS Fiddle reflects where I currently stand. Any suggestions, examples, comments, or form of help would be greatly appreciated as I'm completely stuck.
JS Fiddle (the code is below as well incase you don't want to open JS Fiddle):
http://jsfiddle.net/y2u24x3r/4/
The Issues\conditions that I'm completely stuck on:
[Radio 1] How many attendees? (1) (2)
(2) Should double the Total Cost (unless all Four Event Boxes are checked. See Below).
[Radio 2] Are you a Member? (No) (Yes)
(No) should make the cost $26.00 per Event as seen in the
Jfiddle\code below.
(Yes) change the displayed Price per Event to $18.00 and automatically adjust the Total Cost.
[Four Event Check Boxes]
If all Four Event Boxes are checked, Attendees = '1', and Are you a Member = 'Yes' then override all conditions above and set price to $68.00.
If all Four Event Boxes are checked, Attendees = '2', and Are you a Member = 'Yes' then override all conditions above and set price to $136.00.
HTML:
<font color="orange">How many attendees?</font> <input type="radio" name="attendees" id="attendees" value="1" checked="checked" />1 <input type="radio" name="attendees" id="attendees" value="2"/>2<br/>
<font color="orange">Are you a Member?</font> <input type="radio" name="member" id="member" value="0" checked="checked" />No <input type="radio" name="member" id="member" value="1"/>Yes <br/><br/>
<form name="listForm"><font color="orange">Select the Concerts you want Tickets for:</font><br/>
<input type="checkbox" name="event" value="1" onchange="checkTotal()"/><font color="#33FF33"> <div class="price"></div></font></input> Nov. 1, 2015 -- Concert 1<br/>
<input type="checkbox" name="event" value="1" onchange="checkTotal()"/><font color="#33FF33"> <div class="price"></div></font></input> Dec. 1, 2015 -- Concert 2<br/>
<input type="checkbox" name="event" value="1" onchange="checkTotal()"/><font color="#33FF33"> <div class="price"></div></font></input> Jan. 1, 2015 -- Concert 3<br/>
<input type="checkbox" name="event" value="1" onchange="checkTotal()"/><font color="#33FF33"> <div class="price"></div></font></input> Feb. 1, 2015 -- Concert 4<br/><br/>
<font color="#33FF33">Total Cost:</font> <input value="$0.00" readonly="readonly" type="text" id="total"/>
</form>
Javascript:
function checkTotal() {
var attendees = document.getElementsByName("attendees");
var member = document.getElementsByName("member");
var total = 0;
var event = 0;
if (member == 0) {
price = 26.00;
}
else if (member == 1) {
price = 18.00;
}
for (var i = 0; i < event.length; i++) {
if (event[i].checked) {
total += parseFloat(member.value);
total = total * attendees;
}
}
if (member == 1 && event == 4 && attendees == 1) {
total = 68.00;
}
if (member == 1 && event == 4 && attendees == 2) {
total = 136.00;
}
document.getElementById("total").value = "$" + total.toFixed(2);
}
Thank you for sharing your attempts, now i can help you correct your code.
Lets go over the issues with the code one by one:
1. Invalid left side assignment
unlike in languages like Visual Basic, here in JavaScript you must have a double == operator in order to check conditions. therefore, in the next line:
if (member = 1 && event = 4 && attendees = 1)
what JavaScript actually understands is:
put 1 into member,
put 1 into event,
and put 1 into attendees.
in order to ask JS to check if their values equal 1, you need to use a double equation operator:
if (member == 1 && event == 4 && attendees == 1)
2. Using of system-reserved keywords
the reason why the previous was actually an issue, is because of the word event
after all, JS could simply assign 1 to all of the keywords, but instead it dropped an error into the console saying that the assignment was invalid, so why is that? - that's because in JavaScript there is a reserved keyword named event which represents the event parameter in the function. so when you assign
onchange="checkTotal()"
once that function is called to handle the change event, the event data will be passed into the function in a built in event var.
therefore, you should change the names of the input elements to something else, maybe "eventCheckBox" or something.
3. Duplicate IDs
Ids are supposed to be unique. when you search something by ID in JS, it will search from the top of the page and return the first one it finds, because it assumes that this ID is unique. also, in JavaScript you can address the elements by their IDs without getting the elements first using getElementsByID(), so when you are using var names named the same as multiple ids on the page, well, you see the problem?
make unique ids per element. if you want a common identifier for your elements, use a common class.
4. Getting value of a radio button
most likely, you have tried to name your radio buttons the same and thought that when you ask for the value, you will get the value of the checked one. well, its good thinking but unfortunately it does not work this way in JavaScript.
what you need to do, is find the checked one and get its value.
it is rather simple, with 1 line of code:
document.querySelector('input[name="member"]:checked').value;
*same applies for attendees.
5. Counting Checked Checkboxes
while iterating through the checkboxes and altering the total value could work, it is much simpler to count how many of them are checked using the next line:
document.querySelectorAll('input[name="eventCheckBox"]:checked').length;
6. Optional
if you want the total price to update when attendees and membership are changed, then you need to add the change event to them as well.
Here is your fixed code:
function checkTotal() {
//get values from the inputs
var attendees = document.querySelector('input[name="attendees"]:checked').value;
var member = document.querySelector('input[name="member"]:checked').value;
var SelectedEvents = document.querySelectorAll('.EventCheckBox:checked').length;
//init vars;
var total = 0;
var price = 26.00;
if (member == 1) {
price = 18.00;
}
//calculate cost
total = SelectedEvents * attendees * price;
if (member == 1 && SelectedEvents == 4 && attendees == 1) {
total = 68.00;
}
if (member == 1 && SelectedEvents == 4 && attendees == 2) {
total = 136.00;
}
document.getElementById("total").value = "$" + total.toFixed(2);
}
<font color="orange">How many attendees?</font>
<input type="radio" name="attendees" value="1" checked="checked" onchange="checkTotal()" />1
<input type="radio" name="attendees" value="2" onchange="checkTotal()" />2
<br/>
<font color="orange">Are you a Member?</font>
<input type="radio" name="member" value="0" checked="checked" onchange="checkTotal()" />No
<input type="radio" name="member" value="1" onchange="checkTotal()" />Yes
<br/>
<br/>
<form name="listForm"><font color="orange">Select the Concerts you want Tickets for:</font>
<br/>
<input type="checkbox" name="eventCB1" value="1" onchange="checkTotal()" class="EventCheckBox" /><font color="#33FF33"> <div class="price"></div></font>
</input>Nov. 1, 2015 -- Concert 1
<br/>
<input type="checkbox" name="eventCB2" value="1" onchange="checkTotal()" class="EventCheckBox" /><font color="#33FF33"> <div class="price"></div></font>
</input>Dec. 1, 2015 -- Concert 2
<br/>
<input type="checkbox" name="eventCB3" value="1" onchange="checkTotal()" class="EventCheckBox" /><font color="#33FF33"> <div class="price"></div></font>
</input>Jan. 1, 2015 -- Concert 3
<br/>
<input type="checkbox" name="eventCB4" value="1" onchange="checkTotal()" class="EventCheckBox" /><font color="#33FF33"> <div class="price"></div></font>
</input>Feb. 1, 2015 -- Concert 4
<br/>
<br/>
<font color="#33FF33">Total Cost:</font>
<input value="$0.00" readonly="readonly" type="text" id="total" />
</form>
and a Fiddle
UPDATE:
If having the same name on all of the check boxes causes issues of any sort, it is handled easily.
javascript/html/css have many different ways to achieve the same result, in time you will learn more tricks, for now here are two:
a. the ^= attribute selector:
this selects all elements who's attribute begins with a certain string.
before, we have selected all the inputs using their exact name:
document.querySelectorAll('input[name="eventCB"]:checked')
this selected all checked inputs who's name attribute equals "eventCB". now our elements have now ID's appended to the name, but all still begin with the same string "eventCB" therefore we can alter our selector as follows:
document.querySelectorAll('input[name^="eventCB"]:checked')
b. common class
in my opinion, it is much easier to set a common class to the events, and select them using the class; let their class be "EventCheckBox" for the example:
document.querySelectorAll('.EventCheckBox:checked').length;
the dot at the beginning of the selector string means class select. without a dot it will select element by type, with a dot it selects class, and with a # it will select by ID.
i have updated the snippet and fiddle above.
I've built a script to add quantities/units and generate a total that displays sales tax.
How can I get this calculator to recognise #discount and subtract it from the total before the GST (10% sales tax) is calculated and added?
Also, is it possible to generate the total when the page loads? Instead of a user having to press the 'Generate total' button?
HTML
<ul>
<li> Item 1 (<input type="text" name="others" size="4" value="5" readonly="readonly" class="readonly_field"/> units)</li>
<li> Item 2 (<input type="text" name="others" size="4" value="1" readonly="readonly" class="readonly_field"/> units)</li>
<li> Item 3 (<input type="text" name="others" size="4" value="3" readonly="readonly" class="readonly_field"/> units)</li>
</ul>
<input type="button" value="Generate Total" onclick="total()" /><br><br>
Discount <input type="text" id="discount" name="discount" value="500"/><br><br>
Total Units: <input type="text" id="units_total" name="units_total" readonly="readonly" /><br>
Sub Total: <input type="text" id="sub_total" name="sub_total" readonly="readonly" /><br>
Includes GST: <input type="text" id="gst_total" name="gst_total" readonly="readonly" /><br>
Total: <input type="text" id="g_total" name="g_total" readonly="readonly" />
JS
function total(){
var total_value = 0;
var all_others = document.getElementsByTagName("input");
for(var i=0; i<all_others.length; i++){
if(all_others[i].type!="text" || all_others[i].name!="others"){
continue;
}
total_value += parseFloat(all_others[i].value);
}
document.getElementById("units_total").value = (total_value).toFixed(1);
document.getElementById("sub_total").value = ((total_value) *100).toFixed(2);
document.getElementById("g_total").value = (((total_value * 10/100) + total_value) * 100).toFixed(2);
document.getElementById("gst_total").value = ((total_value * 10/100) * 100).toFixed(2);
}
Firstly, to get your function to execute on window load, wrap it in a load event:
window.onload = function() {
total();
}
Secondly, to get it to figure in discount, you just need to modify your variable a few times, but then when adding them together, make sure you parse them with .parseFloat():
if (document.getElementById('discount').value != '') {
var discount = document.getElementById('discount').value;
}
else {
var discount = 0;
}
var sub_total = (((total_value) * 100).toFixed(2) - discount).toFixed(2);
var gst = ((total_value * 10 / 100) * 100).toFixed(2);
document.getElementById("sub_total").value = sub_total;
document.getElementById("gst_total").value = gst;
document.getElementById("g_total").value = (parseFloat(sub_total) + parseFloat(gst)).toFixed(2);
DEMO
First of all, I suggest you to perform validation and computations both server side and client side. The first ensures security while the second improves the responsiveness of the UI.
Said that, you'd better introduce several support variables and perform computation on them. You should get the value from the elements you are interested into using getElementById and store it in variables.
Then you should perform computation on that variables and finally place the results in the elements you want to use to display them to the user.
To perform the operation when the page loads have a look at this.
I have a form with field names that are generated dynamically by server side code.
I am attempting to allow JQuery to manipulate the value of these fields, but am running into trouble.
The generated fields are paired using a unique ID number Example:
A radio button named option_3030
Will have a amount_3030 field
The number of dynamically created fields is also an unknown (there might be one or ten input pairs -- all named option_xxxx and amount_xxxx.
What I'm trying to do is use jquery to set the value of the 3030_amount field when the 3030_option is checked (or unchecked). The problem is, I don't know ahead of time what the actual id number will be.
Any suggestions?
Thanks,
David
One option is to use classes:
<input type="radio" id="3030_Option" class="option" />
<input type="text" id="3030_amount" class="amount" />
<script>
$(function() {
$('.option').click(function() {
$(this).next('.amount').val('new value goes here')
})
})
</script>
By the way starting html ids with numbers is technically not allowed:
ID and NAME tokens must begin with a
letter ([A-Za-z]) and may be followed
by any number of letters, digits
([0-9]), hyphens ("-"), underscores
("_"), colons (":"), and periods (".")
You can grab the id attribute and take the number from it:
$('input[type=radio]').change(function()
{
var id = this.id.split(/_/)[1];
var amount = $('input[name=amount_' + id + ']');
amount.val(123);
}
If you bind your event with a class, and then parse the id of the clicked element to get the numerical identifier to use for the text field.
<input type="radio" id="3030_Option" class="option" />
<input type="text" id="3030_amount" class="amount" />
<input type="radio" id="3031_Option" class="option" />
<input type="text" id="3031_amount" class="amount" />
$('.option').click(function() {
var id = $(this).attr('id');
var num = id.substring(0, id.indexOf('_'));
$('#' + num + '_amount').val('value');
});
As pointed out by others, numerals are not valid as the initial character of an id. It would be better to suffix them. In which case the code needs modifying slightly.
<input type="radio" id="Option_3030" class="option" />
<input type="text" id="amount_3030" class="amount" />
<input type="radio" id="Option_3031" class="option" />
<input type="text" id="amount_3031" class="amount" />
$('.option').click(function() {
var id = $(this).attr('id');
var num = id.substring(id.indexOf('_') + 1, id.length);
$('#amount_' + num).val('value');
});
Mhh i think you could try to register the javascipt function while generating the code. I have done somthing similar with a gridview.
generatedControl.Attributes.Add("onchange", "jqueryFunction(" generatedId ")" );