Javascript Checkbox onClick Addition - javascript

I have a form with two check box.
Checkbox A = $1500
Checkbox B = $1500
What I want to do is, when Checkbox A is "checked", I want to display $1500 and add into hidden value. When unchecked, subtract $1500.
When both checkbox checked, I want each other to be performed addition, which means I want to have the value "$3000" in total, when one removed, subtracted accordingly.
Currently with my codes, I can make it work for one checkbox only, which means, when checkbox is checked, it will be $1500 and when one it's removed back, it's substracted. I don't know how to combine Checkbox A & Checkbox B.
Please see my codes and help me out.
HTML
<label>
<input type="checkbox" name="Meeting" onClick="if (this.checked) { onCheck3() } else { onUncheck3() }" value="Pre-Meeting 1" id="Meeting" />
Pre-Meeting 1
</label>
<label>
<input type="checkbox" name="Meeting" onClick="if (this.checked) { onCheck4() } else { onUncheck4() }" value="Pre-Meeting 2" id="Meeting" />
Pre-Meeting 2
</label>
<input type="text" name="PreMeetingAmount" readonly id="PreMeetingAmount" /><input type="hidden" name="PreMeetingAmounthidden" readonly id="PreMeetingAmounthidden" />
Javascript
function onCheck3(){
t = document.form1.PreMeetingAmount.value;
t2 = 0;
if (t == 0) {
document.form1.PreMeetingAmount.value = 1500;
}
}
function onCheck4(){
t = document.form1.PreMeetingAmount.value;
t2 = 0;
if (t == 0) {
document.form1.PreMeetingAmount.value = 1500;
}
}
function onUncheck3(){
t = document.form1.PreMeetingAmount.value;
t = t - 1500;
if (t == 0)
document.form1.PreMeetingAmount.value = document.form1.PreMeetingAmounthidden.value;
else
document.form1.PreMeetingAmount.value = t;
}
function onUncheck4(){
t = document.form1.PreMeetingAmount.value;
t = t - 1500;
if (t == 0)
document.form1.PreMeetingAmount.value = document.form1.PreMeetingAmounthidden.value;
else
document.form1.PreMeetingAmount.value = t;
}

You are always setting the value to 1500. You need to add 1500 rather than set it to 1500. Try changing onCheck3 and onCheck4 similar to this:
function onCheck3() {
t = Number( document.form1.PreMeeting.value );
document.form1.PreMeeting.value = t + 1500;
}

Related

Decrease numeric input value when increasing another input value

I should work with two input values that store only Integers when I increase the value of one, the other should decrease. This must stop if the second value hit 0.
The field that contains the value to be decreased is named with ID form_val62_1, and field that can be increased by the user input is called form_val63_1. I'm calling this function onChange() cause I need to pass the ID of the form (that's cause form fields are dynamically generated depending on a PHP array length).
function check(i) {
$("#form_val63_" + i ).change(function () {
var direction = this.defaultValue < this.value;
this.defaultValue = this.value;
var val;
val = parseInt($("#form_val62_" + i).val());
if (direction) {
if (val > 0) {
$('#form_val62_' + i).val(parseInt($(this).val()) - 1);
} else {
var thvar = $(this).val();
$(this).val(thvar - 1);
}
console.log("increase 503");
console.log(val);
} else {
$('#form_val62_' + i).val(parseInt($(this).val()) + 1);
console.log("decrease 503");
console.log(val);
}
});
}
Fiddle
I got many problems here, the first decrease one time, that increase with no reason (I know there is but can't see why).
Using the solution provided by #Ph0b0x i've updated my code as
var v = $("#form_val62_" + i).val(); //Let's say this is the value from PHP....
var preVal = 0;
$("#form_val62_" + i).val(v);
$("#form_val63_" + i).on("change keyup keydown", function(event) {
let currVal = parseInt($("#form_val63_" + i).val());
console.log(preVal);
console.log(currVal);
if (currVal == 0) {
preVal = 0;
$("#form_val62_" + i).val(v);
} else if (currVal <= v) {
$("#form_val62_" + i).val((v - currVal) == 0 ? 0 : (v - currVal));
preVal = currVal;
} else {
$("#form_val63_" + i).val(v);
}
});
Now I can increase the result but when i try decrease the each value remain 0.
I guess, if i understood correctly, i will keep track of the previous value on the second input then i will start decreasing the first one until it reaches 0 and increase it until it reaches 10? Fiddle
HTML
<form>
<input id="form_val62_1" type="number" min="0" value="10" />
<input id="form_val63_1" type="number" min="0" value="0" />
</form>
JS
var v = 13; //Let's say this is the value from PHP....
var preVal = 0;
$("#form_val62_1").val(v);
$("#form_val63_1").on("change keyup keydown", function(event) {
let currVal = parseInt($("#form_val63_1").val());
console.log(preVal);
console.log(currVal);
if (currVal == 0) {
preVal = 0;
$("#form_val62_1").val(v);
} else if (currVal <= v) {
$("#form_val62_1").val((v - currVal) == 0 ? 0 : (v - currVal));
preVal = currVal;
} else {
$("#form_val63_1").val(v);
}
});
Edit: I have updated my code based on your comment. Please see this Fiddle
So bind change event handlers on both elements. I would just use data attributes so you do not have to worry about selecting by ids to bind between both.
$('[data-num-grp]').on('input', function () {
// input that was interacted with
const inp1 = $(this);
// get the group number
const grp = inp1.data('num-grp')
// select the other element with the grp
const inp2 = $('[data-num-grp="' + grp + '"]').not(inp1);
// alter the other element so it's value changes
inp2.val(this.max - this.value)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" data-num-grp="1" min="0" max="10" value="10"/>
<input type="number" data-num-grp="1" min="0" max="10" value="0"/>
<br/>
<input type="number" data-num-grp="2" min="0" max="10" value="10"/>
<input type="number" data-num-grp="2" min="0" max="10" value="0"/>

Multiple radio buttons with same set of options

I have four sets of radio buttons, each containing four options as shown in the code below:
<div *ngFor="let index of [0,1,2,3]">
<label *ngFor="let vehicle of vehicles" class="radio">
<input type="radio"
id="radio1"
[value]="vehicle"
(change)="updateValues(vehicles, formArray.value, index)"
name="vehicle" formControlName="vehicle">
{{vehicle.name}} ({{vehicle.total_no}})
</label>
</div>
Each vehicle in the above option set has a name and total number attached to it. On selecting a vehicle, the total number value should update. The option should also be disabled if the total number is zero.
I have written a function that correctly updates the values, but it unfortunately registers changes in the other sets of radio buttons too.
updateValues(vehicles, form, index) {
let x;
let selectedVehicles = form.map(x => x.vehicle);
if (this._prevSelectedVehicles[index] === '') {
x = vehicles.indexOf(selectedVehicles[index]);
vehicles[x].total_no -= 1;
this._prevSelectedVehicles[index] = selectedVehicles[index];
this.updateTime(form, selectedVehicles);
} else if (
selectedVehicles[index].name !== this._prevSelectedVehicles[index].name
) {
x = vehicles.indexOf(this._prevSelectedVehicles[index]);
vehicles[x].total_no += 1;
x = vehicles.indexOf(selectedVehicles[index]);
vehicles[x].total_no -= 1;
this._prevSelectedVehicles[index] = selectedVehicles[index];
this.updateTime(form, selectedVehicles);
}
}
How can I make sure that the values selected in the previous divs are not updated? Also attaching a mockup if the question is unclear.
Use an unique ID for each vehicle-object and compare by this. E.g.
...
if(vehicles[x].id === this._prevSelectedVehicles[index].id){
x = vehicles.indexOf(this._prevSelectedVehicles[index]);
vehicles[x].total_no += 1;
x = vehicles.indexOf(selectedVehicles[index]);
vehicles[x].total_no -= 1;
this._prevSelectedVehicles[index] = selectedVehicles[index];
}
...

Trying to get back a score from a quiz

For some reason only the score0 wants to increment. Although the two for-loops seem identical (really sorry if I'm wrong). So the totScore just gets the value from the score0 variable. But ofcourse I want totScore to get value form both variables so to get the total score of the quiz.
Also, why does it add 4 to the score0 variable when I wrote score0 += 1;, that doesn't make any sence to me.
If you change my code alot please don't use any JQuery.
Thanks!
<!DOCTYPE html>
<html>
<body>
<form id='quizForm'>
<ul>
<li>
<h3>How many letters are there in 'FB'?</h3>
<input type="radio" name="question0" value="A" />2<br>
<input type="radio" name="question0" value="B" />1<br>
<input type="radio" name="question0" value="C" />3<br>
<input type="radio" name="question0" value="D" />4<br>
</li>
</ul>
<ul>
<li>
<h3>How many letters are there in 'IBM'?</h3>
<input type="radio" name="question1" value="A" />2<br>
<input type="radio" name="question1" value="B" />1<br>
<input type="radio" name="question1" value="C" />3<br>
<input type="radio" name="question1" value="D" />4<br>
</li>
</ul>
</form>
<button onclick="showScore()">Show results
</button>
<script>
//Score and answer variables
var score1 = 0;
var score0 = 0;
var totScore = 0;
var answers = ["A","C"]
//function to calculate the score.
function getScore() {
// some arrays and stuff
userInput1 = new Array(10);
userInput0 = new Array(10);
var question0s = document.getElementsByName("question0");
//for loop to see which radio was checked
for (var i = 0; i < question0s.length; i++) {
if (question0s[i].checked) {
userInput0[0] = question0s[i].value;
}
if (userInput0[0] == answers[0]) {
// Only god knows why the hell I have to divide 4
score0 += 1 / 4;
}
else if (userInput0[0] != answers [0]){
//so that user can't just switch back and fourth from inputs to get higher score.
score0 -= 1 ;
}
}
//if user has changed her answer multiple times she will get an answer with a negative value. I don't want that, so if score is less than 0 it turns to 0.
if (score0 < 0){
score0 = score0 * 0;
}
var question1s = document.getElementsByName("question1");
//for loop to see which radio was checked
for (var y = 0; y < question1s.length; y++) {
if (question1s[y].checked) {
userInput1[0] = question1[y].value;
}
if (userInput1[0] == answers[0]) {
score1 += 1;
}
else if (userInput1[0] != answers [0]){
//so that user can't just switch back and fourth from inputs to get higher score.
score1 -= 1 ;
}
}
if (score1 < 0){
//if user has changed her answer multiple times she will get an answer with a negative value. I don't want that, so if score is less than 0 it turns to 0.
score1 = score1 * 0;
}
//getting score from all different questions
totScore += score1 + score0;
}
//checking for changes in the form
var quizForm = document.getElementById('quizForm');
quizForm.addEventListener("change", function(){
getScore();
});
// onclick function
function showScore (){
alert (totScore);
}
</script>
</body>
</html>
As to why you are not getting proper processing, you have an invalid variable question1 here:
userInput1[0] = question1[y].value;
Now let's fix this and do better.
First off, you have a number of global variables so let's get that under a simple namespace and call it quiz.
Get the click handler out of the markup and create a listener for that.
Now as for your logic, you are looping through the radio buttons. Now the way radio buttons work is that only one can be selected SO, let's use that to our advantage an not do the loop at all.
With the radio buttons, if one is NOT selected yet, then it will be NULL using our new selection technique so we can use that to tell if both the questions have been answered and then if that IS true, we can put scores in. Otherwise, they get no score (score is 0) until all the questions ARE answered (not NULL).
//Score and answer variables=
var quiz = {
score0: 0,
score1: 0,
totalScore: 0,
answers: ["A", "C"],
maxScore: 2,
tries: 0
};
//function to calculate the score.
function getScore() {
var answer0 = document.querySelector('input[name="question0"]:checked');
quiz.score0 = answer0 != null && quiz.answers[0] == answer0.value ? 1 : 0;
var answer1 = document.querySelector('input[name="question1"]:checked');
quiz.score1 = answer1 != null && quiz.answers[1] == answer1.value ? 1 : 0;
// if either is null, not all answered
if (answer0 != null && answer1 != null) {
// if previous tries, subtract how many
if (quiz.tries) {
quiz.totalScore = quiz.totalScore ? quiz.totalScore - quiz.tries : 0;
quiz.totalScore = quiz.totalScore < 0 ? 0 : quiz.totalScore ;//0 if negative
} else {
quiz.totalScore = quiz.score1 + quiz.score0;
}
quiz.tries++;
}
}
// onclick function
function showScore() {
alert(quiz.totalScore + " in tries: " + quiz.tries);
}
// add listeners
//checking for changes in the form
var quizForm = document.getElementById('quizForm');
quizForm.addEventListener("change", function() {
getScore();
});
var resultButton = document.getElementById('results');
resultButton.addEventListener("click", function() {
showScore();
});
Try the above out here: https://jsfiddle.net/MarkSchultheiss/qx4hLjLq/2/
You could also do more with this by putting that in the quiz something like this:
//Score and answer variables=
var quiz = {
totalScore: 0,
tries: 0,
maxScore: 2,
answered: 0,
questions: [{
question: {},
name: "question0",
score: 0,
answer: "A"
}, {
question: {},
name: "question1",
score: 0,
answer: "C"
}],
checkQuestion: function(q) {
q.score = q.question != null && q.answer == q.question.value ? 1 : 0;
},
//function to calculate the score.
getScore: function() {
this.answered = 0;
for (var i = 0; i < this.questions.length; i++) {
var sel = 'input[name="' + this.questions[i].name + '"]:checked';
this.questions[i].question = document.querySelector(sel);
this.checkQuestion(this.questions[i]);
this.answered = this.questions[i].question ? this.answered + 1 : this.answered;
}
console.dir(this);
// if either is null, not all answered
if (this.answered == this.questions.length) {
for (var i = 0; i < this.questions.length; i++) {
this.totalScore = this.totalScore + this.questions[i].score;
}
if (this.tries) {
this.totalScore = this.tries && this.totalScore ? this.totalScore - this.tries : 0;
this.totalScore = this.totalScore < 0 ? 0 : this.totalScore; //0 if negative
}
this.tries++;
}
},
// onclick function
showScore: function() {
var t = "";
if (this.answered != this.questions.length) {
t = "Not all questions ansered!"
} else {
t = this.totalScore + " in tries: " + this.tries;
}
alert(t);
}
};
// add listeners
//checking for changes in the form
var quizForm = document.getElementById('quizForm');
quizForm.addEventListener("change", function() {
quiz.getScore();
});
var resultButton = document.getElementById('results');
resultButton.addEventListener("click", function() {
quiz.showScore();
});
Second example in action: https://jsfiddle.net/MarkSchultheiss/qx4hLjLq/4/
Well if you want to simply get the result from the test, use this code:
<!DOCTYPE html>
<html>
<body>
<ul>
<li>
<h3>How many letters are there in 'FB'?</h3>
<input type="radio" name="question0"/>1<br>
<input type="radio" name="question0"/>2<br>
<input type="radio" name="question0"/>3<br>
<input type="radio" name="question0"/>4<br>
</li>
</ul>
<ul>
<li>
<h3>How many letters are there in 'IBM'?</h3>
<input type="radio" name="question1"/>1<br>
<input type="radio" name="question1"/>2<br>
<input type="radio" name="question1"/>3<br>
<input type="radio" name="question1"/>4<br>
</li>
</ul>
<button onclick="calculate()">Submit</button>
<script>
function calculate(){
var answers = [1, 2];
var score = 0;
var question0s = document.getElementsByName("question0");
var question1s = document.getElementsByName("question1");
if (question0s[answers[0]].checked == true) {
score++;
}
if (question1s[answers[1]].checked == true) {
score++;
}
alert ("You got " + score + " out of " + answers.length + ".");
}
</script>
</body>
</html>
It looks like you're calling the script every time an answer changes, and this is very inefficient. I'm only calling when all the answers have been made and the user presses submit.
And the reason why that is adding 4 times is because if you set your first answer to A, it writes it to userinput0 and doesn't get changed anymore since the answer was the only one checked, and it repeats the amount of choices there are, in which there were 4. Thus you are repeating that assignment statement 4 times so you are adding 4.

Loop Over Input Fields; Stop After Two Iterations

I have five form fields that will initially NOT be pre-populated with any values.
If a user fills out one of the fields, the next time they visit the form that field will be pre-populated with the value from the previous visit.
Here's what I'm trying: I'd like to create a loop that iterates through the fields. It will always check to see if there are empty fields. After finding 2 empty fields, the loop will stop and only show those 2 empty fields, while the other fields are hidden.
Here's what I have so far...I just can't figure how to stop after iterating through two fields,
HTML:
<form action="">
<input id="first" type="text" value="" />
<input id="second" type="text" value="" />
<input id="third" type="text" value="" />
<input id="fourth" type="text" value="" />
<input id="fifth" type="text" value="" />
</form>
JS:
$(document).ready(function() {
$('input').hide();
var firstValue = $('input[id="first"]').val(),
secondValue = $('input[id="second"]').val(),
thirdValue = $('input[id="third"]').val(),
fourthValue = $('input[id="fourth"]').val(),
fifthValue = $('input[id="fifth"]').val();
var firstField = $('input[id="first"]'),
secondField = $('input[id="second"]'),
thirdField = $('input[id="third"]'),
fourthField = $('input[id="fourth"]'),
fifthField = $('input[id="fifth"]');
var formValues = [firstValue, secondValue, thirdValue, fourthValue, fifthValue];
var fieldIds = [firstField, secondField, thirdField, fourthField, fifthField];
for (var i = 0; i < fieldIds.length; i++) {
for (var i = 0; i < formValues.length; i++) {
if ( formValues[i] === '' ) {
fieldIds[i].show();
return false;
}
}
}
});
Take all input fields, take the first two empty fields and show them; finally, take the complement of that to hide the rest:
var $inputFields = $('form input:text'),
$emptyFields = $inputFields
.filter(function() { return this.value == ''; })
.slice(0, 2)
.show();
$inputFields
.not($emptyFields)
.hide();
Demo
$(document).ready(function() {
$('input').hide().each( function(){
var index=0; //initilialize the counter
if( $(this).val().length ){ //check for input's length
if(index < 2) {
$(this).show();
index=index+1 //or index++ if you like
}
else {
break;
}
}
}
)};
If you want to include select and textarea fields in your eligible input population, use $(':input').hide().each(...). If you have multiple forms on your page, you would want to include that in your selector, too: $('#intended_form').find(':input').hide().each(...).
http://api.jquery.com/each/
I think that Jack provides the best answer, but this should work too. here, i use a second counter j and break the loop when j % 2 == 0, so at this time its found two empty fields. this is known as a modulus or the modulo operator.
$(document).ready(function() {
$('input').hide();
var firstValue = $('input[id="first"]').val(),
secondValue = $('input[id="second"]').val(),
thirdValue = $('input[id="third"]').val(),
fourthValue = $('input[id="fourth"]').val(),
fifthValue = $('input[id="fifth"]').val();
var firstField = $('input[id="first"]'),
secondField = $('input[id="second"]'),
thirdField = $('input[id="third"]'),
fourthField = $('input[id="fourth"]'),
fifthField = $('input[id="fifth"]');
var formValues = [firstValue, secondValue, thirdValue, fourthValue, fifthValue];
var fieldIds = [firstField, secondField, thirdField, fourthField, fifthField];
var j = 0;
for (var i = 1; i < fieldIds.length; i++) {
if ( formValues[i] === '' ) {
fieldIds[i].show();
j++;//we found an empty field
if (j % 2 == 0)
{
break;
}
}
}
});

Javascript Internet Explorer Issue - what am I doing wrong?

I've looked through many posts to no avail. I have the following in a simple form where one of the products changes based on the number of checkboxes checked. It works in every browser except IE. What am I doing wrong?
<body>
<script type="text/javascript">
function check(){
"use strict";
var count = 0, x=0, checkboxes=document.signup.getElementsByClassName("styled");
for(;x<checkboxes.length; x++){
if(checkboxes[x].checked){
count++;
}
}
if(count<3) {
document.getElementById("variable").value = "1";
}
else if (count == 3){
document.getElementById("variable").value = "74";
}
else if (count == 4){
document.getElementById("variable").value = "75";
}
else if (count == 5){
document.getElementById("variable").value = "76";
}
}
</script>
<form name="signup" id="signup" method="post" action="/subscribers/signup.php">
<input type="checkbox" id="variable" name="product_id[]" value="" class="styled"></input>product 1 - variable</div>
<input type="checkbox" id="same" name="product_id[]" value="3" class="styled"></input>product 2
<input type="checkbox" id="same2" name="product_id[]" value="2" class="styled"></input>product 3
<input type="checkbox" id="same3" name="product_id[]" value="4" class="styled"></input><div class="check-title">product 4
<input type="checkbox" id="same4" name="product_id[]" value="44" class="styled"></input><div class="check-title">product 5
Continue</td></tr>
</form>
</body>
All versions of IE prior to IE9 do not support getElementsByClassName(). You will need to use some sort of substitute.
Instead of this piece of your code:
checkboxes = document.signup.getElementsByClassName("styled");
I would suggest using this:
checkboxes = document.getElementById("signup").getElementsByTagName("input")
getElementsByTagName() is widely support in all versions of IE. This will obviously get all input tags, but only the checkboxes will have checked set so you should be OK.
If you need to filter by class, then you could do the whole thing this way:
function check() {
"use strict";
// initialize checkbox count to 0
var count = 0, item;
// get all input tags in the form
var inputs = document.getElementById("signup").getElementsByTagName("input");
// loop through all input tags in the form
for (var i = 0; i < inputs.length; i++) {
// get this one into the local variable item
item = inputs[i];
// if this input tag has the right classname and is checked, increment the count
if ((item.className.indexOf("styled") != -1) && item.checked) {
count++;
}
}
// get object for result
var obj = document.getElementById("variable");
// check count and set result based on the count
if(count < 3) {
obj.value = "1";
} else if (count == 3) {
obj.value = "74";
} else if (count == 4) {
obj.value = "75";
} else if (count == 5) {
obj.value = "76";
}
}
IE doesnt have method getElementsByClassName... you can try to define it:
if(document.getElementsByClassName == undefined) {
document.getElementsByClassName = function(cl) {
var retnode = [];
var myclass = new RegExp('\\b'+cl+'\\b');
var elem = this.getElementsByTagName('*');
for (var i = 0; i < elem.length; i++) {
var classes = elem[i].className;
if (myclass.test(classes)) {
retnode.push(elem[i]);
}
}
return retnode;
}
};

Categories