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);.
Related
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);
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()
}
I would like to update the accordion header FormationName information directly from UI when user clicks on refresh button.
However, in the current design accordion header is updated by hard coded string ("party") just for testing purpose. When user clicks on refresh button first accordion header FormationName is updated.
$("#refresh").click(function () {
myData.offsetFormations[0]["FormationName"] = "party";
$('#accordion').accordion('destroy');
build();
});
http://jsfiddle.net/xg7cr0g4/85/
Ok, here's what I came up with. First, add all elements with the class .formationName into an array. It should have the same length as your myData.offsetFormations:
var names = [];
var counter = 0;
$(".formationName").each(function(){
names[counter] = $(this).text();
counter++;
});
Logging this element will result in an array of 8 names, which have the values of the headers (adjusted or otherwise.)
Next, loop over your myData.offsetFormations and set the value of [i]["FormationName"] to that of the name array:
for(var i = 0; i < myData.offsetFormations.length; i++){
myData.offsetFormations[i]["FormationName"] = names[i];
}
Your whole function should look like this:
$("#refresh").click(function () {
var names = [];
var counter = 0;
$(".formationName").each(function(){
names[counter] = $(this).text();
counter++;
});
for(var i = 0; i < myData.offsetFormations.length; i++){
myData.offsetFormations[i]["FormationName"] = names[i];
}
$('#accordion').accordion('destroy');
build();
});
And here's the updated fiddle showing the function in action:
JSFiddle
Hope that helps!
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();
});
i'm trying to make a live search for my mobile website, I don't want to query the database every time a user type a letter so I created a ordered list with all the names that can be searched for and i'm looping through it with jquery, problem is that I have 3300 names and it's freezing the browser when it searches through them, can anyone give me a tip about better ways to do it? here is my code:
$(document).ready(function(){
$("input#search").keyup(function(){
var filter = $(this).val(), count = 0;
var html = "";
$("ol.pacientes li").each(function(){
var nome_paciente = $(this).text();
if(nome_paciente.indexOf(filter.toUpperCase()) != -1){
html = html + " " + nome_paciente;
}
$('#pacientes_hint').html(html);
});
Use the jQuery autocomplete version. You can load an array with all your names and pass it in to autocomplete, which will work on the fly.
http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/
You could change your each to:
var text = $("ol.pacientes li:contains(\""+filter.toUpperCase()+"\")").map(function() {
return $(this).text();
}).join(' ');
$('#pacientes_hint').text(text);
Besides being shorter, the only improvement will be setting the contents of $('#pacientes_hint') only at the end, which could help.
Let me know if you need a more creative solution.
First of all, you could move #pacientes_hint outside the each function.
$(document).ready(function(){
$("input#search").keyup(function(){
var filter = $(this).val(), count = 0;
var html = "";
$("ol.pacientes li").each(function(){
var nome_paciente = $(this).text();
if(nome_paciente.indexOf(filter.toUpperCase()) != -1){
html = html + " " + nome_paciente;
} // end if
}); // end each
$('#pacientes_hint').html(html);
Then, you can define ol.pacientes as a variable before the keyup handler, so it doesn't look for it everytime and in the each function, search inside the variable:
$(document).ready(function(){
var pacientes_list = $("ol.pacientes");
var pacientes_hint = $("#pacientes_hint");
$("input#search").keyup(function(){
...
$("li", $(pacientes_list)).each(function(){ // search in the container
...
}); // end each
$(pacientes_hint).html(html);