I've an html page which has many dynamically created input boxes. The number of text boxes vary each time.
I want to calculate the sum of the numbers the user has entered, and disply it. When the user delete one number the sum should auto calculate.
How can i do it with javascript?
Thanks
In jQuery something like this should work with a few assumptions:
$('.toAdd').live('change', function() {
var total = 0;
$('.toAdd').each(function () {
total += $(this).val();
});
$('#total').val(total);
});
The assumptions being that your input fields all have the class 'toAdd' and that your final input field has an ID of 'total'.
In pure JS:
var elems = document.getElementsByClassName('toAdd');
var myLength = elems.length,
total = 0;
for (var i = 0; i < myLength; ++i) {
total += elems[i].value;
}
document.getElementById('total').value = total;
Let me elaborate when I review my notes but here is a high level answer that I believe will work... (My Java Script is very rusty)...
Make the input boxes share an attribute (or use tag) so you can get a collection to walk through no matter the size... Then on the onkeyup event on every input call this function that will sum the totals. Put the result into another entry with the ID you know beforehand...
You will have to validate input because if one of them is not a number then the total will also be "NAN"
Okay here is a complete working example you can build off of that I just threw together: It obviously needs a great deal of polishing on your end...
<html>
<head>
<script language="javascript">
function AddInputs()
{
var total = 0;
var coll = document.getElementsByTagName("input")
for ( var i = 0; i<coll.length; i++)
{
var ele = coll[i];
total += parseInt(ele.value);
}
var Display = document.getElementById("Display");
Display.innerHTML = total;
}
</script>
</head>
<body>
<input onkeyup="AddInputs()" />
<input onkeyup="AddInputs()" />
<input onkeyup="AddInputs()" />
<span id="Display"></span>
</body>
</html>
Related
Looking for a little guidance. I know its something small and dumb but I'm completely drawing a blank at this point and could use some help. I'm trying to create a mobile app for my class that needs a dynamic table for my results. I'm attempting to create a user input to select a number of "Random powerball tickets" and the table would give "Ticket 1 / Random Numbers." I have managed to create the random number generator onclick but cant for the life of me figure out the rest.
HTML- I dont remember how to connect the user input to the button and repeat x amount of times to match.
<div data-role="content">
<p>This will be a simple application that provide generated powerball numbers between 1-69.</p>
</div>
<div>
<button id="button" onClick="winningNumbers()" >Powerball Numbers</button>
</div>
<p id="outcome"></p>
<table id="data">
</table>
Current Javascript
var powerball;
function powerballNumbers(max) {
var ranNum = Math.floor((Math.random() * max) + 1);
return ranNum;
}
function main() {
powerball = [];
for (i = 0; i < 5; i++) {
powerball.push(powerballNumbers(69));
}
powerball.push(powerballNumbers(26));
}
function winningNumbers() {
main();
var totalTickets = document.getElementById("outcome");
totalTickets.innerText = powerball;
}
Thinking of something like this for the table but know it's not correct
function updateTable(ticketNumber, powerballNumber) {
var dataTable = document.getElementById("data");
dataTable.innerHTML = "";
// create rows of data based on given arrays
(Not sure what to put here)
// create header row
var thead = dataTable.createTHead();
var row = thead.insertRow(0);
var tableHeaders = ["Ticket", "Numbers"];
for (var i = 0; i < tableHeaders.length; i++) {
var headerCell = document.createElement("th");
headerCell.innerHTML = tableHeaders[i];
row.appendChild(headerCell);
}
}
I'm not entirely sure of what your end goal is, but the best I understand is you want to generate some tickets with an ID, and each ticket has 5 numbers? If so, I simply generated a ticket ID, and 5 numbers to go with that ticket. Then in the update table function, I've simplified it so it can focus on just appending new rows. If I've missed the mark please comment below and/or update your question.
Just some side comments.
Avoid using attributes for click events, it's unreliable at best.
Don't hestiate to use HTML when HTML is the answer. Your original update table method was going to build out a table? It only adds a headache, not ease.
Good job on leveraging the tools <table> gives us!
var powerball;
function powerballNumbers(max) {
var ranNum = Math.floor((Math.random() * max) + 1);
return ranNum;
}
function main() {
let i = 0
interval = setInterval(function() {
updateTable(powerballNumbers(9999), [powerballNumbers(69),
powerballNumbers(69),
powerballNumbers(69),
powerballNumbers(69),
powerballNumbers(69)
]);
i++;
if (i > 5) {
clearInterval(interval);
}
}, 500)
}
function winningNumbers() {
main();
var totalTickets = document.getElementById("outcome");
totalTickets.innerText = powerball;
}
function updateTable(ticket, powerballNumber) {
var dataTable = document.getElementById("data");
let newRow = dataTable.insertRow();
let ticketCell = newRow.insertCell();
ticketCell.textContent = ticket;
let numbers = newRow.insertCell();
numbers.textContent = powerballNumber.join(", ");
}
<div data-role="content">
<p>This will be a simple application that provide generated powerball numbers between 1-69.</p>
</div>
<div>
<button id="button" onClick="winningNumbers()">Powerball Numbers</button>
</div>
<p id="outcome"></p>
<table id="data" border=1>
<thead>
<tr>Ticket Number</tr>
<tr>Numbers</tr>
</thead>
</table>
I have this problem here
The problem has been solved, but my question is how can I get the second value from that, or the third one. The sheet will have many tables and at some point I will need a total for each table. Also, is there any solution to automatically find the the array number which contain date row for each table (instead defining this manually). Hope my explanation make sense.
Thank you!
Kind regards,
L.E. Test file
If I understood your question correctly, instead of breaking the loop when a match to "Total" is found do whatever is needed to be done within the loop like so...
var today = toDateFormat(new Date());
var todaysColumn =
values[5].map(toDateFormat).map(Number).indexOf(+today);
var emailDate = Utilities.formatDate(new Date(today),"GMT+1",
"dd/MM/yyyy");
for (var i=0; i<values.length; i++){
if (values[i][0]=='Total'){
nr = i;
Logger.log(nr);
var output = values[nr][todaysColumn];
// Do something with the output here I"m assuming you email it
}
}
The loop will keep going and find every "Total" and do the same thing. This answer assumes that the "Totals" are in the same column. You can get fancier with this if you only want certain tables to send and not others, but this should get you started.
I didn't quite understand the second part of your question...
"Also, is there any solution to automatically find the the array
number which contain date row for each table (instead defining this
manually). Hope my explanation make sense."
I'm guessing you want all the rows that contain "Total" in the specific column. You could instantiate a variable as an empty array like so, var totals = [];. Then instead of sending the email or whatever in the first loop you would push the row values to the array like so, totals.push(nr+1) . //adding 1 gives you the actual row number (rows count from 1 but arrays count from 0). You could then simply loop through the totals array and do whatever you wanted to do. Alternatively you could create an array of all the values instead of row numbers like totals.push(values[nr][todaysColumn]) and loop through that array. Lots of ways to solve this problem!
Ok based on our conversation below I've edited the "test" sheet and updated the code. Below are my edits
All edits have been made in your test sheet and verified working in Logger. Let me know if you have any questions.
Spreadsheet:
Added "Validation" Tab
Edited "Table" tab so the row with "Email Address" in Column A lines up with the desired lookup values (dates or categories)...this was only for the first two tables as all the others already had this criteria.
Code:
Create table/category selector...
In the editor go to File >> New >> HTMLfile
Name the file "inputHTML"
Copy and paste the following code into that file
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form class="notice_form" autocomplete="off" onsubmit="formSubmit(this)" target="hidden_iframe">
<select id="tables" onchange="hideunhideCatagory(this.value)" required></select>
<p></p>
<select id="categories" style="display:none"></select>
<hr/>
<button class="submit" type="submit">Get Total</button>
</form>
<script>
window.addEventListener('load', function() {
console.log('Page is loaded');
});
</script>
<script
src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
// The code in this function runs when the page is loaded.
$(function() {
var tableRunner = google.script.run.withSuccessHandler(buildTableList);
var catagoryRunner = google.script.run.withSuccessHandler(buildCatagoryList);
tableRunner.getTables();
catagoryRunner.getCategories();
});
function buildTableList(tables) {
var list = $('#tables');
list.empty();
list.append('<option></option>');
for (var i = 0; i < tables.length; i++) {
if(tables[i]==''){break;}
list.append('<option>' + tables[i] + '</option>');
}
}
function buildCatagoryList(categories) {
var list = $('#categories');
list.empty();
list.append('<option></option>');
for (var i = 0; i < categories.length; i++) {
if(categories[i]==''){break;}
list.append('<option>' + categories[i] + '</option>');
}
}
function hideunhideCatagory(tableValue){
var catElem = document.getElementById("categories");
if(tableValue == "Total Calls By Date" || tableValue == "Total Appointments by Date"){
catElem.style.display = "none"
document.required = false;
}else{
catElem.style.display = "block"
document.required = true;
}
}
function formSubmit(argTheFormElement) {
var table = $("select[id=tables]").val(),
catagory = $("select[id=categories]").val();
console.log(table)
google.script.run
.withSuccessHandler(google.script.host.close)
.getTotal(table,catagory);
}
</script>
</body>
<div id="hiframe" style="display:block; visibility:hidden; float:right">
<iframe name="hidden_iframe" height="0px" width="0px" ></iframe>
</div>
</html>
Edits to Code.gs file
Replace code in Code.gs with this...
//This is a simple trigger that creates the menu item in your sheet
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Run Scripts Manually')
.addItem('Get Total','fncOpenMyDialog')
.addToUi();
}
//This function launches the dialog and is launched by the menu item
function fncOpenMyDialog() {
//Open a dialog
var htmlDlg = HtmlService.createHtmlOutputFromFile('inputHTML')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(200)
.setHeight(150);
SpreadsheetApp.getUi()
.showModalDialog(htmlDlg, 'Select table to get total for');
};
//main function called by clicking "Get Total" on the dialogue...variables are passed to this function from the formSubmit in the inputHTML javascript
function getTotal(table,catagory) {
function toDateFormat(date) {
try {return date.setHours(0,0,0,0);}
catch(e) {return;}
}
//get all values
var values = SpreadsheetApp
.openById("10pB0jDPG8HYolECQ3eg1lrOFjXQ6JRFwQ-llvdE2yuM")
.getSheetByName("Tables")
.getDataRange()
.getValues();
//declare/instantiate your variables
var tableHeaderRow, totalRow, tableFound = false;
//begin loop through column A in Tables Sheet
for (var i = 0; i<values.length; i++){
//test to see if values have already been found if so break the loop
if(tableFound == true){break;}
//check to see if value matches selected table
if (values[i][0]==table){
//start another loop immediately after the match row
for(var x=i+1; x<values.length; x++){
if(values[x][0] == "Email Address"){ //This header needs to consistantly denote the row that contains the headers
tableHeaderRow = x;
tableFound = true;
}else if(values[x][0] == "Total"){
totalRow = x;
break;
}
}
}
}
Logger.log("Header Row = "+tableHeaderRow)
Logger.log("Total Row = "+ totalRow)
var today = toDateFormat(new Date())
var columnToTotal;
if(catagory==''){
columnToTotal = values[tableHeaderRow].map(toDateFormat).map(Number).indexOf(+today);
}else{
columnToTotal = values[tableHeaderRow].indexOf(catagory);
}
var output = values[totalRow][columnToTotal];
Logger.log(output);
var emailDate = Utilities.formatDate(new Date(today),"GMT+1", "dd/MM/yyyy");
//here is where you would put your code to do something with the output
}
/** The functions below are used by the form to populate the selects **/
function getTables(){
var cFile = SpreadsheetApp.getActive();
var cSheet = cFile.getSheetByName('Validation');
var cSheetHeader = cSheet.getRange(1,1,cSheet.getLastRow(),cSheet.getLastColumn()).getValues().shift();
var tabelCol = (cSheetHeader.indexOf("Tables")+1);
var tables = cSheet.getRange(2,tabelCol,cSheet.getLastRow(),1).getValues();
return tables.filter(function (elem){
return elem != "";
});
}
function getCatagories(){
var cFile = SpreadsheetApp.getActive();
var cSheet = cFile.getSheetByName('Validation');
var cSheetHeader = cSheet.getRange(1,1,cSheet.getLastRow(),cSheet.getLastColumn()).getValues().shift();
var catagoriesCol = (cSheetHeader.indexOf("Catagory")+1);
var catagories = cSheet.getRange(2,catagoriesCol,cSheet.getLastRow(),1).getValues();
return catagories.filter(function (elem){
return elem != "";
});
}
I am having trouble with my onchange not working and storing numbers in an array via a text box.
What I want the code to do is to get statistics on the numbers inputted into the text box. I do this by having the user input numbers into the text box and hit the Enter key to display those numbers. The numbers should be put into an array before being put into a list to display the inputted numbers. However, I keep getting this error where the onchange is not triggering when hitting the Enter key or clicking off of the text box.
Here is an image of the error I am getting when inspecting the code
With the numbers stored in the array, I want to try to get the Mean of the numbers. But, I keep getting the error "NaN" which makes me think that my numbers are not getting stored into the array properly.
Here is the code:
<html>
<head>
<title>Stats</title>
</head>
<p>Array is called numbers. numbers.sort();</p>
<div id="stats">
<input type ="text" id="value" onchange="list()"> <!-- Getting the Onchange Error here -->
<button id="button1" onclick = "list()">Enter</button>
<ul id="list1">
</ul>
<button id="stat_button" onclick="calculateMean()">Get Statistics</button>
<p id="mean">Mean= </p>
</div>
<script>
function list() {
var liElement = document.createElement("li"); //Creating new list element//
var ulElement = document.getElementById("list1"); //Get the ulElement//
var input = document.getElementById("value").value; //Get the text from the text box//
var numbers = []; //create Array called numbers
numbers.push(input);//adds new items to the array
//for loop//
for(var i=0; i < numbers.length; i++) {
liElement.innerHTML = numbers[0]; //Puts the array into the list for display//
ulElement.appendChild(liElement); //add new li element to ul element//
}
}
function calculateMean() {
var meanTotal = 0;
var meanAverage = 0;
var meanArray = [];
for (var i = 0; i < meanArray.length; i++) {
meanTotal += meanArray[i];
}
meanAverage = (meanTotal / meanArray.length);
document.getElementById("mean").innerHTML = meanAverage;
}
</script>
Try adding it through addEventListener instead of inline like that:
document.getElementById('value').addEventListener('change', function(e){
list()
})
The reason the Mean is always NaN is because your mean array is always an empty array when you start with. I think you were referring to a numbers array here.
You will have to declare the array outside the scope of the 2 functions, since it is the common to both.
And it is always a better idea to decouple Javascript and HTML. Bind your events in JS instead of inline event handlers.
Note: When you read the value from the input, it is a string, so convert it to a number before storing it in the numbers array.
HTML
<p>Array is called numbers. numbers.sort();</p>
<div id="stats">
<input type="text" id="value">
<!-- Getting the Onchange Error here -->
<button id="button1">Enter</button>
<ul id="list1">
</ul>
<button id="stat_button">Get Statistics</button>
<p id="mean">Mean= </p>
</div>
JS
document.getElementById('value').addEventListener('change', list);
document.getElementById('button1').addEventListener('click', list);
document.getElementById('stat_button').addEventListener('click', calculateMean);
var numbers = [];
function list() {
var liElement = document.createElement("li"); //Creating new list element//
var ulElement = document.getElementById("list1"); //Get the ulElement//
var input = document.getElementById("value").value; //Get the text from the text box//
numbers.push(input); //adds new items to the array
//for loop//
for (var i = 0; i < numbers.length; i++) {
liElement.innerHTML = numbers[0]; //Puts the array into the list for display//
ulElement.appendChild(liElement); //add new li element to ul element//
}
}
function calculateMean() {
var meanTotal = 0;
var meanAverage = 0;
for (var i = 0; i < numbers.length; i++) {
meanTotal += numbers[i];
}
meanAverage = (meanTotal / numbers.length);
document.getElementById("mean").innerHTML = meanAverage;
}
jsFiddle
I have a subscription form where user selects service and number of hours. Onsubmit I call a function which displays the result/total price. The function looks like this:
<script type="text/javascript">
function calc()
{
var total = 0;
var course = 0;
var nrOfLessons = 0;
var vat = 0;
course = Number(document.getElementById("course").value)
nrOfLessons = Number(document.getElementById("nrOfLessons").value)
total =(course * nrOfLessons)
vat = total * 0.15
total = total+ vat;
document.getElementById("result").innerHTML = "The total is "+total+" Click here to Pay
}
</script>
Now my question is this. How can I change the text from above "click here to pay" into a link. I tried everything that I can think off but I am stumped.
Thanxs in advance for all the help. Please try to keep answers newbie friendly :-)
You can turn that into a link by using:
document.getElementById("result").innerHTML =
"The total is "+total+" <a href='[url-here]'>Click here to Pay</a>";
Replace [url-here] with the URL of your payment page.
I have a div structure like below
<div id=main">
<input type="hidden" id="people_0_1_0" value="12"/>
<input type="hidden" id="people_0_1_1" value="12"/>
</div>
Now how to add all hidden input values in a variable. Thanks
Using Jquery's map function
var myArray = $('#main input').map(function(){
return $(this).val();
}).get();
It will collect all input's values(12 and 12 in this case) to array variable.
See jsfiddle http://jsfiddle.net/GkXUS/1/
If you want to get sum of values you can do the following
var total = 0;
$.each(myArray,function() {
total += parseInt(this,10);
});
var total = 0;
$('#main input[id^="people_"]').each(function(){
total += parseInt(this.value, 10);
});
Note that I am using attribute starts with selector to find all the input elements whose id starts with people_.
total will give you the total of all the input elements value.
I guess you want this:
var hidden_value = new Array();
var hiddens = document.getElementById( "main" ).childNodes;
for( i = 0 ; i < hiddens.length ; i++ ){
hidden_value.push( hiddens[ i ].value );
}
You could try something like this:
var peopleData = $("#main input[type=hidden]").serializeArray();
Putting values in a variable does not make sense. You can insert the values in a Array and perform your required operation
Using Plain Javascript
var els=document.getElementById('main').childNodes;
var allVal=[];
for(i=0; i<els.length-1; i++)
{
if(els[i].nodeType != 3 && els[i].type=="hidden") allVal.push(els[i].value);
}
console.log(allVal); // the array
console.log(allVal[0]); // first value
An example is here.