How can I read the value of a radio button in JavaScript? - javascript

<html>
<head>
<title>Tip Calculator</title>
<script type="text/javascript"><!--
function calculateBill(){
var check = document.getElementById("check").value;
/* I try to get the value selected */
var tipPercent = document.getElementById("tipPercent").value;
/* But it always returns the value 15 */
var tip = check * (tipPercent / 100)
var bill = 1 * check + tip;
document.getElementById('bill').innerHTML = bill;
}
--></script>
</head>
<body>
<h1 style="text-align:center">Tip Calculator</h1>
<form id="f1" name="f1">
Average Service: 15%
<input type="radio" id="tipPercent" name="tipPercent" value="15" />
<br />
Excellent Service: 20%
<input type="radio" id="tipPercent" name="tipPercent" value="20" />
<br /><br />
<label>Check Amount</label>
<input type="text" id="check" size="10" />
<input type="button" onclick="calculateBill()" value="Calculate" />
</form>
<br />
Total Bill: <p id="bill"></p>
</body>
</html>
I try to get the value selected with document.getElementById("tipPercent").value, but it always returns the value 15.

In HTML, Ids are unique. Try changing the id attributes to tipPercent1, tipPercent2, etc.

Both radio buttons have the same ID - this is incorrect in HTML, as IDs should be unique. The consequence is that document.getElementById cannot be used.
Try document.getElementsByName and loop through the resulting array to find out which one is checked and what its value is.

<input type="radio" id="tipPercent" name="tipPercent" value="15" />
<input type="radio" id="tipPercent" name="tipPercent" value="20" />
First of all, id's are required to be unique identifiers, so giving two elements the same id will make problems. document.getElementById("tipPercent") after all tries to get one element, so which of those two different input elements should it return?
Second, you can only check if a radio input is checked or not, so you will need to loop through all those inpud fields and check which one is checked to get the current value.

You have two equal ids "tipPercent". getElementById returns only one first result

You should use different ids for each radio. Try something like follows:
<script type="text/javascript">
//a variable that will hold the index number of the selected radio button
for (i=0;i<document.f1.tipPercent.length;i++){
if (document.document.f1.tipPercent[i].checked==true)
var tipPercent= document.f1.tipPercent[i].value;
}
</script>

You may want to change the calculateBill() function with the following:
function calculateBill() {
var tipPercent = 0;
var check = document.getElementById("check").value;
var radioElements = document.getElementsByName("tipPercent");
for (var i = 0; i < radioElements.length; i++) {
if (radioElements[i].checked)
tipPercent = parseInt(radioElements[i].value);
}
var tip = check * (tipPercent / 100)
var bill = 1 * check + tip;
document.getElementById('bill').innerHTML = bill;
}
Note the use of document.getElementsByName(), as Oded suggested in another answer.
You should also remove the id attribute from your radio buttions:
<input type="radio" name="tipPercent" value="15" />
<input type="radio" name="tipPercent" value="20" />
The following is a screenshot showing that the above function works fine with the 20% radio button:
How can I read the value of a radio button in JavaScript? http://img695.imageshack.us/img695/6214/tipcalc.png

The id of an element has to be unique, so you can't have two elements with the same id.
When you try to get all radio buttons as a single element, you will get one of them. Which one you get is entirely up to how the browser choose to handle the incorrect id's that you have set. You could get either of the elements, or null, depending on the implementation. In this case you happen to use a browser that gets the first element.
Give the elements their own id:
Average Sevice: 15%<input type="radio" id="tipPercent15" name="tipPercent" value="15" />
<br />
Excellent Sevice: 20%<input type="radio" id="tipPercent20" name="tipPercent" value="20" />
Getting the value attribute from the element will only get the value that you have specified for each of them. Instead you used the checked attribute:
var tipPercent;
if (document.getElementById("tipPercent15").checked) tipPercent = 15;
if (document.getElementById("tipPercent20").checked) tipPercent = 20;

Related

How do you delete duplicate elements in htmlcollections?

Im trying to delete duplicates of htmlcollections. Basically they are htmlcollection of input checkboxes with attributes name and value. I want to remove the entire <input> if the name and value are the same.
I couldn't find similar questions in stackoverflow. But what I have so far is to convert the htmlcollections first into array using
var arr = Array.from(htmlCollection);
and then use a Set to remove the duplicates, then convert it back to htmlCollection. This is way too long. Is there another way to do this?
EDIT: Just made a function undDeal to deal with elements that won't have a value AND OR a name
let removeDuplicates=(elem)=>{
let obj={} //for holding data for checking later
//below function for handling elements without a name AND OR value
//(so that <input name="undefined" value="1" /> isn't seen as <input value="1" />)
let undDeal=(val1,val2)=>{
if(val1==undefined){
if(val2==undefined){return Symbol.iterator}
return Symbol.match
}
return val1+val2
}
let elems=[...elem.children]
let check=(el)=>{
let specs=()=>undDeal(el.name,el.value)
if(obj[specs()]){return true}
obj[specs()]=1; return false
}
for(let i=0;i<elems.length;i++){
if(check(elems[i])){elem.removeChild(elems[i])}
}
}
removeDuplicates(document.body)
<body>
<input name="asdf1" value="1" />
<input name="asdf2" value="2" />
<input name="asdf1" value="2" />
<input name="asdf2" value="2" />
<input name="asdf2" value="1" />
</body>

Cant Get Answer Back In answer Box NAN is being shown

it does not returns prpoer answer it returnes NAN in Answer
<html>
<head>
<script type="text/javascript">
function pro(n,p)
{
var number=parseInt(n);
var powe=parseInt(p);
for(var i=1;i<powe;i++)
{
number*=number;
}
document.getElementById("answer").value=number;
}
</script>
</head>
<body>
<form name="F" >
Enter Number <input type="text" name="num" id="num"/>
Enter Power <select name="powe" id="powe">
<option value="2" >square</option>
<option value="3" >cube</option>
</select>
Answer<input type="text" name="Answer" id="answer" />
<input type="button" onClick="pro(num,powe)" value="Calculate" />
</form>
</body>
</html>
The issue is this: onClick="pro(num,powe)". Instead of the values for num and powe being gotten from the input elements and passed into the pro function, the actual element references (which are not numbers) are being passed.
To solve this problem, you'll need to get the values of the elements. But, before you just make a quick edit to your code, don't use inline HTML event attributes (onclick) in the first place. Instead, separate your JavaScript from your HTML and set up event handlers using modern standards with .addEventListener() as shown below.
Also (FYI):
Since you aren't actually submitting form data anywhere, you don't
need a <form> element.
It's not necessary to use parseInt with p.value because that
value is coming from your select and you've already set those at
whole numbers.
Don't bother with self-terminating tags (<input />) as you
gain nothing from using them.
If you are expecting only numeric input, it's better to use input
type=number which restricts the user input to numbers. Making this change also saves you from worrying about parseInt on the input number being misinterpreted as other bases than 10.
Since you don't want the user to be able to change the result of the
operation, it's better to display it in a non-editable element, like
a span.
It's a good idea to move your <script> element to just before the
closing body tag because, by the time the parser reaches that
point, all your HTML elements will have been parsed into memory.
<html>
<head>
</head>
<body>
<div>
Enter Number <input type="number" name="num" id="num">
</div>
<div>
Enter Power
<select name="powe" id="powe">
<option value="2">square</option>
<option value="3">cube</option>
</select>
</div>
<div>
Answer <span id="answer"></span>
</div>
<div>
<input type="button" value="Calculate">
</div>
<script>
// Get references to the inputs, the answer container and the button
let inputNum = document.getElementById("num");
let power = document.getElementById("powe");
let answer = document.getElementById("answer");
let btn = document.querySelector("input[type='button']");
// Set up the click event handler for the button
btn.addEventListener("click", function(){
// Now you need to get the input values and pass them
// to the function that will act with them
pro(inputNum.value, power.value);
});
function pro(n,p) {
var number = parseInt(n);
for(var i = 1; i < p; i++) {
number *= number;
}
answer.textContent = number;
}
</script>
</body>
</html>
Try
document.getElementById("answer").innerHTML = number

Getting value of unknown number of inputs

I have a site generated mainly in PHP. On one page PHP generates a number of dropdowns, the number of which is depending on items in my DB.
The number of dropdowns can change but I want to be able to count them and get the values for each of them in JS/jQuery.
At the moment the dropdowns all have the same class name but I think I'm going to have to try give them all individual IDs.
I know I could the amount of items like this:
var ammount = $(".myclass").length;
I just need some way of looping through these to get the individual values like this, without just picking up the first value of that class each time:
var input =$(".myclass").value;
I think I'm going to have to go with individual IDs being generated by the PHP but was just wondering if there was another way to do it.
$(".myclass").each(function(i,e) {
console.log(e); //e gives you current item in loop
});
or
$(".myclass").each(function() {
console.log($(this).value);
});
You can get the values in an array, by iterating over all these elements and pushing their values to the array:
var vals = [];
$(".myclass").each(function() {
vals.push($(this).val());
});
If you want to get the sum of all these inputs :
var sum = vals.reduce((a,b) => (+a + +b));
Demo:
var vals = [];
$(".myclass").each(function() {
vals.push($(this).val());
});
console.log(vals);
//Calculating sum of values
var sum = vals.reduce((a,b) => (+a + +b));
console.log(sum);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="myclass" value="10" />
<br/>
<input type="text" class="myclass" value="20" />
<br/>
<input type="text" class="myclass" value="30" />
<br/>
<input type="text" class="myclass" value="40" />
<br/>
<input type="text" class="myclass" value="50" />
<br/>

Add Value from One Text Input Field to A Pre Populated Input Field

I have an input field that gets populated by the values of checkboxes in a form. That part works perfectly fine, so the input field labeled total will display the sum of checkbox1 + checkbox2 etc. depending on which boxes are checked. My client added the extra obstacle of having a text input field where users can manually enter any additional costs and this gets added to the sum of total as well.
This is what the form currently looks like:
<div class="checkbox">
<label>
<input type="checkbox" name="checkbox" id="outside" class="sum" value="1" data-toggle="checkbox"/>
Outside Wash
</label>
</div><br/>
<div class="checkbox">
<label>
<input type="checkbox" name="checkbox" id="aclean" class="sum" value="1" data-toggle="checkbox"/>
A - Clean: Wash Vacuum, Windows, Wheels/Tires, Wax
</label>
</div><br/>
<div class="checkbox">
<label>
<input type="checkbox" name="checkbox" id="bclean" class="sum" value="1" data-toggle="checkbox">
B - Clean: Same as A above <em>PLUS:</em> Shampoo Interior, Clean/Dress Interior Panels, Remove Bugs/Tar.
</label>
</div><br/>
<div class="checkbox">
<label>
<input type="checkbox" name="checkbox" id="cclean" class="sum" value="1" data-toggle="checkbox">
C - Clean: Same as B above <em>PLUS:</em> Compound Polish Exterior, Clean/Dress Moldings as Needed.
</label>
</div>
These are the 2 text input fields. The total field currently grabs the sum of those checkboxes. The inputSpecial field is where the user will manually type in any additional charges.
<label for="inputSpecial">Special Price</label><br/>
<input type="special" class="form-controlv sum" id="inputSpecial" placeholder="Enter Price for Any Additional Services">
<label for="total"><strong>Total Price</strong></label><br/>
<input type="text" class="form-control" id="total">
And lastly, here is the javascript that is running behind the form and adding the values. I'd like to build on this code rather than scrapping it for something else.
$(document).ready(function() {
function updateSum() {
$("#total").val($(".sum:checked").length);
}
// run the update on every checkbox change and on startup
$("input.sum").change(updateSum);
updateSum();
})
You want to use parseFloat when adding the value else you will add concatenate a string of numbers.
Checking to see if the value isNaN will also handle any invalid values and use 0 instead of NaN.
Add the change event to handle changed to #inputSpecial as well. Also changed length to value to get valid sum of values.
https://jsfiddle.net/SeanWessell/gwco6uj3/
$(document).ready(function() {
function updateSum() {
var total = 0;
var $special = $('#inputSpecial');
$(".sum:checked").each(function() {
var val = isNaN(parseFloat(this.value)) ? 0 : parseFloat(this.value);
total += val;
})
var addl = isNaN(parseFloat($special.val())) ? 0 : parseFloat($special.val());
$("#total").val(Math.round((total + addl) * 100) / 100);
}
// run the update on every checkbox change and on startup
$("input.sum,#inputSpecial").change(updateSum);
updateSum();
});
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN
You could do it like this:
$("#total").val($(".sum:checked").length + parseFloat($("#inputSpecial").val());
However, I don't think that $(".sum:checked").length is the best way to do the initial summation. It assumes that all four checkboxes have the same monetary value (which is exactly $1).
So you'd probably want something more like:
var sumTotal = 0;
$(".sum:checked").each(function() {
sumTotal += $(this).val();
});
sumTotal += parseFloat($("#inputSpecial").val()
$("#total").val(sumTotal);

How to dynamically add text fields to a form based on a number the user puts in

I'm attempting to make a form that asks the user for a number of units, then asks whether or not they would like those units to be provisioned, and depending on the answer, generates text fields corresponding with the number of units the typed in, along with a text field asking for an account number.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
</script>
<script type="text/javascript">
function Getunits(value) {
var units = document.getElementById('units');
for(count=0; count<=units; count++) {
$("<input type='text'>").appendTo("inpane");
}
document.getElementByTag('futureacc').InnerHTML='What is your account number? <input type="text" value="accountnum">';
}
</script>
</head>
<body>
<div id="container">
<form method="post" action="sendcontact.php">
<div id="unitammount" class="inpane">
Number of units ordered: <input type="text" name="units" id="units"/><br />
</div>
<div id="futureacc" class="inpane">
Are these units to be provisioned? <input type="radio" name="select" value="yes" onClick="Getunits('units.value')"/> Yes <input type="radio" name="select" value="no"/> No
</div>
Obviously I would like the new text fields to appear inside the futureacc div and inpane div respectively.
I don't know whether it's the loop that doesn't do anything or that I'm not appending correctly but as I currently have it this does nothing...
Any help would be greatly appreciated.
You had a number of errors with your code. It was confusing because you were mixing jQuery and pure Javascript. It's generally better to just use jQuery if you've decided to use it anyway. Your loop should have been iterating while it was smaller than units.val(), not while it was smaller than or equal to units. innerHTML is spelled with a lowercase "i," and your appendTo selector needed a period before the class name. I went ahead and cleaned up your code so it should work now!
HTML:
<div id="container">
<form method="post" action="sendcontact.php">
<div id="unitammount" class="inpane">
Number of units ordered: <input type="text" name="units" id="units"/>
</div><br>
<div id="futureacc" class="inpane">
Are these units to be provisioned? <input type="radio" name="select" value="yes" onClick="getUnits()"/> Yes <input type="radio" name="select" value="no"/> No <br>
</div>
</form>
</div>​
Javascript:
function getUnits() {
var units = $("#units").val();
for (var count = 0; count < units; count++) {
$("<input type='text' /><br>").appendTo("#futureacc");
}
$("#futureacc").append('<br>What is your account number? <input type="text" placeholder="accountnum">');
}​
WORKING DEMO
var units = document.getElementById('units');
needs to be
var units = document.getElementById('units').value;
you are passing value to onclick but it is a string will not give you exact value anyway you are not using it in you function so it doesnt have any side effect.
also you need to some error check to make sure that user has entered a number
with
for(count=0; count<=units; count++)
You are adding 1 more text box than user entered value. so if user has entered 4 you are creating 5 <= should be changed to <
This is wrong
onClick="Getunits('units.value')"
Instead use this:
onClick="Getunits(units.value)"
try this
$(document).ready(function(){
$('input[name=select]').click(function(){
if($(this).val() ==='yes'){
var numberOfTextboxes = $('#units').val();
for(var i =0; i<numberOfTextboxes; i++){
$('#unitammount').append('<input type="text" />');
}
}
});
});
See the fiddle

Categories