I need to add and delete the number "7" based on a user checking a checkbox and then display that number on the page:
var theTotal = 0;
$("#highlightChk").change(function() {
var ishchecked= $(this).is(':checked');
if(!ishchecked) theTotal -= 7;
if(ishchecked) theTotal += 7;
});
$('#total').text(theTotal);
When I display the code it is "0" even when I check the checkbox. What am I doing wrong?
Place an initial value in #total and each time an operation is being done read the value and parse it and add to or subtract from it. The #total element has to be updated within the change event handler.
$(function() {
$("#highlightChk").on('change', function() {
//READ & PARSE existing value
var total = +$('#total').text();
//INC-/DECREMENT value accordingly
total += this.checked ? 7 : -7;
//UPDATE DOM with new value
$('#total').text( total ); //<<--- BELONGS INSIDE
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" name="highlight" id="highlightChk"/> Highlight<br><br>
Total: <div id="total">0</div>
You need to put the $('#total').text(theTotal); inside the change method
$("#highlightChk").change(function () {
var theTotal = 0;
var ishchecked = $(this).is(':checked');
if (!ishchecked) theTotal -= 7;
else theTotal += 7;
$('#total').text(theTotal);
});
Since theTotal as a global variable is always 0, but when it's inside the local scope of the jquery .change() method you will always get the correct changed value.
FIDDLE DEMO #1
You can also achieve the same result with less code like:-
$("#highlightChk").change(function () {
$('#total').text(this.checked ? 7 : 0);
});
FIDDLE DEMO #2
Related
I have a score variable and I'm trying to add 1 to it every time a word is clicked, and display the score on the webpage. Here is the html:
<p>1. The <span id="noun">dog</span> and the <span id="noun">kitten</span> play with the <span id="noun">ball</span>.</p>
<h3>Score: <span id="results1"></span> out of 9</h3>
and here is the javascript:
var nounAll = document.querySelectorAll('#noun');
var score = 0;
var result1 = document.querySelector('#result1');
for(var i = 0; i < nounAll.length; i++) {
console.log(nounAll[i].textContent)
nounAll[i].addEventListener("mouseover",function()
{
this.classList.add("hovered")
});
nounAll[i].addEventListener("mouseout", function()
{
this.classList.remove("hovered")
});
nounAll[i].addEventListener("click", function()
{
this.classList.toggle("clickedOn")
score++;
});
}
document.getElementById("results1").textContent = score;
What am I doing wrong?
Your score variable is working fine. You just need to update the Score element:
nounAll[i].addEventListener("click", function()
{
this.classList.toggle("clickedOn")
score++;
// Add the below line
document.getElementById("results1").textContent = score;
});
The problem is that after the click event is fired, you don't assign the new score to your target DOM element on every action.
nounAll[i].addEventListener("click", function()
{
this.classList.toggle("clickedOn")
score++;
document.getElementById("results1").textContent = score; // add this line to your click event handler
});
var nounAll = document.querySelectorAll('#noun');
var score = 0;
var result1 = document.querySelector('#result1');
for(var i = 0; i < nounAll.length; i++) {
console.log(nounAll[i].textContent)
nounAll[i].addEventListener("mouseover",function(e)
{
e.target.classList.add("hovered")
});
nounAll[i].addEventListener("mouseout", function(e)
{
e.target.classList.remove("hovered")
});
nounAll[i].addEventListener("click", function(e)
{
e.target.classList.toggle("clickedOn")
score++;
document.getElementById("results1").textContent = score;
});
}
<p>1. The <span id="noun">dog</span> and the <span id="noun">kitten</span> play with the <span id="noun">ball</span>.</p>
<h3>Score: <span id="results1"></span> out of 9</h3>
There are 2 mistakes:
Your element IDs are not unique, you want to use classes instead, so change id="noun" to class="noun" in the HTML and change the selector in document.querySelectorAll accordingly (dot rather than hash).
There is a logic error: you are updating a js variable but after you update the variable you also have to change the content of the span accordingly (in the fiddle I have put an example of how you can do that)
My solution
I have this code but is not working properly.
The idea is that every input has a value and sum or subtract its value from the total price depending if you click up or down.
Right now is just adding and adding and adding like crazy.
Thank you very much.
the JS:
$( document ).ready(function() {
$(".quantity").each(function(){
$(this).change(function(){
var quantity = ($(this).val());
var ammount = ($(this).attr("data-price"));
var price = $(this).closest(".bookSection").find(".item_price").html();
var subtotal = ammount * quantity;
var total = parseInt(subtotal) + parseInt(price);
$(this).closest(".bookSection").find(".item_price").html(total);
});
});
});
here the example:
http://jsbin.com/tolequyobi/1/edit?html,js,output
Instead of trying to use the .item_price just calculate it from the start. If not you will need to store the old value to know if you need to add or subtract.
You can do something like this
$('.quantity').change(function(){ // check change on the inputs
var total = 0; // set the total to 0
$(this).parent().find('.quantity').each(function() { // loop on all the items thats in this block
total += parseInt($(this).attr('data-price')) * parseInt($(this).val()); // add to the total their value
});
$(this).parent().find(".item_price").html(total); // and then add it to your html
});
How about recomputing the total from scratch whenever the quantity changes, instead of trying to keep a running total that you have to maintain?
$( document ).ready(function() {
var price = 0;
$(".quantity").each(function(){
$(this).change(function(){
var total = computeTotal($(this).closest(".bookSection"));
$(this).closest(".bookSection").find(".item_price").html(total);
});
});
});
function computeTotal(bookSection){
var total=0;
bookSection.children('.quantity').each(function(item){
total += $(this).val() * $(this).attr("data-price");
});
return total;
http://jsbin.com/rimubocijo/edit?html,js,output
If I am looping through elements in a table - say a hidden field of class "pmtos" - how do I get a reference to the text field (input) within the same cell in the table?
jQuery is:
// Loop through each hidden field, which holds the outstanding amount
$(".pmtos").each(function () {
var os = $(this).val();
//
//find text box in same cell - and populate with some value
//
//
});
Thank you for any guidance in getting this working.
Mark
Here's a solution to the question before it was edited (as requested):
$('#allocate').click(function () {
var recd = parseFloat( $('#pmtRecd').val() );
$('input.pmtallocated').each(function() {
var value = parseFloat( $(this).parent().prev().text() );
this.value = (recd >= value) ? value : recd;
recd = recd - this.value;
if (recd == 0) {
return false;
}
});
});
Note: This doesn't rely on the hidden input. It takes the text from the td in the second column.
Here's the fiddle
To answer the question post-edit
You can use siblings('.pmtallocated') or prev('.pmtallocated') to get the input. Using siblings() would probably be the better of the two as it doesn't rely on pmtallocated coming directly before pmtos in the markup:
$(this).siblings('.pmtallocated').val()
Try
// Loop through each hidden field, which holds the outstanding amount
$(".pmtos").each(function () {
var os = $(this);
var cell = os.parent(); // gets the parent, i.e. the table cell
var input = cell.find('input')[0];
});
You could use $(this).closest('input')
Check this out. may works for you.
$(".pmtos").each(function () {
var os = $(this).val();
var input = $(this).closest('td').find('input[type=text]');
});
This must be very simple, but I just got stuck with this... I have a list of products with an input field for the quantity and next to it a column with the prices. The prices are displaying two values. One of them is hidden. If the value of the input field goes over a certain value, it should hide the other price.
Example:
(input: [], show price1price2 )
input: [2], show <span class=one>price1</span>
input: [5], show <span class=one>price1</span>
input: [8], show <span class=two>price2</span>
input: [9], show <span class=two>price2</span>
My code so far (example, since I show just 2 products):
<form name="formname" action="formaction" method="post">
prod 1<input type="text" value="" class="class1" size="3"><span class="one">$1.00</span><span class="two">$2.00</span>
prod 2<input type="text" value="" class="class1" size="3"><span class="one">$4.00</span><span class="two">$6.00</span>
</form>
And at the bottom in script tags:
$(document).ready(function() {
if($('input.class1').val() > 5) {
$('.one').show();
$('.two').hide();
}
});
What am I missing? The form name perhaps?
This is just the first part...
My other question would be.. how can I make it so that if the sum of all the input fields (with class1 as class) is more than 5, do the same. (So now depending on the sum of the input fields, rather than each individual one)
var inputs = $('input[class^=class]'); // get inputs which class name
// start with "class" eg: class1, class2..
// fire blur event
// you may use keyup or something else
inputs.on('blur', function(e) {
var val = 0;
// adding all inputs value
// of all inputs with class = blured input class
$('input.' + this.className).each(function() {
val += parseInt( this.value, 10);
});
// checking for condition
if (val > 5) {
$(this).next('.one').show().next('.two').hide();
} else {
$(this).next('.one').hide().next('.two').show();
}
});
Demo with blur
Demo with keyup
Note
Place you all jQuery codes within $(document).ready().
According to comment
See this update
Code
if (val > 5) {
$('.one').show();
$('.two').hide();
} else {
$('.one').hide();
$('.two').show();
}
Update after last comment
Just change
val += parseInt( this.value, 10);
to
val += parseInt( this.value || 0, 10); // default 0, if no value given
According to comment
How to implement above code for select box?
var selects = $('select[class^=class]'); // get selects which class name
// start with "class" eg: class1, class2..
// fire change event
selects.on('change', function(e) {
var val = 0;
// adding all selects value
$('select.' + this.className).each(function() {
val += parseInt( this.value, 10);
});
// checking for condition
if (val > 5) {
$(this).next('.one').show().next('.two').hide();
} else {
$(this).next('.one').hide().next('.two').show();
}
});
You are calling this on page load, you need to run it each time the value of the input fields is changed.
Consider wrapping your if block in this:
$('input.class1').blur(function() {
if($('input.class1').val() > 5) {
$('.one').show();
$('.two').hide();
}
});
Or something to that effect, consider using $.on().
If you want to sum them, assign each input a common class, and use $.each():
$('.common-class').each(function() {
sum = sum + $(this).val()
});
Hope this helps.
I'm using the jQuery validate plugin. I'm trying to calculate the sum of all inputs fields using the class .percent. If the sum of the .percent fields isn't equal to 100%, throw validation error.
The percent rows are a part of a dynamic grid and can very in number. You'll see a sample of what I've been working on below. I'm finding the addMethod is called for every input.percent rather than a single time. I'd also like to say it's being called before submit is called.
the code.
html
<div class="row">
<input value="" class="percent"/>
</div>
<div class="row">
<input value="" class="percent"/>
</div>
js
$.validator.addClassRules({
percent: {percent:true}
});
$.validator.addMethod("percent",
function cals(value, element) {
// all the fields that start with 'coeff'
var percent = element;
var total = 0;
for (var i = 0; i < percent.length; i++) {
total += Number(percent[i].value);
}
return total == 100;
}, $.format("Percentage fields most total up to 100%"));
$("form").validate({
});
Updates
I've tried the following code with minor success
$("#modify-funding .percent").rules('add', {sum: 100});
$.validator.addMethod("sum", function (value, element, params) {
var sumOfVals = 0;
$("#modify-funding .percent").each(function () {
sumOfVals = sumOfVals + parseInt($(this).val().length ? $(this).val() : 0);
});
if (sumOfVals == params) return true;
return false;
},
$.format("Percentage fields most total up to 100%")
);
when passing the class into rules it's only passing in a single element which doesn't enable me to query for the additional percent fields. The other issue is it only adds the error class to the first .percent element and the additional elements will not release the error once the 100% criteria has been met.
Update 2
This is the closest I've come to getting percent validation working. It isn't very efficient code since it needs to loop through all the percent fields every time you loop the rules. The code still validates before a submit action has taken place plus does not clear all the percent errors on keyup when the percent has been corrected to equal 100.
$("#modify-funding .percent").each(function() {
$(this).rules('add', {sum: [".percent"]});
})
$.validator.addMethod("sum", function (value, element, params) {
var sumOfVals = 0;
$(params[0]).each(function() {
sumOfVals += parseFloat($(this).val().length ? $(this).val() : 0);
});
if (sumOfVals == 100) return true;
return false;
},
$.format("Percentage fields most total up to 100%")
);
Don't use jquery for such a simple validation. I don't really understand what all the hype is about jquery. It just makes your code look all ugly.
function validate() {
var ret = false;
var total = 0;
var elems = document.getElementsByTagName('*'), i;
for (i in elems)
if (elems[i].className == "percent")
total += parseFloat( elems[i].value);
if (total == 100)
ret = true;
return ret;
}