Shortening JavaScript Function - javascript

I must admit, I don't know much about JavaScript that is why my question might sound little bit silly.
But what I'm trying to do is grab values from selected by name radio groups.
It looks like this
function calc() {
var op1 = document.getElementsByName('form[radio1]');
var op2 = document.getElementsByName('form[radio2]');
var op3 = document.getElementsByName('form[radio3]');
var result = document.getElementById('result');
result.value = 0;
result.value = parseInt(result.value);
for (i = 0; i < op1.length; i++) {
if (op1[i].checked) result.value = parseInt(result.value) + parseInt(op1[i].value);
}
for (i = 0; i < op2.length; i++) {
if (op2.options[i].selected) result.value = parseInt(result.value) + parseInt(op2[i].value);
}
for (i = 0; i < op3.length; i++) {
if (op3.options[i].selected) result.value = parseInt(result.value) + parseInt(op3[i].value);
}
return false;
}
And this is my form. Im using rs form for joomla.
<form action="index.php" enctype="multipart/form-data" id="userForm" method="post">
<input name="form[radio1]" value="25" id="radio20" type="radio">
<label for="radio20">Description1</label>
<input name="form[radio1]" value="35" id="radio21" type="radio">
<label for="radio21">Description2</label>
<input name="form[radio2]" value="20" id="radio20" type="radio">
<label for="radio20">Description1</label>
<input name="form[radio2]" value="30" id="radio21" type="radio">
<label for="radio21">Description2</label>
<input type="hidden" value="0" id="result" name="form[result]">
<input type="submit" class="rsform-submit-button" onclick="calc()" id="submit" name="form[submit]" value="submit">
And everything would be OK, as the function is working. the only trouble is that I have about 80 radiograms.
Is there a way to shorten it?

Use arrays of objects (like all the radio buttons, for instance) and iterate over them. Start like this:
var opts = [],
numOpts = 80;
for (var i=0; i<numOpts, i++)
{
opts.push(document.getElementsByName('form[radio' + i + ']'));
}
Edit: let's have a go at the full function. The only thing I'm not 100% sure about is whether you mean to use opX[i].checked or opX.options[i].selected (since your code does different things for op1 and op2/3). Shouldn't be too hard to extrapolate if I've guessed wrong, though.
function calc()
{
var opts = [],
numOpts = 80,
value = 0,
result = document.getElementById('result'),
i, j, opt;
for (i=0; i<numOpts; i++)
{
opts.push(document.getElementsByName('form[radio' + i + ']'));
}
numOpts = opts.length;
for (i=0; i<numOpts; i++)
{
opt = opts[i];
for (j=0; j<opt.length; j++)
{
// or did you mean:
// if (opt.options[j].selected) ?
if (opt[j].checked)
{
value = value + parseInt(opt[j].value, 10);
}
}
}
result.value = value;
return false;
}

jQuery is a great library that's like using JavaScript on steroids. It is well worth learning and there are plenty of examples out in the wild.
You can write complex "selectors" quite like this:
$('input[name=form[radio1]]').attr('checked').each(function() {
result.value = $(this).attr('value')
})
(I'm not sure if it will accept a name like "form[radio1]" as valid, but give it a try.

Related

Getting error [object HTMLCollection]

I am having a problem in making a simple test in javascript. This is a quick example. Each question's div id is incremented in the html code.
HTML
<form action="#">
<div id="q1">
<label>Q. ABCD</label>
<label><input type="radio" name="radio1" value="1">A</label>
<label><input type="radio" name="radio1" value="2">B</label>
<label><input type="radio" name="radio1" value="3">C</label>
<label><input type="radio" name="radio1" value="4">D</label>
</div>
....
....
<input type="button" value="Click to Submit" onClick="result();">
</form>
JS (say for 10 questions)
function result() {
var answer = new Array();
for(var i=1; i<11 ; i++) {
if(document.getElementById("q" + i).getElementsByTagName("input") != undefined) {
answer[i] = document.getElementById("q" + i).getElementsByTagName("input");
}
else {
answer[i] = 0;
}
}
console.log(answer);
}
I am getting an error [object HTMLCollection] every time I submit the code. How should I do this so that I can get the value of each answer given inside the array and if someone doesn't answer any question, the array must get 0 value at its place instead of undefined. I need a pure JS and HTML solution.
Try this one
function result() {
var answer = new Array();
// there is no answer 0
answer[0] = 'unused';
for(var i=1; i<11 ; i++) {
// check if the id exists first
var container = document.getElementById("q" + i);
if(container) {
// get the selected radio checkbox
var input = container.querySelector("input:checked");
// if there's one selected, save it's value
if(input) {
answer[i] = input.value;
}
else {
answer[i] = 0;
}
}
}
console.log(answer);
}
a working fiddle - http://jsfiddle.net/dtpLjru1/
In your code, you are trying to store the HTML collection by using getElementByTagName(). This method will return all the Tags with the name of "input", so total of 4 tags as per the code above.
Instead of that, you can modify your code like below.
Assuming, you want to store "1" in case radio button is checked. else 0
function result() {
var answer = new Array();
for (var i = 1; i <= 4 ; i++) {
if (document.getElementById("q" + i).getElementsByTagName("input") != undefined) {
answer[i] = document.getElementById("q" + i).checked ? 1 : 0;
}
else {
answer[i] = 0;
}
}
console.log(answer);
}
Have not tested the code, How about we do this ?
function result() {
var answer = new Array();
for(i=1; i<11 ; i++) {
if(document.getElementById("q" + i).getElementsByTagName("input") != undefined) {
document.write( document.getElementById("q" + i).getElementsByTagName("input") );
}
else {
document.write(0);
}
}
}

Adding value of selected radio button to an equation

I am at my wits end. I cannot figure out how to add the value of the radio button to the equation. Can someone give me a clue at least on this??
If I don't have the radio button function included, this works fine.
<input type="radio" class="InternetCost" name="int" id="no_int" value="0">None<br>
<input type="radio" class="InternetCost" name="int" id="ten" value="10">10<br>
<input type="radio" class="InternetCost" name="int" id="twenty" value="20">20<br>
<input type="radio" class="InternetCost" name="int" id="thirty" value="30">30<br>
//Try to select radio button
var values = document.getElementsByName("int");
function getValue() {
for(var i = 0; i < values.length; i++) {
if(values[i].checked == true) {
selectedValue = values[i].value;
console.log('value=' + selectedValue);
}
}
}
function calculate()
{
//get selectedValue - this is where I am lost!
var radioValue = getValue()*1;
//Package
var pkgCost = document.getElementById("pkg").value*1;
//Package - Static
var equipPkg = document.getElementById("pep").value*1;
//Additional amount
var addBox = document.getElementById("addtl").value*1;
//Additional Box cost - static
var totalNum = document.getElementById("add_cost").value*1;
//Service amount
var dvrSvc = document.getElementById("dvr_svc").value*1;
//Service cost - static
var dvrCost = document.getElementById("dvr_cost").value*1;
// Sum everything
var SumAll = pkgCost + equipPkg + (addBox*totalNum) + (Svc*Cost) + radioValue;
// print the total
document.getElementById("Sum").innerHTML = SumAll.toFixed(2)
}
Your solution should work fine except you're using
console.log('value=' + selectedValue);
instead of actually returning the value.
return selectedValue;
Example

Using for loop to generate text boxes

I want to be able to enter a number into a text box and then on a button click generate that number of text boxes in another div tag and automatically assign the id
Something like this but not sure how to generate the text boxes and assign automatically assign the id
function textBox(selections) {
for (i=0; i < selections +1; i++) {
document.getElementById('divSelections').innerHTML = ("<form><input type="text" id="1" name=""><br></form>");
}
}
Try this one:
function textBox(selections){
selections = selections*1; // Convert to int
if( selections !== selections ) throw 'Invalid argument'; // Check NaN
var container = document.getElementById('divSelections'); //Cache container.
for(var i = 0; i <= selections; i++){
var tb = document.createElement('input');
tb.type = 'text';
tb.id = 'textBox_' + i; // Set id based on "i" value
container.appendChild(tb);
}
}
A simple approach, which allows for a number to be passed or for an input element to be used:
function appendInputs(num){
var target = document.getElementById('divSelections'),
form = document.createElement('form'),
input = document.createElement('input'),
tmp;
num = typeof num == 'undefined' ? parseInt(document.getElementById('number').value, 10) : num;
for (var i = 0; i < num; i++){
tmp = input.cloneNode();
tmp.id = 'input_' + (i+1);
tmp.name = '';
tmp.type = 'text';
tmp.placeholder = tmp.id;
form.appendChild(tmp);
}
target.appendChild(form);
}
Called by:
document.getElementById('create').addEventListener('click', function(e){
e.preventDefault();
appendInputs(); // no number passed in
});
JS Fiddle demo.
Called by:
document.getElementById('create').addEventListener('click', function(e){
e.preventDefault();
appendInputs(12);
});
JS Fiddle demo.
The above JavaScript is based on the following HTML:
<label>How many inputs to create:
<input id="number" type="number" value="1" min="0" step="1" max="100" />
</label>
<button id="create">Create inputs</button>
<div id="divSelections"></div>
See below code sample :
<asp:TextBox runat="server" ID="textNumber"></asp:TextBox>
<input type="button" value="Generate" onclick="textBox();" />
<div id="divSelections">
</div>
<script type="text/javascript">
function textBox() {
var number = parseInt(document.getElementById('<%=textNumber.ClientID%>').value);
for (var i = 0; i < number; i++) {
var existingSelection = document.getElementById('divSelections').innerHTML;
document.getElementById('divSelections').innerHTML = existingSelection + '<input type="text" id="text' + i + '" name=""><br>';
}
}
</script>
Note: Above code will generate the N number of textboxes based on the number provided in textbox.
It's not recommended to user innerHTML in a loop :
Use instead :
function textBox(selections) {
var html = '';
for (i=0; i < selections +1; i++) {
html += '<form><input type="text" id="'+i+'" name=""><br></form>';
}
document.getElementById('divSelections').innerHTML = html;
}
And be carefull with single and double quotes when you use strings
You have to change some code snippets while generating texboxes, Learn use of + concatenate operator, Check code below
function textBox(selections) {
for (var i=1; i <= selections; i++) {
document.getElementById('divSelections').innerHTML += '<input type="text" id="MytxBox' + i + '" name=""><br/>';
}
}
textBox(4); //Call function
JS Fiddle
Some points to taken care of:
1) In for loop declare i with var i
2) your selection + 1 isn't good practice at all, you can always deal with <= and < according to loop's staring variable value
3) += is to append your new HTML to existing HTML.
ID should be generate manually.
var inputName = 'divSelections_' + 'text';
for (i=0; i < selections +1; i++) {
document.getElementById('divSelections').innerHTML = ("<input type='text' id= " + (inputName+i) + " name=><br>");
}
edit : code formated
Instead of using innerHTML, I would suggest you to have the below structure
HTML:
<input type="text" id="id1" />
<button id="but" onclick="addTextBox(this)">click</button>
<div id="divsection"></div>
JS:
function addTextBox(ops) {
var no = document.getElementById('id1').value;
for (var i = 0; i < Number(no); i++) {
var text = document.createElement('input'); //create input tag
text.type = "text"; //mention the type of input
text.id = "input" + i; //add id to that tag
document.getElementById('divsection').appendChild(text); //append it
}
}
JSFiddle

Buttons with values, How to calculate a total price

First I'd like to say that i'm a very new beginner when it comes to java script with no other skills involved. I seem to be a little lost in my coding. I have two sets of options with three choices within each. Each choice has its own price. How do I calculate a total price?
JavaScript (included in HEAD)
var theForm = document.forms["pizzaOrder"];
var pizza_price = new Array();
pizza_price["meatLover"] = 15.50;
pizza_price["veggieLover"] = 12.50;
pizza_price["supreme"] = 20.00;
function getPizzaPrice() {
var pizzaPrice = 0;
var theForm = document.forms["pizzaOrder"]; //You already declared "theForm" at global scope - no need to redeclare it here to hold the same reference -crush
var pizzaType = theForms.elements["pizzaType"]; //Mispelled "theForm" here -crush
for(var i = 0; i < pizzaType.length; i++) {
if(pizzaType[i].checked) {
pizzaPrice = pizza_price[pizzaPrice[i].value];
break;
}
}
return pizzaPrice;
}
var extra_top = new Array()
extraTop["extraChees"] = 1.00;
extraTop["mushrooms"] = 1.10;
extraTop["anchovies"]-1.25; //Obvious syntax error here -crush
function getToppingPrice() {
var toppingPrice=0;
var theForm = document.forms["pizzaOrder"];
var extraTop = theForm.elements["extraTop"] //You forgot the semi-colon here -crush
for(var i = 0; i < extraTop.length; i++) {
if(extraTop[i].checked) {
toppingPrice = extra_top[extraTop.value];
break;
}
}
return toppingPrice;
}
function getTotal() //You're missing an opening bracket here -crush
var pizzaPrice = getPizzaPrice() + getToppingPrice();
document.getElementbyId('totalPrice').innerHTML = "Total Price for Pizza is $" + pizzaPrice;
//You're missing a closing bracket here -crush
HTML
<body onload="hideTotal">
<h1>Pizza To Go</h1>
<h2>Order Online</h2>
<form action="" id="PizzaOrder" onsubmit="return false;">
<p>Select Your Pizza!<br />
<input type="radio" name="pizzaType" value="meatLover" onclick="calculateTotal()"/> Meat Lover $12.50<br />
<input type="radio" name="pizzaType" value="veggieLover" onclick="calculateTotal()"/> Veggie Lover $12.50<br />
<input type="radio" name="pizzaType" value="supreme" onclick="calculateTotal()"/> Supreme $12.50<br />
<p>Add Extra Toppings!<br />
<input type="checkbox" name="extraTop" value="extraCheese" onclick="calculateTotal()"/> Extra Cheese $1<br />
<input type="checkbox" name="extraTop" value="mushrooms" onclick="calculateTotal()"/> Mushrooms $1.10<br />
<input type="checkbox" name="extraTop" value="anchovies" onclick="calculateTotal()"/> Anchovies $1.25<br />
</form>
</body>
I'm currently lost as it just doesnt seem to work. Any help is much appreciated.
Your code could stand to be cleaned up quite a bit in general, but your functional issue is that you should be using an object instead of arrays to hold your item prices. Cleanup notwithstanding, try something like this:
var pizza_price = {
"meatLover": 15.50,
"veggieLover": 12.50,
"supreme": 20.00
};
var extra_top = {
"extraChees": 1.00,
"mushrooms": 1.10,
"anchovies": -1.25
};
function getPizzaPrice() {
var pizzaPrice=0;
var theForm = document.forms["pizzaOrder"];
var pizzaType = theForms.elements["pizzaType"];
for(var i = 0; i < pizzaType.length; i++) {
if(pizzaType[i].checked) {
pizzaPrice += pizza_price[pizzaPrice[i].value];
}
}
return pizzaPrice;
}
function getToppingPrice() {
var toppingPrice=0;
var theForm = document.forms["pizzaOrder"];
var extraTop = theForm.elements["extraTop"];
for(var i = 0; i < extraTop.length; i++) {
if(extraTop[i].checked) {
toppingPrice += extra_top[extraTop[i].value];
}
}
return toppingPrice;
}
function getTotal() { return getPizzaPrice() + getToppingPrice(); }
If you want to create a jsfiddle I'll take a closer look.

Unchecking a checkbox and modifying value of sum

I am trying to design a menu. If you check a box, then sum get added up and if you uncheck it, the sum is reduced. I face trouble in reducing the sum while unchecking the box and also the value of sum is not globally changed. Please help me out.
<head>
<script>
var sum=0;
function a(sum,num) {
sum=sum+num;
document.getElementById("demo").innerHTML=sum;
}
</script>
</head>
<body>
<input type="checkbox" name="Dal" id="dal" onclick=a(sum,10)>Dal<br>
<input type="checkbox" name="Rice" id="rice" onclick=a(sum,20)>Rice<br>
<h1> Total Price is : </h1>
<p id="demo"> 0 </p>
</body>
Change the markup, add a value and a class, and remove the inline JS
<input type="checkbox" name="Dal" id="dal" value="10" class="myClass">Dal
<input type="checkbox" name="Rice" id="rice" value="20" class="myClass">Rice
<h1> Total Price is : </h1><p id="demo">0</p>
Then do
<script type="text/javascript">
var inputs = document.getElementsByClassName('myClass'),
total = document.getElementById('demo');
for (var i=0; i < inputs.length; i++) {
inputs[i].onchange = function() {
var add = this.value * (this.checked ? 1 : -1);
total.innerHTML = parseFloat(total.innerHTML) + add
}
}
</script>
FIDDLE
You can do something like this:
function a (elem, num) {
var k = (elem.checked) ? 1 : -1;
sum = sum + k * num;
document.getElementById("demo").innerHTML = sum;
}
And in the HTML:
<input type="checkbox" name="Dal" id="dal" onclick="a(this, 10);">Dal<br>
<input type="checkbox" name="Rice" id="rice" onclick="a(this, 20);">Rice<br>
Try something like this:
var sum = 0;
function a(id, num) {
if(id.checked == true){
sum += num;
id.onclick = function() { a(id, num)};
}
else {
sum -= num;
id.onclick = function() { a(id, num)};
}
document.getElementById("demo").innerHTML=sum;
}
Fiddle: http://jsfiddle.net/95pvc/2/
My own take would involve removing the event-handling from the HTML (unobtrusive JavaScript) for easier maintenance in future, using data-* attributes to contain the price and using a class-name to identify the relevant ingredients, to give the following HTML:
<input class="ingredients" type="checkbox" name="Dal" data-price="10" id="dal" />Dal
<input class="ingredients" type="checkbox" name="Rice" data-price="20" id="rice" />Rice
<h1> Total Price is : </h1>
<p id="demo">0</p>
Which leads to the following JavaScript:
var ingredients = document.getElementsByClassName('ingredients');
function price() {
var result = document.getElementById('demo'),
curPrice = 0,
ingredients = document.getElementsByClassName('ingredients');
for (var i = 0, len = ingredients.length; i < len; i++) {
if (ingredients[i].checked) {
curPrice += parseFloat(ingredients[i].getAttribute('data-price'));
}
}
result.firstChild.nodeValue = curPrice;
}
for (var i = 0, len = ingredients.length; i < len; i++) {
ingredients[i].addEventListener('change', price);
}
JS Fiddle demo.
To avoid having to iterate through the relevant checkboxes, it might be better to wrap those input elements in a form, and then bind the event-handling to that form:
var ingredients = document.getElementsByClassName('ingredients');
function price() {
var result = document.getElementById('demo'),
curPrice = 0,
ingredients = document.getElementsByClassName('ingredients');
for (var i = 0, len = ingredients.length; i < len; i++) {
if (ingredients[i].checked) {
curPrice += parseFloat(ingredients[i].getAttribute('data-price'));
}
}
result.firstChild.nodeValue = curPrice;
}
document.getElementById('formID').addEventListener('change', price);
JS Fiddle demo.
References:
addEventListener().
element.getAttribute().
getElementsByClassName().
parseFloat().

Categories

Resources