Pass var and refresh Div on blur - javascript

I have the following code, the alert works fine. the div refreshes fine, the var is not returned what am I missing, thanks
$('.cap_per_day').blur(function () {
var sum = 0;
var remaining = 0;
$('.cap_per_day').each(function() {
if ($(this).val() != "") {
sum += parseFloat($(this).val());
remaining = total - sum;
}
});
//alert('Total Remaining '+ remaining);
$(document.getElementById('div.alert-div')).innerHTML = remaining;
$("div.alert-div").fadeIn(300).delay(2000).fadeOut(400);
});

It's not clear exactly what the problem you're trying to solve is, however from your code sample I can tell you that a jQuery object doesn't have an innerHTML property, and the 'id' selector looks more like a class. Try this instead:
$('div.alert-div').html(remaining);

Related

How do I add up the vals of inputs using jquery?

I'm working on a GPA calculator, but I've hit a road block.
Here's how the calculator looks like: http://codepen.io/m6cheung/pen/KdWGxa.
Here is the JS part of it:
var $units = $('.units');
var $grade = $('.grade-select');
var $gpa = $('#gpa');
var sum = 0;
$('.btn').click(function() {
$('.block').last().clone().children().val("").parent().appendTo($('.inner-box'));
});
$('.result').hide();
$units.keyup(function() {
$gpa.text((($grade.val() * $(this).val()) / $(this).val()).toFixed(2));
});
$grade.change(function() {
$gpa.text((($units.val() * $(this).val()) / $units.val()).toFixed(2));
$('.result').show();
});
What I want to know: is there any other way, so I can use jQuery to manipulate further $units and $grade values when I press the Add Course button? For now, it only works for the first set of input values.
after adding a new row the keyup and change events are not bind to them.
try using:-
$(document).on('keyup','.units', function() {
and
$(document).on('change','.grade-select', function() {
EDIT from comment
to add them up, create a new function:
function sumScores(){
var score = 0;
$('.block').each(function(i, element){
var unit = $(element).find('.units').val();
var grade = $(element).find('.grade-select').val();
// do calculation and add to score
});
$gpa.text(score.toFixed(2);
}
then set that function to the keyup/change handler.
$(document).on('keyup','.units', sumScores);
$(document).on('change','.grade-select', sumScores);
Since the inputs are added dynamically, you need to bind events to the closest static parent, such as .outer-box. Binding it to document is bad/costly due to event bubbling. Adding up the inputs is as easy as writing a function that would be called on keyup and change which also eliminates code duplication.
var $oBox = $('.outer-box'),
$gpa = $('#gpa'),
$result = $('.result').hide();
$('.btn').click(function() {
$('.block').last().clone().children().val("").parent().appendTo($('.inner-box'));
});
$oBox.on("keyup", ".units", function() {
$gpa.text(getTotal());
});
$oBox.on("change", ".grade-select", function() {
$gpa.text(getTotal());
//Show $result only if it's hidden
$result.is(":hidden") && $result.show();
});
//The function I stated above
function getTotal() {
var sum = 0;
//Loop thru the units
$('.units').each(function() {
var $this = $(this);
//You must also check if the entered unit is a number
//to avoid operating on non-number inputs
//https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/isNaN
if ( !isNaN($this.val()) ) {
//Input vals are always of type string, so, convert them to numbers
//Multiply the pairs
sum += parseFloat($this.val()||0) * parseFloat($this.parent().find('.grade-select').val()||0);
}
});
//Format the number
return sum.toFixed(2);
}
Your updated pen
I noticed the beginning of your code starts with:
var $units = $('.units');
And your inputs are dynamically generated by cloning.
One reason why your computation only works at first input is because $input only points to the fist input, same with $grade.
Maybe you are expecting that $input will automatically take other input as they are cloned. It is not the case. It does not work like CSS rules.
You need to re-execute the line for every clone like this:
$('.btn').click(function() {
$('.block').last().clone().children().val("").parent().appendTo($('.inner-box'));
$units = $('.units');
$grade = $('.grade-select');
});
To manipulate all values you need to loop all elements like this:
var sum = 0;
for (var n = 0; n < $units.length; n++) {
sum += 1 * $($units[n]).val();//1 * -> is for assurance it adding not concat
//to retreive $grade use $($grade[n]).val()
}

Get total of all data attribute values

I am dynamically loading some of the content within my page and would like to get a total of all the data-attributes.
First the elements are cloned and appended
$('.chip').on('click', function () {
$(this).clone().appendTo('.chipPlacement');
});
Then I have written a function that should get the totals
function chipsBet() {
var redchip = $('.chipPlacement .chipValue.r').data() || 0;
var bluechip = $('.chipPlacement .chipValue.b').data() || 0;
var orangechip = $('.chipPlacement .chipValue.o').data() || 0;
var total = redchip.chipValue + bluechip.chipValue + orangechip.chipValue;
return total;
}
Before I append the elements the HTML looks like
<div class="chipPlacement"></div>
and once appended the HTML structure is
<div class="chipPlacement">
<div class="chip red">
<div class="chipValue r" data-chip-value="1">1</div>
</div>
</div>
I need to listen for the DOM structure the change and then fire the chipsBet() function, but I'm not sure how to get this to work. I can't use .on('change') as that only applies to input, textarea and select.
I have tried firing the chipsBet function within the .chip.on('click') but I get NaN returned.
How can I get the data-attribute-values for the new elements in the DOM?
If you don't have a blue or orange chip, you're effectively trying to get .chipValue from 0 which is undefined and adding it to another number gives you NaN.
You can simply iterate over all .chipValue elements within the placement element like so:
function chipsBet()
{
var total = 0;
$('.chipPlacement .chipValue').each(function() {
total += $(this).data('chipValue');
});
return total;
}
Nevermind, you altered your initial question.. carrying on.
<div class='chipPlacement'>
<div class='chip red'>
<div class='chipValue' data-chip-value='1'></div>
</div>
</div>
Then to read your data attributes, you could do something like this.
$('.chip').on('click', function () {
$(this).clone().appendTo('.chipPlacement');
chipsBet();
});
function chipsBet() {
var redchipVal = parseInt($('.chipValue .r').data('chip-value')) || 0;
var bluechipVal = parseInt($('.chipValue .b').data('chip-value')) || 0;
var orangechipVal = parseInt($('.chipValue .o').data('chip-value')) || 0;
var total = redchipVal + bluechipVal + orangechipVal;
return total;
}
I think you want something like bellow. It will call the function every time any change will in div .chipPlacement.
$('.chipPlacement').bind("DOMSubtreeModified",function(){
console.log('Div modified');
});
You can say for your problem
$('.chipPlacement').bind("DOMSubtreeModified",function(){
chipsBet();
});
DEMO

Passing the JavaScript variable into HTML

My JavaScript code is:
<script type="text/javascript">
var current = 0;
var cars = new Array(5);
cars[0] = "Audi";
cars[1] = "Bentley";
cars[2] = "Mercedes";
cars[3] = "Mini";
cars[4] = "BMW";
document.getElementById("addCarBtn").onclick = function () {
if (!(current > cars.length - 1)) {
document.getElementById("carsDiv").innerHTML += cars[current] + "<br />";
current++;
}
}
</script>
I want to display the value of each array item one by one on button click the div.
But when i click the button, the array[0] i.e "Audi" is displayed but just for fraction of seconds. then it disappears and only the button is visible.
You can use a loop like:-
for(var i=0; i< cars.length;i++)
{
alert(cars[i]);
}
//It will show alert 5 times. You'll need to click through ok to traverse all array elements.
//I think it is what you're thinking, or have I interpreted it wrong.
// I'm assuming you're completely new to javascript then on your button write onclick="yourFuncName();"
function YourfuncName()
{
//Initailze your array here, like you have done or like kamituel has done
// then just print each array element one by one
for(var i=0; i< cars.length;i++)
{
alert(cars[i]);
}
}
How about the every method?
cars.every( function(c) {
alert("car: " + c);
});
You're almost there. Since the JS code was located before the HTML, the button element still doesn't exist. Best just wrap the code with window.onload and it should work:
window.onload = function() {
document.getElementById("addCarBtn").onclick = function() {
if (!(current > cars.length - 1)) {
document.getElementById("carsDiv").innerHTML += cars[current] + "<br />";
current++;
}
}
};
Live test case.
Edit: just noticed your button doesn't have type. This means that some browsers might make it a submit button by default, which will cause a page reload. To avoid it, make it a plain button:
<button id="addCarBtn" type="button">

Update div with jQuery upon entry of data

I have a form with four text input elements. Every time one of them is updated, I want the sum of the four text input boxes to be displayed in a div below without the user pushing a button. Here's what I have so far (I got the idea from here [does this only work with select?]):
var getSum = function() {
var email = $('#emailDown').val();
var internet = $('#internetDown').val();
var server = $('#serverDown').val();
var desktop = $('#pcDown').val();
//TODO:Check for integers (not needed with sliders)
var sum = email + internet + server + desktop;
$('totalHoursDown').html(sum);
}
$('#emailDown').change(getSum(event));
$('#internetDown').change(getSum(event));
$('#serverDown').change(getSum(event));
$('#pcDown').change(getSum(event));
Currently, it's not updating. (Don't worry about validating). I'm new to PHP, so I'm not sure if I should be using it in this instance.
You are missing a # or . in your selector, depending on if totalHoursDown is a class or an ID:
$('totalHoursDown').html(sum);
// Should be this if ID
$('#totalHoursDown').html(sum);
// or this if class
$('.totalHoursDown').html(sum);
Update:
I modified the code by jmar777 a bit to make it work. Try this instead:
$(function(){
var $fields = $('#emailDown, #internetDown, #serverDown, #pcDown'),
$totalHoursDown = $('#totalHoursDown');
$fields.change(function() {
var sum = 0;
$fields.each(function()
{
var val = parseInt($(this).val(), 10);
sum += (isNaN(val)) ? 0 : val;
});
$totalHoursDown.html(sum);
});
});
​Here is a working fiddle as well: http://jsfiddle.net/mSqtD/
Try this:
var $fields = $('#emailDown, #internetDown, #serverDown, #pcDown'),
$totalHoursDown = $('#totalHoursDown');
$fields.change(function() {
var sum = 0;
$fields.each(function() { sum += $(this).val(); });
$totalHoursDown.html(sum);
});
Also, in your example, you had $('totalHoursDown').html(sum);, which I'm assuming was intended to be an ID selector (i.e., $('#totalHoursDown').html(sum);.

Dynamically changing costs in custom pc builder with checked inputs

First, please take a look at my fiddle.
I'm trying to figure out a clean way of making the price next to each item change when any item is selected (in that group, you can image that there will be graphics cards etc in a different section which also will need the same functionality).
If its positive I need the class to be .positive and vice versa, and if the item is selected (+0) then the price difference wont be displayed.
This will also be used on checkbox's.
Non-working example.
You'll want to compare each selected item with items having the same name. In the .each() loop in CalculatePrice(), pass the checked item to this function:
function CalculateDiffs(item) {
var selectedPrice = +item.data("price");
item.siblings(".item_price").text("");
$(".calculation-item[name='"+item.attr("name")+"']").not(item).each(function(){
var price = +$(this).data("price");
var diff = (price-selectedPrice).toFixed(2);
if (diff >= 0) {
diff = "+"+diff;
}
$(this).siblings(".item_price").toggleClass("negative", diff < 0).text(diff);
});
}
As for checkboxes, the above function will take care of hiding the price when it is checked. To display the prices for unchecked checkboxes:
$(".calculation-item:checkbox:not(:checked)").each(function(){
$(this).siblings(".item_price").text("+"+$(this).data("price"));
});
Or, if you want to display the price of a checked checkbox as negative, use this instead:
$(".calculation-item:checkbox").each(function(){
var diff = (this.checked ? "-" : "+") + $(this).data("price");
$(this).siblings(".item_price").toggleClass("negative",this.checked).text(diff);
});
http://jsfiddle.net/gilly3/HpEJf/8/
Actually it's pretty straight forward, all you'll need to do is calculate the difference between the selected price and the price of all the options in the list. Eg, something like this:
$(".calculation-item").each(function(index) {
var my_cost = base_price + $(this).data("price");
var difference = Math.round(my_cost - base_cost);
});
I've created a working jsFiddle for you here: http://jsfiddle.net/HpEJf/6/. You'll need to implement decimal rounding etc but this should put you on the right track :)
If my understanding is correct, you want to display the cost difference from the previously selected radio button and the currently selected radio button.
To do that you need to keep track of the previously selected button. The only way I know of to do that is to set a variable outside the clickhandler scope to keep track of it and update the element in the clickhandler.
The rest is fairly straightforward. I updated your jsFiddle with an example of how to do it. The relevant code is below:
Adding at top of script:
//global for last checked/selected radio
var lastSelection = $(".calculation-item:checked");
//clear existing price diffs set by markup
$('span.processor_price').text('');
Added another function:
function priceDifference(oldPrice, newPrice) {
var difference = {
'cssClass': '',
'inCost': '0'
};
var fixedDiff = '';
var diff = newPrice - oldPrice;
diff = Math.ceil(Math.abs(diff * 100)) / 100;
fixedDiff = diff.toString();
if (newPrice < oldPrice) {
difference.cssClass = 'negative';
difference.inCost = '-' + fixedDiff;
} else if (newPrice > oldPrice) {
difference.cssClass = 'positive';
difference.inCost = '+' + fixedDiff;
}
/* else {
* must be the same, no reason for this block
* as the default empty string will suffice
* as will the cost difference of 0
}*/
return difference;
}
And changed your click handler to:
$(".calculation-item").click(function() {
var difference = {};
if (lastSelection) {
//get difference
difference = priceDifference($(lastSelection).data("price"), $(this).data("price"));
//change class
$(this).siblings('span.processor_price').addClass(difference.cssClass).text(difference.inCost);
$(lastSelection).siblings('span.processor_price').removeClass('positive').removeClass('negative').text('');
if (lastSelection !== this) {
lastSelection = this;
}
} else {
lastSelection = this;
}
CalculatePrice();
});​

Categories