Trying to make a simple JQuery/JavaScript calculation - javascript

I'm pretty fresh regarding JS/JQuery, and I'm trying to make a simple calculation/function based on a code I found earlier here. The original code works great, it sums a given col and appends the result as in a new row.
I'm now trying to get a percentage of said result.
<script>
var result = [];
$('#table tr').each(function(){
$('td#pay', this).each(function(index, val){
if(!result[index]) result[index] = 0;
result[index] += parseInt($(val).text());
});
});
var varTax = 24;
$('#table').append('<tr></tr>');
$(result).each(function(){
$('#table tr').last().append('<td colspan="3"> </td><td><b>Totalt</b></td><td id="sumOfPay">'+this+' kr</td><td colspan="2">'+( 100 - varTax ) / 100 * this+'</td>')
});
</script>
var taxCalc and var taxTot is what I've added. But this only prints [object Object].
Edit: I figured it out. The formula I was looking for was +( 100 - varTax ) / 100 * this+

The formula I was looking for was +( 100 - varTax ) / 100 * this+

Related

Loop through jQuery arrays / Output values to a div

I have a button that dynamically creates 2 inputs per click
Data of Input 1: string
Data of Input 2: number (float) (0-100)
I am creating an array of each like this.
var recipe_flavour_name = $("input[name='flav-name']").map(function() {return $(this).val();}).get();
var recipe_flavour_percent = $("input[name='flav-percent']").map(function(){return $(this).val();}).get();
As far as I can tell, the arrays are comma separated values.
Let's for simplicity's sake say:
recipe_flavour_name = a,b,c
recipe_flavour_percent = 5,6,7
I then want to take the number value to use in a function and then loop through all the values and use jQuery's .html() to add the values to a div.
I have tried this: flavPercent1 is just recipe_flavour_percent
var arrayLength = flavPercent1.Length;
for (var i = 0; i < arrayLength; i++) {
var flavML = (flavPercent1[0] / 100 * 100 * 1000) / 1000;
var flavGrams = (flavML * .98 * 100) / 100;
var flavPercent = (flavML / 100 * 1E4) / 100;
$('.live-flavours').html('<tr>'+flavName[0]+'<td></td>'+parseFloat(flavML).toFixed(2)+'<td>'+parseFloat(flavGrams).toFixed(2)+'</td><td>'+parseFloat(flavPercent1[0]).toFixed(2)+'</td></tr>');
};
But I only get flavGrams and flavPercent returned, dynamically adding more data to the array does nothing.
What do I want to achieve?
Grab the values of specified inputs in an array.
Pass them to a function.
Loop through the values and output them in HTML using jQuery.
I hope that makes sense and thanks in advance.
Ok, so assuming that you don't have a problem getting the arrays you need, the problem lies within your for loop.
YOUR CODE:
for (var i = 0; i < arrayLength; i++) {
var flavML = (flavPercent1[0] / 100 * AMOUNT * 1000) / 1000;
var flavGrams = (flavML * .98 * 100) / 100;
var flavPercent = (flavML / AMOUNT * 1E4) / 100;
$('.live-flavours').html('<tr>'+flavName[0]+'<td></td>'+parseFloat(flavML).toFixed(2)+'<td>'+parseFloat(flavGrams).toFixed(2)+'</td><td>'+parseFloat(flavPercent1[0]).toFixed(2)+'</td></tr>');};
You put everything in the for loop, yet make no reference to the index. I'm assuming everywhere you put [0] you actually want [i]. This means that every time the index increases, you are getting the next array element.
You should use .append instead of .html. .html means that the current html will be replaced by what you are adding.
Finally, although making it dynamic is possible, I'm not sure that JQuery is the best libary to use in this case. I'd suggest taking a look at libraries such as Vue or MoonJs (both are very light and very simple libraries) etc... to find a much easier, and frankly better way to do this. They allow for dynamic rendering, and what you are trying to do becomes insanely simplified.
Hope this helps.
(hopefully) WORKING CODE:
for (var i = 0; i < arrayLength; i++) {
var flavML = (flavPercent1[i] / 100 * AMOUNT * 1000) / 1000;
var flavGrams = (flavML * .98 * 100) / 100;
var flavPercent = (flavML / AMOUNT * 1E4) / 100;
$('.live-flavours').append('<tr>'+flavName[i]+'<td></td>'+parseFloat(flavML).toFixed(2)+'<td>'+parseFloat(flavGrams).toFixed(2)+'</td><td>'+parseFloat(flavPercent1[i]).toFixed(2)+'</td></tr>');};

Javascript Wrong Calculations When Storing Value In A Variable or Object

I am trying to animate related columns' width in my HTML layout using a slider.
in this code everything works great, here I am getting new value for another column on slide-UP.
var item.thisWidth; // current width of edited column
var item.prevCellWidth; // current width of previus/last column
fdd
if(slider.value > item.thisWidth){
var prevNewWidth = item.prevCellWidth - (slider.value-item.thisWidth);
$('#r'+item.thisRowId+'s'+item.prevCellRowOrder+'').css('width', prevNewWidth + '%');
}
But here is something weird happening after the calculation on slide-Down. The value created is in 100s of thousands.
Need to keep in mind that the slider min/max value is from 0-100
"slider.value"
if(slider.value < item.thisWidth){
var prevNewWidth = item.prevCellWidth + (item.thisWidth - slider.value);
$('#r'+item.thisRowId+'s'+item.prevCellRowOrder+'').css('width', prevNewWidth + '%');
}
I have tried to check all values that are being passed over for calculation and they show up ok.
alert('oldWidth'+item.thisWidth+'sliderWidth'+slider.value+'previuscell'+item.prevCellWidth+'');
But when decreasing the slider I get these wrong results
e.g. 30 + (40 - 10) = 400000; ??
UPDATE:
Sorted this out by using #rogelio's suggestion - parsing a string into an integer:
var integer = parseInt(string);
Thanks, #rogelio!
The problem is because slider.value is a string. Assuming that you are getting the value from an input, you will need to parse it to integer. with javascript is trivial, for example your line
var prevNewWidth = item.prevCellWidth + (item.thisWidth - slider.value);
needs to change to
var prevNewWidth = item.prevCellWidth + (item.thisWidth - parseInt(slider.value));
I study my self, so for simple things like that sometimes I can spend a while without having someone to direct me to the right information.
parseInt(value); here is my updated question and answer:)
function handleSliderChange(event, slider){
$('#r'+item.thisRowId+'s'+item.thisRowOrder).css('width', slider.value + '%');
var sliderValue = parseInt(slider.value);
var oldValue = item.thisWidth;
var oldPrevValue = item.prevCellWidth;
if(sliderValue > oldValue){
var prevNewWidth = oldPrevValue - (sliderValue-oldValue);
$('#r'+item.thisRowId+'s'+item.prevCellRowOrder).css('width', prevNewWidth + '%');
}
if(slider.value < item.thisWidth){
var prevNewWidth = oldPrevValue + (oldValue - sliderValue);
$('#r'+item.thisRowId+'s'+item.prevCellRowOrder).css('width', prevNewWidth + '%');}
if(slider.value === item.thisWidth){
var prevNewWidth = sliderValue;
$('#r'+item.thisRowId+'s'+item.prevCellRowOrder).css('width', prevNewWidth + '%');
} }
So for guys like me who is not at uni or college ... always create vars for values, in case of numbers also add parseInt(value) --> that should let you avoid common mistakes and save some time:)

d3 how to turn a set of numbers into a larger set representative of the first set

Say I have array [1,2,5,18,17,8] and I want to turn that into an array of length 40 that follows the same path.
a = [1,2,5,18,17,8];
stepSize = 1 / (40 / a.length);
then i think i could do something like
steps = [];
for( var i = 0; i < 1; i+= stepSize) {
steps.push(d3.interpolate(a[0],a[1])(i));
}
and then repeat that for all the elements. My question is there a better way to do this?
I can only guess what your real problem is but I think you want to plot these values and have a smooth curve. In that case use line.interpolate() https://github.com/mbostock/d3/wiki/SVG-Shapes#line_interpolate
In case you DO know what you need and your solution works for you, take this tip:
Never iterate over stepSize. Calculate it once and multiply it with i in every loop where i goes from 0 to 40. This way you work around precision problems.
Your algorithm cleaned up, tested and working:
var a = [1,5,12,76,1,2];
var steps = 24;
var ss = (a.length-1) / (steps-1);
var result = new Array(steps);
for (var i=0; i<steps; i++) {
var progress = ss * i;
var left = Math.floor(progress);
var right = Math.ceil(progress);
var factor = progress - left;
result[i] = (1 - factor) * a[left] + (factor) * a[right];
// alternative that actually works the same:
//result[i] = d3.interpolateNumber(a[left], a[right], factor);
}
console.log(result);

jQuery - Strange rounding error with table calculations with some numbers

I've got a simple table that allows users to enter 2 numbers, and then a script then calculates the annual average and gets the totals for all rows that have the same option in the select menu.
I've setup a sample JSFiddle:
http://jsfiddle.net/fmdataweb/73Jzc/1/
that shows how this works. I've just noticed that at times I get a strange rounding error (I want it to round to one decimal place). For example if you select "moderate" and then enter 5 and 4 for an average of 0.4, then click the button to create a new row and select "moderate" again then enter 3 and 40 for an average of 2.3 you'll notice the total for the moderate is "2.6999999999999997" when it should be 2.7.
If you enter other numbers it's fine so far in my testing but for some reason these combinations don't get rounded for the totals and I'm not sure why. Appreciate if anyone can point out the error in my script. Here's the script that does the averages and totals:
$('#nextYear')
.on('change', 'select', calc)
.on('keyup', 'input', calc);
function calc(){
$('#nextYear tr:has(.risk)').each(function(i,v){
var $cel = $(v.cells);
var $risk = $cel.eq(1).find('option:selected').val();
var $numb = $cel.eq(2).find('input').val();
var $weeks = $cel.eq(3).find('input').val();
var $avg = ($numb * $weeks) / 52;
var $avgRounded = Math.round( $avg * 10 ) / 10;
$cel.eq(4).find('input').val($avgRounded);
});
var tot = {};
$('#nextYear tr:has(.risk) option:selected')
.map(function(i){
var el = $(this).val();
var qty = parseFloat($('#nextYear tr:has(.risk)').eq(i).find('td:last').prev().find('input').val());
if (!tot.hasOwnProperty(el)) {
tot[el] = 0;
}
tot[el] += qty
return tot;
}).get();
// console.log(tot);
$('#textfield6').val(tot.moderate);
$('#textfield7').val( tot.high );
}
​
You problem is here:
$('#textfield6').val(tot.moderate);
$('#textfield7').val( tot.high );
You must round them like you did with
var $avgRounded = Math.round( $avg * 10 ) / 10;
or using .toFixed(1)
Edit:
Then, the code is:
$('#textfield6').val(tot.moderate.toFixed(1));
$('#textfield7').val(tot.high.toFixed(1));
You can see it here: http://jsfiddle.net/73Jzc/2/
Try $avg.toFixed(1); instead of Math.round( $avg * 10 ) / 10;

Incrementing a number smoothly with a variable time period in JS

I have a really simple JS counter which I display on a dashboard like screen which does the following:
Every 5 minutes it makes an jsonp call and retrieves a "total" number
It then displays this number to the screen by incrementing the last total displayed till it is equal to the new total. (the number can only ever increase)
I'm having some trouble with making the number increment smoothly. What I would like to do is find a delta (i.e. New total - old total) and increment the number gradually over the 5 minutes till the next call so it looks like a nice smooth transition.
Any ideas on how I can do this?
Currently some of my code looks like this (This block get's called every 5mins. And yes, it's in dire need of a refactor...)
var LAST_NUMBER_OF_SESSIONS = null;
var five_minutes_in_seconds = 300;
var new_number_of_sessions;
$.getJSON('http://blah.com/live_stats/default_jsonp.aspx?callback=?', function(data) {
if(LAST_NUMBER_OF_SESSIONS === null){
LAST_NUMBER_OF_SESSIONS = data.total_sessions;
}
new_number_of_sessions = data.total_sessions;
var delta = Math.floor(new_number_of_sessions - LAST_NUMBER_OF_SESSIONS);
var time_interval = (five_minutes_in_seconds / delta) * 1000;
var old_value = LAST_NUMBER_OF_SESSIONS;
var new_value = null;
sessions_interval = setInterval(function (){
new_value = parseInt(old_value, 10) + 1;
$('#stats').text(new_value);
old_value = new_value;
if(new_value >= new_number_of_sessions){
clearInterval(sessions_interval);
}
}, time_interval);
LAST_NUMBER_OF_SESSIONS = new_value;
});
}
This code it seems to increment the number very quickly at the start of the 5min period and then stop so it's not exactly right...
Try this:
var total = 0,
delta = 0,
stats = $('#stats').text( total );
function increment() {
var v = +stats.text();
if ( v < total ) {
stats.text( v + 1 );
} else {
$.getJSON('http://...', function(data) { // added data here
delta = Math.floor( 300000 / ( data.total_sessions - total ) );
total = data.total_sessions;
});
}
setTimeout(increment, delta);
}
Update:
In order to test my code, I had to simulate the JSON reponse - I used an array of numbers. See here: http://jsfiddle.net/simevidas/MwQKM/
(In the demo, I use an interval of 5 seconds instead of 5 minutes.)
I am not exactly sure why your code doesn't work as expected, although I suspect that it has to do with line LAST_NUMBER_OF_SESSIONS = new_value;. I wrote something similar and it works fine. It's not that different from what you have, minus that last line of code.

Categories

Resources