I've read a lot about uncaught reference errors here and think I have the idea down - when the script is trying to call a function or reference a variable that hasn't been initialized yet. However, I am uncertain how to fix this, and why in my case one function works and the other doesn't.
I have one JS file with two functions in it, and one HTML file with a form. The form calls function1 onSubmit, and that works fine. A radio button inside of the form calls function2 onClick, and that's when I get the error:
Uncaught ReferenceError: toggleGender is not defined onclick # forms.html:20
Why would my first function work and not the second? It seems to me like they are operating under the same premise.
function calculatePFT()
{
var userForm = document.getElementById('userValues');
var pullups = userForm.userPullups.value;
var crunches = userForm.userCrunches.value;
var runMinutes = userForm.userMinutes.value;
var runSeconds = userForm.userSeconds.value;
var runScore = 0;
if(runMinutes < 18) { runScore = 100; }
else
{
var minDiff = runMinutes - 18;
var minPoints = minDiff * 6;
var secPoints = Math.ceil(runSeconds/10);
runScore = 100 - (minPoints + secPoints);
}
var score = parseInt(pullups*5) + parseInt(crunches) + parseInt(runScore);
document.getElementById('scoreBox').innerHTML = "You scored " + pullups + " pullups and " + crunches + " crunches and a run time of " + runMinutes + " minutes " + runSeconds + " seconds. TOTAL SCORE: " + score;
}
function toggleGender(var gender)
{
alert("Inside");
var maleForm = document.getElementById('male');
var femaleForm = document.getElementById('female');
if(gender == "f")
{
alert("Female");
maleForm.style.display = 'none';
femaleForm.style.display = 'block';
}
else
{
alert("Male");
maleForm.style.display = 'block';
femaleForm.style.display = 'none';
}
}
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Javascript Testing</title>
<link rel="stylesheet" href="style.css" />
<script src="scripts.js"></script>
</head>
<body>
<section id="wrapper">
<h3>PFT Calculator</h3>
<form action="#" id="userValues" method="post" onSubmit="calculatePFT()">
<div id="gender">
<span class="maleFemale">Male <input type="radio" name="maleFemale" value="male" CHECKED onClick="toggleGender('m')" /></span>
<span class="maleFemale">Female <input type="radio" name="maleFemale" value="female" onClick="toggleGender('f')" /></span>
</div>
<div id="male">
<div class="scoreLine">
<div class="label">Pullups:</div>
<div class="entry"><input type="number" name="userPullups" min="0" max="20" default="18" class="scoreEntry" required /></div>
</div>
</div>
<div id="female">
<div class="scoreLine">
<div class="label">Hang:</div>
<div class="entry"><input type="number" name="userHang" min="0" max="150" default="70" class="scoreEntry" required /></div>
</div>
</div>
<div class="scoreLine">
<div class="label">Crunches:</div>
<div class="entry"><input type="number" name ="userCrunches" min="0" max="100" default="100" class="scoreEntry" required /></div>
</div>
<div class="scoreLine">
<div class="label">Run (Minutes):</div>
<div class="entry"><input type="number" name="userMinutes" min="0" max="100" default="19" class="scoreEntry" required /></div>
</div>
<div class="scoreLine">
<div class="label">Run (Seconds):</div>
<div class="entry"><input type="number" name="userSeconds" min="0" max="59" default="30" class="scoreEntry" required /></div>
</div>
<div style="text-align:center;"><input type="submit" value="Calculate Score!" id="submitButton" /></div>
</form>
<span id="scoreBox"></span>
</section>
</body>
</html>
function toggleGender(var gender)
You have a syntax error here. Argument names should not be prefixed by var. This causes the functional declaration to fail (hence why you get a reference error when you try to call it).
function calculatePFT()
{
var userForm = document.getElementById('userValues');
var pullups = userForm.userPullups.value;
var crunches = userForm.userCrunches.value;
var runMinutes = userForm.userMinutes.value;
var runSeconds = userForm.userSeconds.value;
var runScore = 0;
if(runMinutes < 18) { runScore = 100; }
else
{
var minDiff = runMinutes - 18;
var minPoints = minDiff * 6;
var secPoints = Math.ceil(runSeconds/10);
runScore = 100 - (minPoints + secPoints);
}
var score = parseInt(pullups*5) + parseInt(crunches) + parseInt(runScore);
document.getElementById('scoreBox').innerHTML = "You scored " + pullups + " pullups and " + crunches + " crunches and a run time of " + runMinutes + " minutes " + runSeconds + " seconds. TOTAL SCORE: " + score;
}
function toggleGender(gender)
{
alert("Inside");
var maleForm = document.getElementById('male');
var femaleForm = document.getElementById('female');
if(gender == "f")
{
alert("Female");
maleForm.style.display = 'none';
femaleForm.style.display = 'block';
}
else
{
alert("Male");
maleForm.style.display = 'block';
femaleForm.style.display = 'none';
}
}
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Javascript Testing</title>
<link rel="stylesheet" href="style.css" />
<script src="scripts.js"></script>
</head>
<body>
<section id="wrapper">
<h3>PFT Calculator</h3>
<form action="#" id="userValues" method="post" onSubmit="calculatePFT()">
<div id="gender">
<span class="maleFemale">Male <input type="radio" name="maleFemale" value="male" CHECKED onClick="toggleGender('m')" /></span>
<span class="maleFemale">Female <input type="radio" name="maleFemale" value="female" onClick="toggleGender('f')" /></span>
</div>
<div id="male">
<div class="scoreLine">
<div class="label">Pullups:</div>
<div class="entry"><input type="number" name="userPullups" min="0" max="20" default="18" class="scoreEntry" required /></div>
</div>
</div>
<div id="female">
<div class="scoreLine">
<div class="label">Hang:</div>
<div class="entry"><input type="number" name="userHang" min="0" max="150" default="70" class="scoreEntry" required /></div>
</div>
</div>
<div class="scoreLine">
<div class="label">Crunches:</div>
<div class="entry"><input type="number" name ="userCrunches" min="0" max="100" default="100" class="scoreEntry" required /></div>
</div>
<div class="scoreLine">
<div class="label">Run (Minutes):</div>
<div class="entry"><input type="number" name="userMinutes" min="0" max="100" default="19" class="scoreEntry" required /></div>
</div>
<div class="scoreLine">
<div class="label">Run (Seconds):</div>
<div class="entry"><input type="number" name="userSeconds" min="0" max="59" default="30" class="scoreEntry" required /></div>
</div>
<div style="text-align:center;"><input type="submit" value="Calculate Score!" id="submitButton" /></div>
</form>
<span id="scoreBox"></span>
</section>
</body>
</html>
Related
I'm getting undefined of my variable 'base' which is basic $('slider').value. I have added a console.log(base) to test what is returned, but the value is undefined.
Here is my html:
jQuery(document).ready(function($) {
let precentage = 17.5;
let commision = 0.2746;
function cost() {
let base = $('#slider').value;
let precentAmout = base * (precentage / 365 * 30);
let commisionAmout = base * commision;
let totalCost = commisionAmout + precentAmout;
let totalSum = base + commisionAmout + precentAmout;
console.log(base);
$('#cost').text(totalCost);
$('#sum').text(totalSum);
}
$('#slider').on('change', function() {
$('#amout').text(this.value);
cost();
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="calc">
<div class="range-title">
<h2 class="range-label">Ile chcesz pożyczyć?</h2>
<div class="display-wrap">
<span id="amout">500</span><span class="currency"> zł</span>
</div>
</div>
<div class="range-wrap">
<button class="buttons-change-value">-</button>
<input id="slider" class="range-input" type="range" min="500" max="1500" step="50" value="500">
<button class="buttons-change-value">+</button>
</div>
<div class="summary-container">
<div class="summary-box">
<h3>Koszt:<br>
<span id="cost">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>Do zwrotu:<br>
<span id="sum">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>RRSO:<br>
<span id="rrso">200</span><span class="percentage"> %</span></h3>
</div>
</div>
</div>
Do You have an idea why this is happening?
In JQuery, .val() function is available to get value of textbox.
let base = $('#slider').val()
jQuery(document).ready(function($) {
let precentage = 17.5;
let commision = 0.2746;
function cost() {
let base = $('#slider').val();
let precentAmout = base * (precentage / 365 * 30);
let commisionAmout = base * commision;
let totalCost = commisionAmout + precentAmout;
let totalSum = base + commisionAmout + precentAmout;
console.log(base);
$('#cost').text(totalCost);
$('#sum').text(totalSum);
}
$('#slider').on('change', function() {
$('#amout').text(this.value);
cost();
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="calc">
<div class="range-title">
<h2 class="range-label">Ile chcesz pożyczyć?</h2>
<div class="display-wrap">
<span id="amout">500</span><span class="currency"> zł</span>
</div>
</div>
<div class="range-wrap">
<button class="buttons-change-value">-</button>
<input id="slider" class="range-input" type="range" min="500" max="1500" step="50" value="500">
<button class="buttons-change-value">+</button>
</div>
<div class="summary-container">
<div class="summary-box">
<h3>Koszt:<br>
<span id="cost">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>Do zwrotu:<br>
<span id="sum">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>RRSO:<br>
<span id="rrso">200</span><span class="percentage"> %</span></h3>
</div>
</div>
</div>
jQuery objects don't have a value property, they have a val() method.
You can always pass the base variable value as a parameter to the cost function like this cost(this.value). That would make more sense since you are already fetching the slider value once via onChange no need to do it again inside the cost function.
Please take a look at the working snippet below.
jQuery(document).ready(function ($) {
let precentage = 17.5;
let commision = 0.2746;
function cost(sliderValue) {
let base = sliderValue;
let precentAmout = base * (precentage / 365 * 30);
let commisionAmout = base * commision;
let totalCost = commisionAmout + precentAmout;
let totalSum = base + commisionAmout + precentAmout;
console.log(base);
$('#cost').text(totalCost);
$('#sum').text(totalSum);
}
$('#slider').on('change', function () {
$('#amout').text(this.value);
cost(this.value);
});})
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="calc">
<div class="range-title">
<h2 class="range-label">Ile chcesz pożyczyć?</h2>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<div class="display-wrap">
<span id="amout">500</span><span class="currency"> zł</span>
</div>
</div>
<div class="range-wrap">
<button class="buttons-change-value">-</button>
<input id="slider" class="range-input" type="range" min="500" max="1500" step="50" value="500">
<button class="buttons-change-value">+</button>
</div>
<div class="summary-container">
<div class="summary-box">
<h3>Koszt:<br>
<span id="cost">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>Do zwrotu:<br>
<span id="sum">200</span><span class="currency"> zł</span></h3>
</div>
<div class="summary-box">
<h3>RRSO:<br>
<span id="rrso">200</span><span class="percentage"> %</span></h3>
</div>
</div>
</div>
</body>
</html>
I created a calculator in HTML/js, now am trying to add some validation to it but I can't seem to get it to work.
In the below calculator, I added a script that checked if the sex radio button has not been checked then output a message. Unfortunately, when I ran it the message isn't showing anything. Help please
function calcCreatine() {
var sexInput = document.querySelector('input[name="sex"]:checked').value;;
var ageInput = document.getElementsByName("patients-age")[0].value;
var weightInput = document.getElementsByName("patients-weight")[0].value;
var serumInput = document.getElementsByName("patients-serum")[0].value;
var result;
if (sexInput == null) {
return document.getElementById("outs").innerHTML = "Please enter a value";
} else {
if (sexInput === 'm') {
result = Math.round(((140 - ageInput) * weightInput * 1.23) / serumInput);
result = result.toString().bold().fontsize(6);
resultText = " mL/min".small() + " - Creatinine clearance.";
res = result + resultText.bold();
return document.getElementById("outs").innerHTML = res;
} else {
result = Math.round(((140 - ageInput) * weightInput * 1.04) / serumInput);
result = result.toString().bold().fontsize(6);
resultText = " mL/min".small() + " - Creatinine clearance.";
res = result + resultText.bold();
return document.getElementById("outs").innerHTML = res;
}
}
}
<!-- Creatinine clearance calculator. -->
<form id="form-id" method="post">
<div id="creat-calc">
<div class="card">
<div class="card-header py-3">
<h5 class="m-0 font-weight-bold text-primary"><strong>Creatinine clearance
calculator</strong></h5>
</div>
<div class="card-body">
<p>Sex of patient:</p>
<div>
<label class="radio-inline">
<input type="radio" name="sex" value="m"> Male
</label>
<label class="radio-inline">
<input type="radio" name="sex" value="f"> Female
</label>
<p>Age of patient (years):</p>
<input type="number" min="1" max="120" name="patients-age" />
<br/><br/>
<p>Weight of patient (kg):</p>
<input type="number" min="1" max="120" name="patients-weight" />
<br/><br/>
<p>Serum creatinine (micromol/L):</p>
<input type="number" min="1" max="120" name="patients-serum" />
<br/>
</div>
<br/>
<hr/>
<div id="crtresult">
<h5 id="outs"></h5>
<p>Original Cockcroft-Gault Equation: <u> mdcalc website</u></p>
</div>
<button type="button" class="btn btn-primary" onclick="calcCreatine();">Calculate
</button>
<button type="button" class="btn btn-danger" onclick="popup.hideCeatCalcFormPopup();">
Close
</button>
<button type="reset" class="btn btn-primary" onclick="resetButton();">Reset</button>
</div>
</div>
</div>
</form>
The problem here is that when you are not selecting any radio button, following statements returns null:
document.querySelector('input[name="sex"]:checked')
since its null this cannot have value property. So I did some modification in the code and stored the whole input instead of the value and then used it later with value property wherever needed.
Here's the solution. Try it yourself:
function calcCreatine() {
var sexInput = document.querySelector('input[name="sex"]:checked');
var ageInput = document.getElementsByName("patients-age")[0];
var weightInput = document.getElementsByName("patients-weight")[0];
var serumInput = document.getElementsByName("patients-serum")[0];
var result;
if (sexInput == null) {
return document.getElementById("outs").innerHTML = "Please select your gender";
} else {
if (sexInput.value === 'm') {
result = Math.round(((140 - ageInput.value) * weightInput.value * 1.23) / serumInput.value);
result = result.toString().bold().fontsize(6);
resultText = " mL/min".small() + " - Creatinine clearance.";
res = result + resultText.bold();
return document.getElementById("outs").innerHTML = res;
} else {
result = Math.round(((140 - ageInput.value) * weightInput.value * 1.04) / serumInput.value);
result = result.toString().bold().fontsize(6);
resultText = " mL/min".small() + " - Creatinine clearance.";
res = result + resultText.bold();
return document.getElementById("outs").innerHTML = res;
}
}
}
<!-- Creatinine clearance calculator. -->
<form id="form-id" method="post">
<div id="creat-calc">
<div class="card">
<div class="card-header py-3">
<h5 class="m-0 font-weight-bold text-primary"><strong>Creatinine clearance
calculator</strong></h5>
</div>
<div class="card-body">
<p>Sex of patient:</p>
<div>
<label class="radio-inline">
<input type="radio" name="sex" value="m"> Male
</label>
<label class="radio-inline">
<input type="radio" name="sex" value="f"> Female
</label>
<p>Age of patient (years):</p>
<input type="number" min="1" max="120" name="patients-age" />
<br/><br/>
<p>Weight of patient (kg):</p>
<input type="number" min="1" max="120" name="patients-weight" />
<br/><br/>
<p>Serum creatinine (micromol/L):</p>
<input type="number" min="1" max="120" name="patients-serum" />
<br/>
</div>
<br/>
<hr/>
<div id="crtresult">
<h5 id="outs"></h5>
<p>Original Cockcroft-Gault Equation: <u> mdcalc website</u></p>
</div>
<button type="button" class="btn btn-primary" onclick="calcCreatine();">Calculate
</button>
<button type="button" class="btn btn-danger" onclick="popup.hideCeatCalcFormPopup();">
Close
</button>
<button type="reset" class="btn btn-primary" onclick="resetButton();">Reset</button>
</div>
</div>
</div>
</form>
There are a couple of issues with your code.
var sexInput = document.querySelector('input[name="sex"]:checked').value;
This line is trying to get the value of the selected sex. If the form has just loaded and the user has not selected anything yet, then:
document.querySelector('input[name="sex"]:checked');
Will be null, so you will get an error:
Uncaught TypeError: Cannot read property 'value' of null
The simplest way to fix that would be to just add a default value to the radio buttons, for example:
<input type="radio" name="sex" value="m" checked>
That being said, you can also improve the following:
The <font> tag has been removed from HTML5, so it would be a good idea to replace that.
Since patient sex only affects one line of your code, you can remove the duplicate part by just calculating the result in an if statement and doing the rest only once.
I have created this fiddle to demonstrate.
The first problem is the code is the double ";" in the first line please, change it:
var sexInput = document.querySelector('input[name="sex"]:checked').value;;
to:
var sexInput = document.querySelector('input[name="sex"]:checked').value;
The second problem in you radio button is not working because you are trying to get a value from an element that doesn't exist if you don't check the button but if you check it and you execute the calculate button then you get an error:
and this error is because you are trying to obtain a value from an element that doesn't exist yet.
How to solve it?
You can modify the first line to get the null value from the element like this:
var sexInput = document.querySelector('input[name="sex"]:checked');
then if the user not check the radio button you will get a null value.
Another way could be using the checked property of the element to evaluate if the user checked the button using true/false like this:
var sexInput = document.querySelector('input[name="sex"]').checked;
then in your code you can eval like this:
if(sexInput){
// Do something
}
EDIT
I added a working exmaple:
EDIT 2
Improved the response a little bit more.
function calcCreatine() {
var sexInput = document.querySelector('input[name="sex"]:checked');
var ageInput = document.getElementsByName("patients-age")[0].value;
var weightInput = document.getElementsByName("patients-weight")[0].value;
var serumInput = document.getElementsByName("patients-serum")[0].value;
var result;
if (sexInput == null) {
return document.getElementById("outs").innerHTML = "Please enter a value";
} else {
if (sexInput === 'm') {
result = Math.round(((140 - ageInput) * weightInput * 1.23) / serumInput);
result = result.toString().bold().fontsize(6);
resultText = " mL/min".small() + " - Creatinine clearance.";
res = result + resultText.bold();
return document.getElementById("outs").innerHTML = res;
} else {
result = Math.round(((140 - ageInput) * weightInput * 1.04) / serumInput);
result = result.toString().bold().fontsize(6);
resultText = " mL/min".small() + " - Creatinine clearance.";
res = result + resultText.bold();
return document.getElementById("outs").innerHTML = res;
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="asd.js"></script>
</head>
<body>
<!-- Creatinine clearance calculator. -->
<form id="form-id" method="post">
<div id="creat-calc">
<div class="card">
<div class="card-header py-3">
<h5 class="m-0 font-weight-bold text-primary">
<strong>Creatinine clearance calculator</strong>
</h5>
</div>
<div class="card-body">
<p>Sex of patient:</p>
<div>
<label class="radio-inline">
<input type="radio" name="sex" value="m" /> Male
</label>
<label class="radio-inline">
<input type="radio" name="sex" value="f" /> Female
</label>
<p>Age of patient (years):</p>
<input type="number" min="1" max="120" name="patients-age" />
<br /><br />
<p>Weight of patient (kg):</p>
<input type="number" min="1" max="120" name="patients-weight" />
<br /><br />
<p>Serum creatinine (micromol/L):</p>
<input type="number" min="1" max="120" name="patients-serum" />
<br />
</div>
<br />
<hr />
<div id="crtresult">
<h5 id="outs"></h5>
<p>
Original Cockcroft-Gault Equation:
<a
href="https://www.mdcalc.com/creatinine-clearance-cockcroft-gault-equation#creator-insights"
style="color: white"
><u> mdcalc website</u></a
>
</p>
</div>
<button
type="button"
class="btn btn-primary"
onclick="calcCreatine();"
>
Calculate
</button>
<button
type="button"
class="btn btn-danger"
onclick="popup.hideCeatCalcFormPopup();"
>
Close
</button>
<button
type="reset"
class="btn btn-primary"
onclick="resetButton();"
>
Reset
</button>
</div>
</div>
</div>
</form>
</body>
</html>
Regards
This is run automatic. i need it run when call window.onload, not run before call window.onload, because i want to create function as a template code to embed other side, just change id, or className input
Thanks
function changeResultBox(resultTextClassName,inputSearchToggleId){
var inputSearchToggle=document.getElementById(inputSearchToggleId),
resultText=document.getElementsByClassName(resultTextClassName);
resultText[0].innerHTML='"'+inputSearchToggle.value+'"';
resultText[1].innerHTML='"'+inputSearchToggle.value+'"';
}
window.onload=function(){
document.getElementById('Store-Page-Search-Input').onkeyup =
changeResultBox('search-bar-item__text','Store-Page-Search-Input');
}
<input type="text" id="Store-Page-Search-Input" class="search-bar__input" name="txtsearchbar" placeholder="Find product, find shop,..." autocomplete="off" value=""/>
<div class="search-bar-item">
<div class="search-bar-item__title">find product </div>
<div class="search-bar-item__text"></div>
</div>
<div class="search-bar-item">
<div class="search-bar-item__title">find shop </div>
<div class="search-bar-item__text"></div>
</div>
Bind event on the input itself onkeyup="changeResultBox('search-bar-item__text','Store-Page-Search-Input')".
<input type="text" id="Store-Page-Search-Input" class="search-bar__input" name="txtsearchbar" placeholder="Find product, find shop,..." autocomplete="off" value="" onkeyup="changeResultBox('search-bar-item__text','Store-Page-Search-Input')" />
function changeResultBox(resultTextClassName, inputSearchToggleId) {
var inputSearchToggle = document.getElementById(inputSearchToggleId),
resultText = document.getElementsByClassName(resultTextClassName);
resultText[0].innerHTML = '"' + inputSearchToggle.value + '"';
resultText[1].innerHTML = '"' + inputSearchToggle.value + '"';
}
<input type="text" id="Store-Page-Search-Input" class="search-bar__input" name="txtsearchbar" placeholder="Find product, find shop,..." autocomplete="off" value="" onkeyup="changeResultBox('search-bar-item__text','Store-Page-Search-Input')" />
<div class="search-bar-item">
<div class="search-bar-item__title">find product </div>
<div class="search-bar-item__text"></div>
</div>
<div class="search-bar-item">
<div class="search-bar-item__title">find shop </div>
<div class="search-bar-item__text"></div>
</div>
function changeResultBox(resultTextClassName, inputSearchToggleId) {
//var resultTextClassName = 'search-bar-item__text';
//var inputSearchToggleId = 'Store-Page-Search-Input';
var inputSearchToggle = document.getElementById(inputSearchToggleId),
resultText = document.getElementsByClassName(resultTextClassName);
resultText[0].innerHTML = '"' + inputSearchToggle.value + '"';
resultText[1].innerHTML = '"' + inputSearchToggle.value + '"';
}
window.onload = function() {
document.getElementById("Store-Page-Search-Input").addEventListener("keyup", changeResultBox.bind(event, 'search-bar-item__text', 'Store-Page-Search-Input'));
}
<input type="text" id="Store-Page-Search-Input" class="search-bar__input" name="txtsearchbar" placeholder="Find product, find shop,..." autocomplete="off" value="" />
<div class="search-bar-item">
<div class="search-bar-item__title">find product </div>
<div class="search-bar-item__text"></div>
</div>
<div class="search-bar-item">
<div class="search-bar-item__title">find shop </div>
<div class="search-bar-item__text"></div>
</div>
I'm trying to work out the percentage value for each field in a form. However my current code is only working out the value for the first field or whichever one is focused.
I'd like it so that the percentage value only for the filed in the same fieldset
The current code works but i'd like to apply to to multiple fieldsets without them interfering with other inputs on the same page
In the snippet you can see that the two separate amounts which are editing each others details
function percentageCal() {
var $price = $(".form-item--invamt .form-item__input").on("input", calculatePerc),
$percentage = $(".form-item__input-expand .percentage").on("input", calculatePrice),
$currency = $(".form-item__input-expand .currency").on("focus", removePercent),
$none = $(".form-item--charges .no-charge").on("focus", removePercent),
$increase = $(".wrapper-types__percentage-value"),
$increaseWrap = $(".wrapper-types__percentage");
$($percentage).add($currency).keypress(function(event) {
if (event.which != 8 && event.which != 0 && (event.which < 48 || event.which > 57)) {
return false;
}
});
function calculatePrice() {
var percentage = parseFloat($(this).val());
var price = parseFloat($price.val());
var calcPrice = parseFloat((price * percentage / 100).toFixed(2));
var newPrice = price + calcPrice;
$increase.text(newPrice);
$increaseWrap.fadeIn();
if (isNaN(newPrice)) {
$increaseWrap.hide();
}
}
function calculatePerc() {
var percentage = $percentage.val();
var price = parseFloat($(this).val());
var calcPerc = parseFloat((price * percentage / 100).toFixed(2));
var newPrice = price + calcPerc;
$increase.text(newPrice);
}
function removePercent() {
$increaseWrap.fadeOut();
}
}
percentageCal();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<fieldset class="wrapper-types__investment">
<legend class="sr-only">Investment 1</legend>
<div class="form-item form-item--required form-item--invamt">
<label class="form-item__label" for="wrappers[0]">Investment amount</label>
<div class="form-item__input-labelled">
<span class="form-item__input-label">£</span>
<input class="form-item__input " type="number" name="wrappers[0]" id="wrappers[0]" min="0" value="15000" required>
</div>
</div>
<div class="form-item form-item--charges-wrap">
<span class="form-item__label">Charges</span>
<div class="form-item form-item--charges">
<label class="form-item__input-label-expand" for="percentage1">%</label>
<div class="form-item__input-expand">
<input class="form-item__input percentage" type="number" name="percentage" id="percentage1">
</div>
</div>
</div>
<div class="form-item form-item--charges-wrap">
<span class="wrapper-types__percentage">= £<span class="wrapper-types__percentage-value"></span></span>
</div>
<div class="form-item form-item--action-btns">
</div>
</fieldset>
<fieldset class="wrapper-types__investment">
<legend class="sr-only">Investment 2</legend>
<div class="form-item form-item--required form-item--invamt">
<label class="form-item__label" for="wrappers[1]">Investment amount</label>
<div class="form-item__input-labelled">
<span class="form-item__input-label">£</span>
<input class="form-item__input " type="number" name="wrappers[1]" id="wrappers[1]" min="0" value="13005.02" required>
</div>
</div>
<div class="form-item form-item--charges-wrap">
<span class="form-item__label">Charges</span>
<div class="form-item form-item--charges">
<label class="form-item__input-label-expand" for="percentage2">%</label>
<div class="form-item__input-expand">
<input class="form-item__input percentage" type="number" name="percentage" id="percentage2">
</div>
</div>
</div>
<div class="form-item form-item--charges-wrap">
<span class="wrapper-types__percentage">= £<span class="wrapper-types__percentage-value"></span></span>
</div>
<div class="form-item form-item--action-btns">
</div>
</fieldset>
Instead of IDs, use classes and DOM traversal functions to find the fields in the same fieldset.
function percentageCal() {
var $price = $(".form-item--invamt .form-item__input").on("input", calculatePerc),
$percentage = $(".form-item__input-expand .percentage").on("input", calculatePrice),
$currency = $(".form-item__input-expand .currency").on("focus", removePercent),
$none = $(".form-item--charges .no-charge").on("focus", removePercent),
$increase = $(".wrapper-types__percentage-value"),
$increaseWrap = $(".wrapper-types__percentage");
$percentage.add($currency).keypress(function(event) {
if (event.which != 8 && event.which != 0 && (event.which < 48 || event.which > 57)) {
return false;
}
});
function calculatePrice() {
var $fieldset = $(this).closest("fieldset");
var percentage = parseFloat($(this).val());
var price = parseFloat($fieldset.find(".form-item--invamt .form-item__input").val());
var calcPrice = parseFloat((price * percentage / 100).toFixed(2));
var newPrice = price + calcPrice;
$fieldset.find(".wrapper-types__percentage-value").text(newPrice);
$fieldset.find(".wrapper-types__percentage").fadeIn();
if (isNaN(newPrice)) {
$fieldset.find(".wrapper-types__percentage").hide();
}
}
function calculatePerc() {
var $fieldset = $(this).closest("fieldset");
var percentage = $fieldset.find(".form-item__input-expand .percentage").val();
var price = parseFloat($(this).val());
var calcPerc = parseFloat((price * percentage / 100).toFixed(2));
var newPrice = price + calcPerc;
$fieldset.find(".wrapper-types__percentage-value").text(newPrice);
}
function removePercent() {
var $fieldset = $(this).closest("fieldset");
$fieldset.find(".wrapper-types__percentage").fadeOut();
}
}
percentageCal();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<fieldset class="wrapper-types__investment">
<div class="form-item--invamt">
<div>
<span class="form-item__input-label">£</span>
<input class="form-item__input " type="number" name="wrappers[0]" id="wrappers[0]" min="0" value="15000" required>
</div>
</div>
<div class="form-item--charges-wrap">
<div class="form-item--charges">
<label class="form-item__input-label-expand" for="percentage">%</label>
<div class="form-item__input-expand">
<input class="form-item__input percentage" type="number" name="percentage" id="percentage">
</div>
</div>
</div>
<div class="form-item--charges-wrap">
<span class="wrapper-types__percentage">= £<span class="wrapper-types__percentage-value"></span></span>
</div>
</fieldset>
<fieldset class="wrapper-types__investment">
<div class="form-item--invamt">
<div>
<span class="form-item__input-label">£</span>
<input class="form-item__input " type="number" name="wrappers[1]" id="wrappers[1]" min="0" value="15000" required>
</div>
</div>
<div class="form-item--charges-wrap">
<div class="form-item--charges">
<label class="form-item__input-label-expand" for="percentage1">%</label>
<div class="form-item__input-expand">
<input class="form-item__input percentage" type="number" name="percentage" id="percentage1">
</div>
</div>
</div>
<div class="form-item--charges-wrap">
<span class="wrapper-types__percentage">= £<span class="wrapper-types__percentage-value"></span></span>
</div>
</fieldset>
I want to make a book catalog with JQuery to add books to a author. In the code That I have I am trying to add a author and have his books be in a array with his number only. Separated by other authors and their own arrays of books.
For example, when I press the button to add a author a input box appears so that I can add the authors name also a button to add a book that when I press that button I get an input box to add a books name.
When I press the add author again I want to be able to add another author with the same input boxes as before (adding more books to that author).
Also to add multiple books assigned to that author.
I have already done this in the pics but I get an array of everything. I want it to be separated by author.
author1 has an array of {book1, book2, book3...}
author2 has an array of {book13, book14, book15}
(i'm a beginner at JQuery)
This is the code that I have so far:
<!DOCTYPE html>
<html>
<head>
<title>Add or Remove text boxes with jQuery</title>
<script type="text/javascript" src="//code.jquery.com/jquery-latest.js"></script>
<style type="text/css">
<!--
#main {
max-width: 800px;
margin: 0 auto;
}
-->
</style>
</head>
<body>
<div id="main">
<h1>Add or Remove text boxes with jQuery</h1>
<div class="my-form">
<form role="form" method="post">
<p class="all_fields">
<button class="add_author">Add Author</button>
<div id="commonPart" class="commonPart">
<label for="author1">Author <span class="author-number">1</span></label>
<br/>
<input type="text" name="author" value="" id="author1" />
<br/>
<button class="add_book">Add book</button>
<div>
<input type="text" class="bookName" name="authBook[]"/>
</div>
</div>
</p>
<p><input type="submit" value="Submit" /></p>
</form>
</div>
</div>
<script type="text/javascript">
$(document).ready(function($){
var wrapper = $(".all_fields"); //Fields wrapper
var commonPart = $("#commonPart");
var add_author = $(".add_author"); //Add button ID
var add_subButton = $(".add_book"); //Add sub button ID
$('.my-form .add-box').click(function(){
var n = $('.all_fields').length + 1;
if( 15 < n ) {
alert('Stop it!');
return false;
}
$(add_author).click(function(e){
e.preventDefault();
var htmlToAdd = $('<label for="author' + n + '">Author <span class="author-number">' + n + '</span></label><br/><input type="text" name="author' + n + '" value="" id="author' + n + '" /><br/><button class="add_book">Add book</button><a class="add-book" href="#">Add Book</a><div><input type="text" class="bookName" name="authBook' + n + '[]"/></div>');
htmlToAdd.hide();
$('.my-form p.all_fields:last').after(htmlToAdd);
box_html.fadeIn('slow');
return false;
});
$(add_book).click(function(e){
e.preventDefault();
var htmlToAdd = $('<div><input type="text" class="bookName" name="authBook' + n + '[]"/></div>');
htmlToAdd.hide();
$('.my-form p.all_fields:last').after(htmlToAdd);
box_html.fadeIn('slow');
return false;
});
$('.my-form').on('click', '.remove-box', function(){
$(this).parent().css( 'background-color', '#FF6C6C' );
$(this).parent().fadeOut("slow", function() {
$(this).remove();
$('.box-number').each(function(index){
$(this).text( index + 1 );
});
});
return false;
});
});
</script>
</body>
</html>
updated code(fixed some bugs..), try this....
<!DOCTYPE html>
<html>
<head>
<title>Add or Remove text boxes with jQuery</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style type="text/css">
<!--
#main {
max-width: 800px;
margin: 0 auto;
}
-->
</style>
</head>
<body>
<div id="main">
<h1>Add or Remove text boxes with jQuery</h1>
<div class="my-form">
<button onclick="addAuthor()" >Add Author</button><br><br>
<div id="addAuth"></div>
<br><br>
<button onclick="submit()" >Submit</button>
</div>
<div id="result" ></div>
</div>
<script type="text/javascript">
var authors = 0;
function addAuthor(){
authors++;
var str = '<div id="auth'+authors+'"><input type="text" name="author" id="author'+authors+'" />'
+'<button onclick="addMore(\'auth'+authors+'\')" >Add Book</button>'
+'</div>';
$("#addAuth").append(str);
}
var count=0;
function addMore(id){
count++;
var str = '<div id="bookDiv'+count+'">'
+'<input class="'+id+'" type="text" name="book'+id+'" />'
+'<span onclick="addMore(\''+id+'\')" style="font-size: 20px; background-color: green; cursor:pointer;">+</span>'
+'<span onclick="removeDiv(\'bookDiv'+count+'\')" style="font-size: 20px; background-color: red; cursor:pointer; margin-left:1%;">-</span>'
+'</div>';
$("#"+id).append(str);
}
function removeDiv(id){
var val = confirm("Are you sure ..?");
if(val){
$("#"+id).slideUp(function(){$("#"+id).remove();});
}
}
function submit(){
var arr = [];
for(i=1; i<=authors; i++){
var obj = {};
obj.name = $("#author"+i).val();
obj.books = [];
$(".auth"+i).each(function(){
var data = $(this).val();
obj.books.push(data);
});
arr.push(obj);
}
$("#result").html(JSON.stringify(arr));
}
</script>
</body>
</html>
Please try this code and include jquery min js :
<div class="my-form">
<form role="form" method="post">
<p class="all_fields">
<div id="commonPart" class="commonPart">
<label for="author1">Author <span class="author-number"></span></label>
<input type="text" name="author" value="" id="author1" />
<br/>
<div>
<label for="author1">book <span class="author-number"></span></label>
<input type="text" class="bookName" name="authBook[]"/>
</div>
</div>
<button type="button" class="add_author" onclick="AddCustomMOre();">Add More</button>
</p>
<p><input type="submit" value="Submit" /></p>
</form>
</div>
<script> function AddCustomMOre(){
$(".all_fields ").append('<div id="commonPart" class="commonPart"><label for="author1">Author <span class="author-number"></span></label> <input type="text" name="author" value="" id="author1" /> <br/> <div><label for="author1">book <span class="author-number"></span></label> <input type="text" class="bookName" name="authBook[]"/></div> Remove</div>');
} </script>
You can try this....
<p class="all_fields">
<button class="add_author">Add Author</button>
<div class="commonPart">
<label for="author1">Author <span class="author-number">1</span></label>
<br/>
<input type="text" name="author1" value="" id="author1" />
<br/>
<button div-id="1" class="add_book">Add book</button>
<div id="books1">
<input type="text" class="bookName" name="authBook[]"/>
</div>
</div>
</p>
<script>
var c=1;
$(".add_author").on("click",function(){
c++;
$(".all_fields").append('<div class="commonPart"><label for="author'+c+'">Author <span class="author-number">'+c+'</span></label><br/><input type="text" name="author'+c+'" value="" id="author'+c+'" /><br/><button class="add_book" div-id="'+c+'">Add book</button><div id="books'+c+'"><input type="text" class="bookName" name="authBook[]"/></div></div>');
});
$(".add_book").on("click",function(){
var id=$(this).attr("div-id");
$("#books"+id).append('<input type="text" class="bookName" name="authBook[]"/>');
});
</script>