Reputation: 59
So say for example I have this form here
<input type="checkbox" name="degree" value="certificate">Trade School/Certificate<br/>
<input type="checkbox" name="degree" value="aa">Associates Degree<br/>
<input type="checkbox" name="degree" value="ba">Bacholors Degree<br/>
<input type="checkbox" name="degree" value="masters">Masters Degree<br/>
<input type="checkbox" name="degree" value="dr">Doctors Degree<br/>
and for each checkbox that is checked, I want to place it in a separate variable.However, if it is not checked, I want it to be ignored. As of right now i would run a querySelector to pull the value, but that gives me a undefined variable if one isn't checked.
The reason why i want each in its own variable is because i want each value to add up to its own amount of price. Say for example....
if (degreeValue1 === "certificate") {
currentPrice += 300;
}
if (degreeValue2 === "ba") {
currentPrice += 500;
}
Is there a easier or better way to this solution in pure javascript? Thanks in advance.
Upvotes: 1
Views: 105
Reputation: 118
HTML:
<input type="checkbox" name="degree[]" value="certificate">Trade School/Certificate<br/>
<input type="checkbox" name="degree[]" value="aa">Associates Degree<br/>
<input type="checkbox" name="degree[]" value="ba">Bacholors Degree<br/>
<input type="checkbox" name="degree[]" value="masters">Masters Degree<br/>
<input type="checkbox" name="degree[]" value="dr">Doctors Degree<br/>
JavaScript:
var myCheckboxes = new Array();
$("input[name='degree[]']:checked").each(function() {
myCheckboxes.push($(this).val());
});
Upvotes: 0
Reputation: 42179
You have several options, which depends on how you organize and implement the rest of your code.
One way is to solve your problem is to keep the price model in your JavaScript and loop through checkboxes to generate the price when they are clicked:
<label><input type="checkbox" name="degree" value="certificate" />Trade School/Certificate</label>
<label><input type="checkbox" name="degree" value="aa" />Associates Degree</label>
<label><input type="checkbox" name="degree" value="ba" />Bacholors Degree</label>
<label><input type="checkbox" name="degree" value="masters" />Masters Degree</label>
<label><input type="checkbox" name="degree" value="dr" />Doctors Degree</label>
<div>Price is: <span id="price">0</span></div>
var checkboxes = document.getElementsByName('degree'),
price_of = {
certificate: 100,
aa: 200,
ba: 300,
masters: 400,
dr: 500
};
// bind click event
for (var i = 0, n = checkboxes.length; i < n; i++) {
checkboxes[i].onclick = updatePrice;
}
function updatePrice() {
// generate the price
for (var i = 0, n = checkboxes.length, price = 0; i < n; i++) {
if (checkboxes[i].checked)
price += price_of[checkboxes[i].value];
}
// display it in the browser
document.getElementById('price').innerHTML = price;
// ensure checkbox gets checked
return true;
}
The benefit here is that you can quickly locate, view, and manage the association of value to price. While others will talk of jQuery, which is unnecessary given what you've displayed, I will say that an MVC framework like Angular/Ember/Knockout would do a great deal to simplify this.
There is no right solution, but another way instead of using the price_of
object, is to utilize data-*
attributes on your elements. This would couple your price with the checkbox value. An example my might be:
<label><input type="checkbox" name="degree" value="masters" data-price="400" />Master's Degree</label>
<label><input type="checkbox" name="degree" value="doctors" data-price="500" />Doctor's Degree</label>
<div>Price is: <span id="price">0</span></div>
To retrieve the value you could do something like:
var checkboxes = document.getElementsByTagName('INPUT');
for (var i = 0, n = checkboxes.length; i < n; i++) {
checkboxes[i].onclick = updatePrice;
}
function updatePrice() {
for (var price = 0, i = 0, n = checkboxes.length; i < n; i++) {
if (checkboxes[i].checked)
price += +checkboxes[i].dataset.price; //unary plus intentional
}
document.getElementById('price').innerHTML = price;
return true;
}
This is far less code, but your values are embedded in your HTML elements, which could be good or bad depending on how you work and plan to handle your other code. Personally, I would probably be managing the model on the server and load it dynamically into a JSON object. The data would also probably be generated from the server and Angular.js would come in handle to reduce the HTML clutter, but as said there is no wrong way, just better ways than others.
Upvotes: 1
Reputation: 106900
You could put the checked state of each checkbox into an object indexed by their value
:
var elements = document.getElementsByName('degree'),
degrees = {};
for (var i = 0, l = elements.length; i < l; i++) {
degrees[elements[i].value] = elements[i].checked;
}
Now degrees
contains the checked state of each checkbox (example when only masters
is checked):
Object {certificate: false, aa: false, ba: false, masters: true, dr: false}
Then you could use it like so:
if (degrees.certificate) {
currentPrice += 300;
}
if (degrees.ba) {
currentPrice += 500;
}
Upvotes: 1
Reputation: 4808
By using jQuery, you can get all your selected checkboxes with the name="degree" and make test on a switch case like this :
<input type="checkbox" name="degree" value="certificate">Trade School/Certificate<br/>
<input type="checkbox" name="degree" value="aa">Associates Degree<br/>
<input type="checkbox" name="degree" value="ba">Bacholors Degree<br/>
<input type="checkbox" name="degree" value="masters">Masters Degree<br/>
<input type="checkbox" name="degree" value="dr">Doctors Degree<br/>
function getPrice()
{
currentPrice = 0;
var inputs = $("input[name=degree]:checked");
for(i=0;i<inputs.length;i++)
{
switch($(inputs[i]).val())
{
case "certificate":
currentPrice += 100;
break;
case "aa":
currentPrice += 100;
break;
case "ba":
currentPrice += 100;
break;
case "masters":
currentPrice += 100;
break;
case "dr":
currentPrice += 100;
break;
}
}
return currentPrice;
}
Upvotes: 0