I am attempting to make my first attempt at Javascript taking user input and then changing the html of an element to spit out a value. It's a calorie calculator. Here's my HTML, my javascript, and an explanation of what I think is SUPPOSED to happen with my limited knowledge:
<center>
<p>Fill out the form below.</p>
<input type="radio" name="female" value="665.09" oninput="calsPerDay" ><p>Female</p>
<input type="radio" name="male" value="66.47" oninput="calsPerDay" ><p>Male</p>
<input id="age" type="number" oninput="calsPerDay"><p>Age</p><br>
<input id="height" type="number" oninput="calsPerDay"><p> Height- In Inches (12 inches=1 foot)</p>
<input id="weight" type="number" oninput="calsPerDay"><p> Weight (in pounds)</p><br>
</center>
<p id="totalCals"> </p> <p>kcal per day</p>
function calsPerDay() {
var age=document.getElementById("age").value;
var height=document.getElementById("height").value;
var weight=document.getElementById("weight").value;
var female=document.getElementsByName("female").value;
var male=document.getElementsByName("male").value;
if (document.getElementsByName("male").checked) {
var maleCals = male+ (13.75 * weight/2.2) + (5.0 * (height * 2.54) - (6.75 x age);
document.getElementById("totalCals").innerHTML = maleCals;
} else (document.getElementsByName("female").checked) {
var femaleCals = female + (9.56 * weight/2.2) + (1.84 * (height * 2.54) - (4.67 x age);
document.getElementById("totalCals").innerHTML = femaleCals;
}
}
What I expect to happen is that the function will first check if the user has checked off male or female. Then if they check off male, it creates a new variable (not sure if this would be the most optimal way to do this anyway0 where it adds male (because I put var male = document.getElementsByName("male").value and its a radio type input, I read that it would read what you put as the value so I assumed that "male" in the variable maleCals would become that value, 66.47. Then I assumed the height and weight would be read as whatever the number the user puts in the input forms and then be spit out as a paragraph for the <p> element with the id of totalCals.
Here's a JS fiddle for it: https://jsfiddle.net/oafu54x3/
My dilemma is that it simply isn't working, when you put in values, nothing's being written in the <p> tags.
Any suggestions would be helpful.
The problem is when you use getElementsByName, it returns an object array not the object you are looking for.
You should use getElementById for those too.
There are numerous problems.
Lets's start by cleaning up the HTML:-
<h1>Fill out the form below.</h1>
<label>Female:
<input id="female" type="radio" name="gender" onchange="calsPerDay()">
</label>
<label>Male:
<input id="male" type="radio" name="gender" onchange="calsPerDay()" checked>
</label>
<label>Age:
<input id="age" type="number" oninput="calsPerDay()" value="50">
years
</label>
<label>Height:
<input id="height" type="number" oninput="calsPerDay()" value="70">
in inches (12 inches=1 foot)
</label>
<label>Weight:
<input id="weight" type="number" oninput="calsPerDay()" value="225">
in pounds
</label>
<label>
Base metabolic rate: <span id="totalCals"></span> kcal per day
</label>
By placing the input elements inside label tags, the user can now click anywhere in the label to give the contained input element focus.
Note also that both the radio buttons need to have the same name attribute. So in order to differentiate between them, they need to have different id attributes.
On some browsers you need to place () at the end of each event handler name. If you can't predict which browser will be used by the client, then it is better to play it safe. So always include them.
To make testing easier, I have added a selected attribute to the male radio button, and default value attributes to the other input elements. Please feel free to remove them before deployment.
The value attributes on the radio buttons are really things that belong in the model (i.e. javascript) not in the view (i.e. html).
Now add a bit of style in CSS:-
label {
display: block;
box-shadow: 0.1em 0.1em 0.2em #888;
margin: 1em;
border-radius: 1ex;
padding: 1ex 1em;
}
input[type=number] {
text-align: right;
border: none;
}
input {
float: right;
}
span {
font-weight: bold;
}
And finally clean up the Javascript:-
function calsPerDay() {
function find(id) { return document.getElementById(id) }
var age = find("age").value
var height = find("height").value * 2.54
var weight = find("weight").value / 2.2
var result = 0
if (find("male").checked)
result = 66.47 + (13.75 * weight) + (5.0 * height - (6.75 * age))
else if (find("female").checked)
result = 665.09 + (9.56 * weight) + (1.84 * height - (4.67 * age))
find("totalCals").innerHTML = Math.round( result )
}
calsPerDay()
I know many people won't agree but I personally find code duplication distracting. In your code document.getElementById(id) is repeated often. So I have extracted that behaviour out into a little helper function find. Now the rest of the code reads so much better.
Because you apply the same scaling factor to weight, height regardless of the gender, I moved that scaling out, and now it is no longer duplicated.
Notice that I assumed the missing closing braces should go at the end of the formulae. I can't check this as I don't have access to the source document where you discovered these formulae.
You also used "x" inside a formula instead of "*". This is a common mistake as one transitions from written algebra to computer algorithms. Take care on this one.
Lastly I have removed all those unnecessary (and distracting) semicolons. In Javascript there are only a few rare occasions where you actually must use semicolons.
You can see a working CodePen here
Related
I've got a bit of an interesting mathematical puzzle to solve.
I'm writing a test to verify that values outside of a range of a field in a window are not allowed to be input. For the most part this is extremely easy.
I'm using a function like this:
function getRanInt(min, max)
{
let min = Math.ceil(min);
let max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min);
}
to set the range of "erroneous" values I want to test.
However, there is one field which throws a wrench in this method. One field has constraints on each digit. So the first digit can only be between 0-7 and the second digit can only be between 0-3.
My first thought was to simply concatenate two numbers together that I could separately constrain like this:
let m1_1;
let m1_2;
m1_1 = getRanInt(8,9);
m1_2 = getRanInt(4,9);
m1 = m1_1.toString() + m1_2.toString();
m1 = Number(m1);
until I thought about it for half a second and realized that this would only get me erroneous values > 83 but leave out an entire array of possible erroneous values like 24, 36, 18 etc...
I've been wracking my brain to try and come up with a solution that isn't massively convoluted but I've been drawing a blank. I thought I'd turn to you fine braniacs here and see if you could maybe help unstick my gears.
ADDITIONAL: If anyone's interested, the tool tip for the field in question explicitly says this:
2 Digits:
1st = 0 - 7
2nd = 0 - 3
To test all the incorrect values, you can combine solution that provided by you with the second set of values, that are accessible using your functions in the following way:
let result;
if(Math.round(Math.random()))
{
let m1_1;
let m1_2;
m1_1 = getRanInt(8,9);
m1_2 = getRanInt(0,9);
let m1 = m1_1.toString() + m1_2.toString();
result = Number(m1);
}
else
{
let m2_1;
let m2_2;
m2_1 = getRanInt(0,7);
m2_2 = getRanInt(4,9);
let m2 = m2_1.toString() + m2_2.toString();
result = Number(m2);
}
I just wonder why the users can fill in the wrong values in the first place.
You can stop this from happening either by restricting the numbers the user can put in an input, by using a number input, or a range slider.
I will show you how it can look like below, but you can go even further and override any input the user have done, based on a pattern or min and max value - or to check if the input validates.
The slider doesn't need extra code so that's probably the preferred way.
function updateLabel(rangeId, rangeValue) {
let labelElement = document.getElementById(rangeId + "label");
if (labelElement) {
labelElement.innerHTML = rangeValue;
}
}
label {
display: none;
font-size: 0.8rem;
}
input:invalid + label,
.range-container > label {
display: inline-block;
}
.range-container {
display: flex;
align-items: center;
}
<h4>Text Input</h4>
<div>
<input type="text" placeholder="0-7" maxlength="1" pattern="[0-7]{1}">
<label>A number between 0 and 7 is required.</label>
</div>
<div>
<input type="text" placeholder="0-3" maxlength="1" pattern="[0-7]{1}">
<label>A number between 0 and 3 is required.</label>
</div>
<hr/>
<h4>Number Input</h4>
<div>
<input type="number" placeholder="0-7" min="0" max="7">
<label>A number between 0 and 7 is required.</label>
</div>
<div>
<input type="number" placeholder="0-3" min="0" max="3">
<label>A number between 0 and 3 is required.</label>
</div>
<hr/>
<h4>Range Slider</h4>
<div class="range-container">
<input type="range" oninput="updateLabel(this.id, this.value)" id="first" min="0" max="7" value="0">
<label id="firstlabel">0</label>
</div>
<div class="range-container">
<input type="range" oninput="updateLabel(this.id, this.value)" id="second" min="0" max="3" value="0">
<label id="secondlabel">0</label>
</div>
I'm new to web programming, and I have been trying to do a true/false test, and when the answers are submitted, the answers change colors depending if it's correct or not.
At first, I used labels for each input:
<h3>1. Father Christmas and Santa Claus are the same man</h3>
<input type="radio" id="1bon" name="q1" value="Non" >
<label for="1bon" > True </label> <!-- label is for css -->
<input type="radio" id="1non" name="q1" value="Bon">
<label for="1non" > False </label><br/>
And in the css, I used " input[value=Bon] + label" or "input[value=Non] +label" with a "background color : blue ", and in a JS, I used label[i].style.background to change the color. It's does change the color, but only of the radio button, and when not checked, which is exactly what I'm trying to do. It comes from the fact I don't know how to select the label of a precise input[x=y]:selector.
So I rewrote the whole thing without any labels
<h3>1. Father Christmas and Santa Claus are the same man </h3>
<input type="radio" class="input" id="1bon" name="q1" value="Non"> True
<input type="radio" class="input" id="1non" name="q1" value="Bon"> False
With new css:
.input {
background-color: #fff;
display:inline-block;
width:5%;
padding:10px;
border:1px solid #ddd;
margin-bottom:10px;
cursor:pointer; /* new selectoon type */
}
.input:checked{
background-color: #4876ff;
}
So, when just checked, it is blue, but when the answers are submitted, depending of the value of the input, it change the color of the class:checked.
It there any way do modify the style of a class with a selector in javascript ?
Also, if the user decides to change his answer for a question, the checked have to go back to being color neutral.
Thank you for your help.
You can use this function to change class of element as you explained earlier. But changing color of checkbox is not possible without using third party plugin or customized elements. Please check this link
function Test2($this){
var radios = document.getElementsByName('q1');
for(i=0; i< radios.length; i++){
var element = radios[i];
element.classList.remove("correctAnswer");
element.classList.remove("wrongAnswer");
}
if($this.value === "Non"){//Assume "Non" is correct answer
$this.classList.add("correctAnswer");
}else{
$this.classList.add("wrongAnswer");
}
}
I'm currently taking a beginner's course on Javascript. I just started coding about a week ago, and was given this prompt to use what I know so far to get data from forms etc.
I've run into a block, and the instructor told me I had to figure it out on my own but… I've been stuck on it for hours, just glancing at the materials and trying to search the internet for answers!! I know I have to use onchange, but I'm completely lost on the rest. I did the best that I could at this stage, but I'd really appreciate some help! Sorry for the super beginner/extra long question!
For the prompt, I was given a form and told to recreate it. After sorting out all the HTML, I have to:
Make sure everything starts out with no values.
Make sure the reset button works.
When choosing "male" in the "gender" category, the "hobby" row with "dance", "travel", and "photography" is hidden. The background color of the "soccer" and "futsal" row becomes blue.
When choosing "female" in the "gender" category, the "soccer" and "futsal" lines are hidden, and the background color of the "dance", "travel", "photography" line turns yellow.
When choosing "blank" from the "gender" category, both lines of "hobby" should be displayed, and the background color should be white.
Note: I don't think my HTML shows the rows for the "hobby" correctly, but it should be like:
- Soccer - Futsal
-Dance - Travel -Photography
<style>
h1 {
text-align: center;
}
.pink {
background-color: pink;
}
body {
border: 2px;
}
</style>
<script>
function clr() {
var t1 = document.info.lfname.value="";
var t2 = document.info.gender.value="";
var t3 = document.info.hobby.value="";
}
<p>Last name (Chinese):</p>
<form name="info">
<input type="text" name="lfname">
First name (Chinese):
<input type="text" name="lfname"><br>
<p>Last name (alphabet):</p>
<input type="text" name="lfname">
First name (alphabet):
<input type="text" name="lfname"><br><br>
Gender:
<select name="gender" onchange="hide()">
<option value=""></option>
<option value="man">Male</option>
<option value="woman">Female</option><br>
</select>
<p>Hobbies:</p>
<input type="checkbox" name="hobby" value="soccer">Soccer
<input type="checkbox" name="hobby" value="futsal">Futsal
<input type="checkbox" name="hobby" value="dance">Dance
<input type="checkbox" name="hobby" value="travel">Travel
<input type="checkbox" name="hobby" value="photo">Photography<br><br><br>
<input type="reset" class="pink" value="Reset" onclick="clr()">
<input type="submit" class="pink" value="Submit">
</form>
I'm avoiding giving you the full solution, so you can learn yourself but I have a few tips to put you in the right direction.
First you should make a css class hidden. This contains the following css
.hidden {
display:none
}
This is just to make your life a little easier.
You can get any element in javascript by adding an id as attribute, so for example:
HTML:
<input type="checkbox" name="hobby" value="soccer" id="soccer">
Javascript:
var HTMLelement = document.getElementById('soccer');
You can also add classes to elements in javascript
HTMLelement.classList.add("hidden");
As last tip, you can check whether the checked value is true or false. Based on this if structure add the class or not.
if ( HTMLelement.checked == true) {
do something
}
I hope this helps you, I will answers your comments if u have questions
Good luck!
As I see, most of the answers are giving you some hints, and that's ideal in your case as you supposed to do your homework by yourself, so I tried to push it further by giving you a working example, i'll comment each line of code to let you understand, but keep in mind I'll be using some advanced JavaScript stuff that requires digging into the JavaScript language in order to get more familiar with, and also you'd really have to search by yourself for how the methods/attributes that'll be using work in order to, firstly and most importantly to get some more knowledge in this language, and secondly to have answers for your teachers questions when they, probably, ask what do these things do.
Sorry for being little bit aggressive, here's a demo on how you'll get your job done.
// select the dropdown, male and female hobbies sections based on the IDs that we already gave to each one.
var gender = document.getElementById('gender'),
maleHobbies = document.getElementById('male-hobbies'),
femaleHobbies = document.getElementById('female-hobbies');
// adding change event listener to the dropdown.
gender.addEventListener('change', function() {
if(this.value === 'man') {
/**
* when 'Male' is selected on the dropdown(based on the value of the relevant checkbox):
* 1. add 'hidden' class to the female hobbies section to hide it.
* 2. remove the 'hidden' class from the male hobbies section to show it if it was hidden.
3. add the 'blue' class from the male hobbies section.
**/
femaleHobbies.classList.add('hidden');
maleHobbies.classList.remove('hidden');
maleHobbies.classList.add('blue');
} else if(this.value === 'woman') {
/**
* when 'Female' is selected on the dropdown(based on the value of the relevant checkbox):
* 1. add 'hidden' class to the male hobbies section to hide it.
* 2. remove the 'hidden' class from the female hobbies section to show it if it was hidden.
3. add the 'yellow' class from the female hobbies section.
**/
maleHobbies.classList.add('hidden');
femaleHobbies.classList.remove('hidden');
femaleHobbies.classList.add('yellow');
} else {
/**
* when the empty option is selected:
* remove the 'hidden' class from both the male and female hobbies sections.
* remove the 'blue' and 'yellow' classes from the male and female hobbies sections respectively.
**/
maleHobbies.classList.remove('blue', 'hidden');
femaleHobbies.classList.remove('yellow', 'hidden');
}
});
.pink {
background-color: pink;
}
/* 'hidden' class is used to hide an element by giving it a 'display' property of 'none'. */
.hidden {
display: none;
}
/* 'blue' class is used to make the male hobbies section background as blue */
.blue {
background-color: blue;
}
/* 'blue' class is used to make the female hobbies section background as yellow */
.yellow {
background-color: yellow;
}
<!--
I made some changes to your HTML:
- surrounded each checkbox inputs in a label tag with for attribute pointing to the corresponding input, soand you can click the text and the checkbox will check/uncheck.
- Added an ID to each checkbox input
- surrounded the corresponding checkboxes in a div, thus making row for male hobbies and row for female hobbies, each row(div tag) has a unique ID.
-->
<p>Last name (Chinese):</p>
<form name="info">
<input type="text" name="lfname" />
First name (Chinese):
<input type="text" name="lfname" /><br>
<p>Last name (alphabet):</p>
<input type="text" name="lfname" />
First name (alphabet):
<input type="text" name="lfname" /><br><br>
Gender:
<select name="gender" id="gender">
<option value=""></option>
<option value="man">Male</option>
<option value="woman">Female</option>
</select>
<p>Hobbies:</p>
<div id="male-hobbies">
<label for="soccer"><input type="checkbox" name="hobby" id="soccer" value="soccer" />Soccer</label>
<label for="futsal"><input type="checkbox" name="hobby" id="futsal" value="futsal" />Futsal</label>
</div>
<div id="female-hobbies">
<label for="dance"><input type="checkbox" name="hobby" id="dance" value="dance" />Dance</label>
<label for="travel"><input type="checkbox" name="hobby" id="travel" value="travel" />Travel</label>
<label for="photography"><input type="checkbox" name="hobby" id="photography" value="photo" />Photography</label>
</div>
<input type="reset" class="pink" value="Reset" />
<input type="submit" class="pink" value="Submit" />
</form>
Some hints for you:
you don't need to create a function that resets each input field as
the input[type="reset"](input with the type of reset) will do it
for you.
In order to make my demo work for you you have to either: paste the JavaScript code in a script tag and put that script just before </body>, or you can paste it in a seperate file then include it and again put the script tag that has the src to the file(that has the JavaScript code with .js extension) just before </body>.
And here are some useful links that may(indeed they'll do) help you:
Learn more more about getElementById method.
Learn more more about addEventListener method.
Learn more more about classList attribute and its methods(add, remove and more).
Hope I pushed you further.
Welcome to StackOverflow!
As it is for your course. It is intended to teach you something. So don't expect ready solution. I will give you some hints instead:
As someone mentioned in comments, you have missing closing HTML tags
<script>...your code here...</script>
As #ths mentioned, input is already self closing tag.
It is good practice (it sometimes depends on technology but for pure JS/HTML it is really good practice) to give HTML elements some unique IDs:
<input id="soccer" type="checkbox" name="hobby" value="soccer">Soccer
You can use
const soccerCheckbox = document.getElementById("soccer");
to obtain reference for some HTML elements, which you will use for further operations.
The easiest way to hide an element:
soccerCheckbox.hidden = true;
#Wimanicesir provided more elegant solution: https://stackoverflow.com/a/52630428/1944056
To append event listener:
const genderSelect= document.getElementById("gender");
genderSelect.onchange = function () {
//here you can show/hide appropriate elements
}
Another possibility: https://stackoverflow.com/a/4029360/1944056
To get the current value of dropdown:
document.getElementById("gender").value
It is important to enclose all your Javascript code into:
document.onload = function () {
...
}
To wait until all HTML elements are accessible
Good luck for your course!
This is my textbox that I have:
This is the code for it :
<!-- Preferred credit limit -->
<div class="signup-card-section">
<h2 class="accordion-header boldtext">Tell Us Your Preferred Credit Limit</h2>
<div class="column-control no-padding twelve colgrid">
<fieldset>
<div class="row">
<p class="text-red">(Choose one)</p>
<p>My Preferred Credit Limit<span class="text-red">*</span></p>
<br>
<input type="radio" name="prefcreditlimit" checked="checked" value="yesprefcreditlimit" id="yesprefcreditlimit">
<span class="radiotextdeco">S$</span> <input type="text" class="input numeric-only nodecimal width30" name="prefcreditlimitval" id="prefcreditlimit" min="100"> <span style="font-size:12px;"> (Must be in multiples of 00’ and a minimum of S$100)</span><br><br>
<input type="radio" name="prefcreditlimit" checked="checked" value="noprefcreditlimit"> <span class="radiotextdeco">I dont have a preferred credit limit and agree to any credit limit determined</span><br><br>
<p><strong>Note:</strong> Principal applicant and Suplementary applicant will be granted the preferred credit limit of any limit determined by the bank, whichever is lower.</p>
</div>
</fieldset>
</div>
</div>
Error message to appear if value key in is not in multiples of 00’ or minimum of S$100: “Your Preferred Credit Limit must be in multiple of 00’ and a minimum of S$100.
Since I set the min value to 100. There's an error message appear when user enters less 100. The problem is now, I'm not sure how to check for the validation of 00'
Any help would be appreciated.
Use <input type="number"> along with the min and step attributes:
<input type="number" name="prefcreditlimitval" min="100" step="100">
If the user enters a value lower than the min or something that isn't a multiple of step, the browser's validation will prevent the form from being submitted. In browsers that don't support validation, you can use a polyfill (like this one).
You can test out the validation (though SO doesn't allow forms to run):
input:invalid {
border-color: red;
}
Input multiples of 100<br><br>
<input type="number" name="test" min="100" step="100">
Input tag also has 'pattern' attribute, where you can specify Regex pattern to check input.
So something like
<input type="text" class="input numeric-only nodecimal width30" name="prefcreditlimitval" id="prefcreditlimit" min="100" pattern="\d+00$">
should work!
Some info about input's pattern attr
As mentioned in other answers, you may use min and step attributes to limit value of input field. But these attributes were introduced as a part of HTML 5 standards and it is not supported in all browsers yet.
A generic solution using jQuery/JS to check input value and give error message if it does not meet your requirements can be written as follows.
function validate() {
var value = $("#prefcreditlimit").val();
if (isNaN(value) || value < 100 || value % 100 != 0) {
alert("Please provide a valid input");
$("#prefcreditlimit").val("");
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="radiotextdeco">S$</span>
<input type="text" class="input numeric-only nodecimal width30" name="prefcreditlimitval" id="prefcreditlimit" min="100" onblur="validate()"> <span style="font-size:12px;"> (Must be in multiples of 00’ and a minimum of S$100)</span>
You could add some validation in Javascript, checking whether the input is indeed a number, if so then check if it's also at least 100 and if so, check if the input is a multitude of 100. You can do it like this:
var val = parseInt($("#prefcreditlimit").val(), 10);
if (isNaN(val))
{
// ERROR; NOT A NUMBER
}
else if (val < 100)
{
// ERROR; VALUE IS LOWER THAN 100
}
else if (val % 100 !== 0)
{
// ERROR; VALUE IS NOT A MULTITUDE OF 100
}
It seems you want the value to be greater than 100 and a multiple of 100. Seeing as you have tagged the question with jQuery I have done a jQuery example for you.
I am listening for changes on the textfield using .change().
jQuery("#prefcreditlimit").change(function () { ... });
I am using jQuery(this).val(); or jQuery("#prefcreditlimit").val(); to get the current value of the textfield .val()
From your comments, I have updated to first check that the radio button is checked first using !jQuery("#yesprefcreditlimit").is(':checked') which says if the checkbox is not checked.
Then I use simple logic checks first checking if the value is a number isNaN(value) then if value < 100 is less than 100. Then if value % 100 > 0 if the modulus of the value is greater than 100.
There definitely a lot more you could go here, and a lot of different ways you could do this, this is just one way. For example you might not want the change part of this and instead do the validation on the submit of the form.
Note: In the stack snippet you need to click out of the textbox for the change event to be triggered.
jQuery(function () {
jQuery("#prefcreditlimit").change(function () {
var value = jQuery(this).val();
if(!jQuery("#yesprefcreditlimit").is(':checked')) {
jQuery("#warning").text("");
return;
}
if(isNaN(value)) {
jQuery("#warning").text("Value is not a number.");
return;
}
if(value < 100) {
jQuery("#warning").text("Value is less than 100");
return;
}
if(value % 100 > 0) {
jQuery("#warning").text("Value needs to be a multiple of 100");
return;
}
jQuery("#warning").text("Value: " + value + " is Okay!");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>My Preferred Credit Limit<span class="text-red">*</span></p>
<br>
<input type="radio" name="prefcreditlimit" checked="checked" value="yesprefcreditlimit" id="yesprefcreditlimit">
<span class="radiotextdeco">S$</span> <input type="text" name="prefcreditlimitval" id="prefcreditlimit" min="100"> <span style="font-size:12px;"> (Must be in multiples of 00’ and a minimum of S$100)</span><br><br>
<input type="radio" name="prefcreditlimit" checked="checked" value="noprefcreditlimit"> <span class="radiotextdeco">I dont have a preferred credit limit and agree to any credit limit determined</span><br><br>
<p id="warning"></p>
If you have no problem using input type number you can use, step attribute
step = "any" or positive floating-point number NEW specifies the value granularity of the element’s value.
If step is not explicitly included, the value of step defaults to 1, as if it were included with step="1" (or step="100" in the case of type="time"), even if the default value or min value is a float.
<input type="number" class="input numeric-only nodecimal width30" name="prefcreditlimitval" id="prefcreditlimit" min="100" step="100">
I am trying to make a form that generates a value based on weighted inputs. For example, if we had the following in the database
**Item** _|_**Weight**
sink | 1.5
toilet | 2.5
shower | 3
And a form that looked like this, built from the database, using AJAX (Has to be built using AJAX, because the inputs' names and the number of inputs varies depending on a user selection in a previous section of the form)
<form id="calculator">
...There are several field sets here...
<fieldset id="myFields">
<input type="text" class="iteminput" data-weight="1.5" name="sink" id="sink">
<input type="text" class="iteminput" data-weight="2.5" name="toilet" id="toilet">
<input type="text" class="iteminput" data-weight="3" name="shower" id="shower">
</fieldset>
</form>
If the user puts in that they have X sinks, Y toilets, and Z showers, I want to automatically calculate the total "value" of their plumbing system, in this case, X*1.5+Y*2.5+Z*3.
Where I am hung up is on how to get the value of each input. What I want to be able to do is loop through all of the inputs in #myFields, get the value of the field, as well as the value of the data-weight attribute, multiply them together, then add them to a running total. I would like to do all of this in a function attached to the onKeyUp event for each input.
Any help is appreciated, and more information can be provided if necessary.
Javascript only solution would be best, but I am not against using jQuery if it drastically simplifies the answer.
Here is a jQuery example:
You should be able to get the values of the inputs on a blur function. And then update the values by running an each function on the inputs. Something like this...
<ul>
<li>
<label>Number of X</label>
<input type="text" value="" id="x"/>
</li>
<li>
<label>Number of Y</label>
<input type="text" value="" id="y"/>
</li>
<li>
<label>Number of Z</label>
<input type="text" value="" id="z"/>
</li>
</ul>
<p>Total is: <span class="total"></span>
jQuery:
$('input').blur(function () {
var total = 0;
$('input').each(function() {
total += Number($(this).val());
});
$('.total').text(total);
});
DEMO:
http://jsfiddle.net/DYzsR/1/
This is what I ended up doing.
function calcFixtures()
{
var elements = [];
var total = 0;
elements = document.getElementsByClassName('fixtureinput');
for (var i=0; i<elements.length; i++) {
total += elements[i].value * elements[i].getAttribute("data-weight");
}
}
Logic being, get all elements with a certain class, loop through them, and for each element, get the value of the data-weight attribute and multiply it by the current form value for that element. Thanks to #Kris for the idea of doing it as a running total rather than a single calculation. That was really the breakthrough point.