Average of four fields in a form - javascript

form.getElement('ar_essay1_read1_subscore4').bind('change', function() {
calcEssayScore();
}).bind('keyup', function() { $(this).triggerHandler('change'); });
function calcEssayScore()
{
var score1 = form.getElement('ar_essay1_read1_subscore1').val();
var score2 = form.getElement('ar_essay1_read1_subscore2').val();
var score3 = form.getElement('ar_essay1_read1_subscore3').val();
var score4 = form.getElement('ar_essay1_read1_subscore4').val();
var recalc = ((score1 + score2 + score3 + score4) / 4);
form.getElement('sys:app:ar_essay1_read1').val(recalc.toFixed(3));
}
I know this is a total rookie javascript error, but this keeps returning errors. If i put 4 into each field in the form, it's return 1111.000 as the sys:app:ar_essay1_read1 score. How should I be structuring the formula to make it work correctly?

You need to use parseInt(val, 10) or parseFloat(val) to convert the value of each form field as number. Otherwise, you are just doing string manipulation.

Related

How to make if statement keep working after clicking on a button once

I will try to explain it better. I rewrote a code, to make it better as an example. As you can see I have an app to generate a number, but to generate correct number I have to click 5-15 times on a button, due to random and if statement. I want to ask how to make a process to skip incorrect numbers and give an actual answers ( which took 5-15 clicks ) only in one click. I can give more information, if you didn't understand me. Thank you very much!
*video: https://vimeo.com/251109159
function getnumber() {
var input = document.IX.onetoThou.value;
var firstNum = input[0];
var ranNumb = Math.floor(Math.random()*(99-00+1)+00);
var ans = "you are right!";
var newNumber = firstNum + ranNumb;
if ( newNumber % 5 == 0){
document.getElementById("newnumber").innerHTML = newNumber+" "+ans;
}
}
You can wrap the generation of your number inside a do while loop:
function getnumber() {
var input = document.IX.onetoThou.value;
var firstNum = input[0];
var ans = "you are right!";
var newNumber;
do {
var ranNumb = Math.floor(Math.random()*(99-00+1)+00);
newNumber = firstNum + ranNumb;
} while (newNumber % 5 !== 0);
document.getElementById("newnumber").innerHTML = newNumber+" "+ans;
}
Instead of generating a random integer in [0, 100) and checking to see if it's a multiple of 5, generate a random integer in [0, 20) and multiply it by 5. That guarantees that your result will be a multiple of 5 between 0 and 100.
var ranNumb = Math.floor(Math.random() * 20) * 5;
hope this might help. You have to use if-else rather then if conditional statement
function getnumber() {
var input = document.IX.onetoThou.value;
var firstNum = input[0];
var ranNumb = Math.floor(Math.random()*(99-00+1)+00);
var ans = "you are right!";
var newNumber = firstNum + ranNumb;
if ( newNumber % 5 == 0){
document.getElementById("newnumber").innerHTML = newNumber+" "+ans;
}else{
document.getElementById("newnumber").innerHTML = "You are wrong";
}
}

jQuery function calculation wrong

I have this function
$("#exchange").on("change", function() {
var am = $(this).val();
var fee = $("#fee").val();
var cost = $("#cost").val();
var perc = fee / 100;
var tot = perc * am;
var fea = parseFloat(tot) + parseFloat(cost);
var total = parseFloat(am) - parseFloat(tot) - parseFloat(cost);
$("#return").val(total.toFixed(2));
$("#due").val("$" + fea.toFixed(2));
});
$("#return").on("change", function() {
var am = $(this).val();
var fee = $("#fee").val();
var cost = $("#cost").val();
var perc = fee / 100;
var tot = perc * am;
var fea = parseFloat(tot) + parseFloat(cost);
var total = parseFloat(am) + parseFloat(tot) + parseFloat(cost);
$("#exchange").val(total.toFixed(2));
$("#due").val("$" + fea.toFixed(2));
});
for example if #exchange = 16.85, #fee = 11, and #cost = 0
it should calculate #due = $1.85 and #return = 15.00
which is all correct. The problem is working in reverse I need it to calculate the same way but instead right now I get this
#return = 15, #fee = 11, and #cost = 0
it calculates #due = $1.65 and #exchange = 16.65
I understand why it is doing that, because it is calculating the fees from the var am which is the value of that field, which makes it very difficult for me to accomplish what I am trying to achieve which is to make it the same both ways, but obviously I cannot call var am to be the value of #exchange in my #return function because the field would be blank at that time which would calculate it at NAN so what can I do to make it to where all of my calculations are the same both ways, I have been trying for the better part of 5 hours to figure out what to do, but I am lost, a point in the right direction would be greatly appreciated.
This looks like a simple problem with your algebra to me. I see what you are trying to do. As it stands, you assume return = exchange - tot - cost and exchange = return + tot + cost. The problem is that you have assumed var tot is the same in your solution working forward and your solution working in reverse.
However, tot is equal to (fee/100) * exchange working forward and (fee/100) * return working backward, which breaks your assumptions for how to calculate exchange and return. My first step would be to move away from the var am assignment and naming, which seems to be confusing you, and call each exchange and return what they really are. This might help you form a correct algebraic solution, which you can then implement in JavaScript.
JSFiddle: https://jsfiddle.net/z6hrLbmc/
You are using wrong formula.
Use brutto=netto/(1-fee/100) instead of brutto=netto*(1+fee/100)
You have to distinguish whether the fee is applied to netto (+netto*fee/100) or to brutto (-brutto*fee/100).

Finding average from input array with Javascript - not calculating correctly

I am trying to calculate the average of 3 values (each numbered from 1-10) that are selected by the user and then pass the results to an text input (for display as a graph).
It should be updating the new average every time one of the values is changed, but the averaging is not working correctly at all. I think that the loop is not resetting the values every time it runs- it's adding up the sum each time it runs, but not sure how to fix it.
Here is my code:
var sliders = $("#health1,#health2,#health3");
var elmt = [];
$(sliders).each(function () {
elmt.push($(this).attr('value'));
$("#health1,#health2,#health3").change(function () {
var sum = 0;
averageRisk();
});
});
function averageRisk() {
var sum = 0;
for (var i = 0; i < elmt.length; i++) {
sum += parseInt(elmt[i], 10);
}
var avg = sum / elmt.length;
document.getElementById('healthLevel').value = +avg;
elmt.push($(sliders).attr('value'));
$('#healthLevel').val(avg).trigger('change');
console.log("Sum: " + sum);
console.log("Average: " + avg);
}
Here is an example:
http://jsfiddle.net/pixelmix/783cfmnv/
Not sure but seems like a lot of extra work going. Main issue was you were building array of initial values and not getting the values each time they changed. That first .each got all the slider values and added them to elmt and continued to push new values on to after every change instead of just getting the current values every time. Did you want to accumulate all values over time?
Fiddle: http://jsfiddle.net/AtheistP3ace/783cfmnv/6/
$("#health1,#health2,#health3").on('change', function () {
averageRisk();
});
function averageRisk() {
var sum = 0;
var elmt = $("#health1,#health2,#health3");
for (var i = 0; i < elmt.length; i++) {
sum += parseInt(elmt[i].value, 10); //don't forget to add the base
}
var avg = sum / elmt.length;
document.getElementById('healthLevel').value = +avg;
$('#healthLevel').val(avg).trigger('change');
console.log("Sum: " + sum);
console.log("Average: " + avg);
}
And as pointed out if you want to ignore updating things when the sum is NaN you can do this:
function averageRisk() {
var sum = 0;
var elmt = $("#health1,#health2,#health3");
for (var i = 0; i < elmt.length; i++) {
sum += parseInt(elmt[i].value, 10); //don't forget to add the base
}
if (isNaN(sum)) {
return false;
}
var avg = sum / elmt.length;
document.getElementById('healthLevel').value = +avg;
$('#healthLevel').val(avg).trigger('change');
console.log("Sum: " + sum);
console.log("Average: " + avg);
}
The problem is that you fill the elmt array at page loading.
When user changes the values, you do not refresh the elmt array. So the array used to compute the average is always the same, empty.
You have to recover the input values each time they are modified.
function averageRisk() {
var sum = 0;
// Re make the loop for getting all inputs values
$(sliders).each(function() {
var value = parseInt($(this).val(), 10);
sum += value;
});
var avg = sum/$(sliders).length;
$('#healthLevel').val(avg);
}
Working example : http://jsfiddle.net/783cfmnv/7/
PS : You can use the css class healthInput to select your inputs. If you add later other fields, you will not have to add the new input id to your jQuery selector.
I did this work, check it .
http://jsfiddle.net/783cfmnv/10/
$("#health1,#health2,#health3").change(function() {
var val1 = +slider1.val();
var val2 = +slider2.val();
var val3 = +slider3.val();
var avg = (val1 + val2 + val3) /3;
$("#healthLevel").val(avg);
});

Can not adding up numbers in a column with angular

Im trying to get the sum of a column ("price") with angular with this code, but only have the value.
Example:
Price: 5,7,8,9
Total Price:05789
$scope.totalPrice = function(){
var total = 0;
for(count=0;count<$scope.names.length;count++){
var product = $scope.names[count];
total += (product.price);
}
return total;
};
It looks like the product.price is str, so each time you use +=, you are concatenating the string.
Try using parseFloat or parseInt
$scope.totalPrice = function(){
var total = 0;
for(count=0;count<$scope.names.length;count++){
var product = $scope.names[count];
total += parseFloat(product.price);
}
return total;
};
EDIT 1:: Double checking it, you declare var total = 0 and that is a Int, the += between a Int and a str should give a Int... weird stuff...
EDIT 2: Well, triple checking it... the first thing I said was ok :D 0 + "0" gives "00"

I am getting an unusual behavior with a Google script that calculates a time difference

The following is my spreadsheet:
This is my spreadsheet script:
function onFormSubmit(e) {
//Retrieving the Timesheet Table sheet for reading and writing
var spreadsheet = SpreadsheetApp.openById('15U8dQIPeYkIiA6B4iHXRe3gEoGGRHy25Qv06jHAJ43_QA');
var Timesheet_Table = SpreadsheetApp.setActiveSheet(spreadsheet.getSheetByName('Timesheet Table'));
//Extract response dataSets from the current form submission
var timeStamp = e.values[0];
var formID = e.values[1];
var inOutChoiceResponse = e.values[2];
var tsParse = timeStamp.split(" ");
var tsDate = tsParse[0];
var tsTime = tsParse[1];
var lastRow = Timesheet_Table.getLastRow();
if (inOutChoiceResponse == "Check in") {
Timesheet_Table.getRange(lastRow, 1).setValue(ID);
Timesheet_Table.getRange(lastRow, 2).setValue(timeStamp);
Timesheet_Table.getRange(lastRow, 3).clearContent();
} else if (inOutChoiceResponse == "Check out") {
Timesheet_Table.deleteRow(lastRow);
var dataRange = Timesheet_Table.getDataRange();
var dataSet = dataRange.getValues();
for (var i = 1; i < dataSet.length; i++) {
var volunteerID = dataSet[i][0];
var sheetDate = dataSet[i][1].getMonth() + 1 + "/" + dataSet[i][1].getDate() + "/" + dataSet[i][1].getFullYear();
if (volunteerID == formID && sheetDate == tsDate) {
var rowToEdit = i + 1;
Timesheet_Table.getRange(rowToEdit, 3).setValue(timeStamp);
var diff = ((dataSet[i][2] - dataSet[i][1]) / (60 * 1000)) / 60;
var hoursWorked = precise_round(diff, 2);
Timesheet_Table.getRange(rowToEdit, 4).setValue(hoursWorked);
break;
}
}
}
};
function precise_round(num, decimals) {
var t = Math.pow(10, decimals);
return (Math.round(num * Math.pow(10, decimals)) / Math.pow(10, decimals)).toFixed(decimals);
};
The problem is that when ever I try to check out a volunteer for the first time through the volunteer check in/out form, it writes -396071.9625 into the Total Hours Worked column. But, if I check-out the same volunteer a second time, it returns the right positive number value into the Total Hours Worked column.
What could be the problem?
Thanks
The problem must lie here:
Timesheet_Table.getRange(rowToEdit, 3).setValue(timeStamp);
var diff = ((dataSet[i][2] - dataSet[i][1]) / (60 * 1000)) / 60;
After the value in the sheet is updated, the array dataSet still contains the values from before the update. In this case dataSet[i][2] contains an empty value. You have to make a call to the sheet again, or better, use the value stored in timeStamp in your calculations.

Categories