So I'm basically making an savings account system. A user can set up an account and start with a balance of 0 the withdraw and deposit money whenever they want. It works perfectly the first few times but then it gives me the RangeError either when I try logging in or out.
setScreen('LogIn');
var balance;
var curbal = [];
var totalAccts=[];
onEvent("saveAcct", "click", function() {
var username = getText('createUserInput');
var password = getText('createPassInput');
appendItem(totalAccts, getText('createUserInput') + " " +
getText('createPassInput') + " ");
console.log("Username: " + username + " Password: " + password);
console.log(totalAccts);
setScreen('LogIn');
});
onEvent('makeAcct', 'click', function(){
setScreen('CreateAcct');
setText('createUserInput', "");
setText('createPassInput', "");
setText("userInput", "");
setText("passInput", "");
hideElement('alert');
});
onEvent('addMoney', 'click', function(){
setNumber('balance', balance + getNumber('addInput'));
balance = balance + getNumber('addInput');
setNumber('addInput', '');
console.log(balance);
});
onEvent('subMoney', 'click', function(){
setNumber('balance', balance - getNumber('subInput'));
balance = balance - getNumber('subInput');
setNumber('subInput', '');
console.log(balance);
});
onEvent('login', 'click', function(){
balance = 0;
changeEnBal(totalAccts, curbal);
});
onEvent('logout', 'click', function(){
changeExBal(totalAccts, getNumber('balance'), curbal);
hideElement('alert');
setText('balance', 0);
setText("userInput", "");
setText("passInput", "");
setScreen('LogIn');
});
onEvent("goBack", "click", function() {
setScreen('LogIn');
});
function changeEnBal(list, balList) {
var user = getText('userInput');
var pass = getText('passInput');
for (var i = 0; i < list.length; i++) {
if (list[i] === (user + " " + pass + " ")) {
setScreen('Account');
} else {
for (var a = 0; a < balList.length; a++) {
if (list[i] === (user + " " + pass + " " + balList[a])) {
balance = balList[a];
setNumber('balance', balList[a]);
setScreen('Account');
console.log(balList[a]);
}
}
}
}
for (var b = 0; b < balList.length; b++) {
if (balList[b] != (user + " " + pass + " " + balList[b])){
showElement('alert');
}
}
}
function changeExBal(list, curBal, balList) {
var user = getText('userInput');
var pass = getText('passInput');
for (var i = 0; i < list.length; i++) {
if (list[i] === (user + " " + pass + " ")) {
list[i] = user + " " + pass + " " + curBal;
appendItem(curbal, curBal);
console.log(curbal);
console.log(list[i]);
} else {
for (var a = 0; a < balList.length; a++) {
if (list[i] === (user + " " + pass + " " + balList[a])) {
balList[a] = curbal;
list[i] = user + " " + pass + " " + curBal;
}
}
}
}
console.log(totalAccts);
}
As suggested in some of the comments I would change your for loops to start with a zero index:
for (var i = 0; i < list.length; i++)
and
for (var a = 0; a < balList.length; a++)
Related
I'm using the following script to export Google Ads data from my account, but I am stuck with Google's pre-set date ranges and can't figure out how/if it's possible to jimmy these. Ideal date range would be year to date, with the report refreshing each day and adding on a fresh day's data, but would also be interested if we can get all time to work.
I'm a coding novice, so apologies in advance.
Script:
function main() {
var currentSetting = new Object();
currentSetting.ss = SPREADSHEET_URL;
// Read Settings Sheet
var settingsSheet = SpreadsheetApp.openByUrl(currentSetting.ss).getSheetByName(SETTINGS_SHEET_NAME);
var rows = settingsSheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var numSettingsRows = numRows - 1;
var sortString = "";
var filters = new Array();
for(var i = 0; i < numRows; i++) {
var row = values[i];
var settingName = row[0];
var settingOperator = row[1];
var settingValue = row[2];
var dataType = row[3];
debug(settingName + " " + settingOperator + " " + settingValue);
if(settingName.toLowerCase().indexOf("report type") != -1) {
var reportType = settingValue;
} else if(settingName.toLowerCase().indexOf("date range") != -1) {
var dateRange = settingValue;
} else if(settingName.toLowerCase().indexOf("sort order") != -1) {
var sortDirection = dataType || "DESC";
if(settingValue) var sortString = "ORDER BY " + settingValue + " " + sortDirection;
var sortColumnIndex = 1;
}else {
if(settingOperator && settingValue) {
if(dataType.toLowerCase().indexOf("long") != -1 || dataType.toLowerCase().indexOf("double") != -1 || dataType.toLowerCase().indexOf("money") != -1 || dataType.toLowerCase().indexOf("integer") != -1) {
var filter = settingName + " " + settingOperator + " " + settingValue;
} else {
if(settingValue.indexOf("'") != -1) {
var filter = settingName + " " + settingOperator + ' "' + settingValue + '"';
} else if(settingValue.indexOf("'") != -1) {
var filter = settingName + " " + settingOperator + " '" + settingValue + "'";
} else {
var filter = settingName + " " + settingOperator + " '" + settingValue + "'";
}
}
debug("filter: " + filter)
filters.push(filter);
}
}
}
// Process the report sheet and fill in the data
var reportSheet = SpreadsheetApp.openByUrl(currentSetting.ss).getSheetByName(REPORT_SHEET_NAME);
var rows = reportSheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var numSettingsRows = numRows - 1;
// Read Header Row and match names to settings
var headerNames = new Array();
var row = values[0];
for(var i = 0; i < numCols; i++) {
var value = row[i];
headerNames.push(value);
//debug(value);
}
if(reportType.toLowerCase().indexOf("performance") != -1) {
var dateString = ' DURING ' + dateRange;
} else {
var dateString = "";
}
if(filters.length) {
var query = 'SELECT ' + headerNames.join(",") + ' FROM ' + reportType + ' WHERE ' + filters.join(" AND ") + dateString + " " + sortString;
} else {
var query = 'SELECT ' + headerNames.join(",") + ' FROM ' + reportType + dateString + " " + sortString;
}
debug(query);
var report = AdWordsApp.report(query);
try {
report.exportToSheet(reportSheet);
var subject = "Your " + reportType + " for " + dateRange + " for " + AdWordsApp.currentAccount().getName() + " is ready";
var body = currentSetting.ss + "<br>You can now add this data to <a href='https://www.optmyzr.com'>Optmyzr</a> or another reporting system.";
MailApp.sendEmail(EMAIL_ADDRESSES, subject, body);
Logger.log("Your report is ready at " + currentSetting.ss);
Logger.log("You can include this in your scheduled Optmyzr reports or another reporting tool.");
} catch (e) {
debug("error: " + e);
}
}
function debug(text) {
if(DEBUG) Logger.log(text);
}
I've tried overwriting the data validation in the host spreadsheet, but think I need to amend the script itself also.
function displayEvent(array) {
var vOutput = "";
var ind = 0;
for(var i = 0; i < array.length; i++) {
ind += 1;
vOutput += "Name " + ind + ": " + array[i].name + ", Age " + array[i].age + "<br />";
}
document.getElementById("output").innerHTML = vOutput;
}
function init() {
var arrEvent = [];
var objEvent = {};
objEvent.name = prompt("Enter name of Event");
objEvent.age = prompt("Enter number of Guests");
arrEvent.push(objEvent);
while(objEvent.name.length > 0) {
objEvent.name = prompt("Enter name of Event");
objEvent.age = prompt("Enter number of Guests");
if(objEvent.name.length > 0) {
arrEvent.push(objEvent);
}
}
displayEvent(arrEvent);
}
window.onload = init;
Trying to print an object array into the HTML paragraph id and whenever I execute the code above I get the correct output but the array elements just show as blank.
You are always pushing the same object into your array.
Change to:
function displayEvent(array) {
var vOutput = "";
var ind = 0;
for(var i = 0; i < array.length; i++) {
ind += 1;
vOutput += "Name " + ind + ": " + array[i].name + ", Age " + array[i].age + "<br />";
}
document.getElementById("output").innerHTML = vOutput;
}
function init() {
var arrEvent = [];
var name = '';
var age = '';
name = prompt("Enter name of Event");
age = prompt("Enter number of Guests");
arrEvent.push({name: name, age: age});
while(name.length > 0) {
name = prompt("Enter name of Event");
age = prompt("Enter number of Guests");
if(name.length > 0) {
arrEvent.push({name: name, age: age});
}
}
displayEvent(arrEvent);
}
window.onload = init;
Can this be better? More simple?
My Steps:
Created a Google Doc Sheet -spread sheet
Exported as json
Build this ajax js script to make available to leaflet. js app.
https://jsfiddle.net/lukedohner/by80bvL7/
There maybe a more succinct way.
xhr.onload = function() {
console.log("onload + function");
if (xhr.status === 200) {
//sucessfull load of json
alert("Here is the data in a alert window " + xhr.responseText);
var respText = xhr.responseText;
xhrText = JSON.parse(respText); // convert it to an object
console.log(
"json data: xhrText.length >>>>>>>> " +
Object.keys(xhrText.mysheet).length
);
console.log(
"Object.keys(xhrText) >>>>>>>> " + Object.keys(xhrText)
);
var i = -1;
for (var mykey in xhrText.mysheet) {
//In case you want to check to see it there is a null value -property
if (xhrText.mysheet.hasOwnProperty(mykey)) {
i++;
window["card" + i] = mykey + " -> " + xhrText[mykey];
}
}
} else {
// not sucessfull load of json
alert("Request failed. Returned status of " + xhr.status);
}
createhooks();
};
};
var ch = {}; // create a var namespace
createhooks = function() {
var mysheetlenght = Object.keys(xhrText.mysheet).length;
for (var j = 0; j < mysheetlenght; j++) {
//console.log(" xhrText.title >>>>>>>> " + j + " " + xhrText.mysheet[j].title);
ch["title" + j] = xhrText.mysheet[j].title;
ch["subtitle" + j] = xhrText.mysheet[j].subtitle;
ch["copy" + j] = xhrText.mysheet[j].copy;
ch["imagename" + j] = xhrText.mysheet[j].imagename;
console.log("title" + j + " is " + ch["title" + j]);
console.log("subtitle" + j + " is " + ch["subtitle" + j]);
console.log("copy" + j + " is " + ch["copy" + j]);
console.log("imagename" + j + " is " + ch["imagename" + j]);
console.log("~~~~~ " + "~~~~~ ");
//create vars for addLElement function - Display it is the DOM
titleindex = "ch.title" + j;
addElement("Title " + j, ch["title" + j]);
subtitleindex = ["ch.subtitle" + j];
addElement("Subtitle " + j, ch["subtitle" + j]);
copyindex = ["ch.copy" + j];
addElement("Copy " + j, ch["copy" + j]);
imagenameindex = ["ch.imagename" + j];
addElement("Image Name " + j, ch["imagename" + j]);
addElement("~~~~~ ", "~~~~~");
}
ch_callback();
};
function ch_callback() { // Use ch.title1, ch.title1, ch.title1, ch.title1, ch.title1... in your add addElement function or in the Leaflet.js L.control.window method
console.log("callback " + ch.copy1);
}
Now I can use the var like this ch.copy1 in the leaflet L.control.window method. Not shown in fiddle example.
To preface this, we are a small organization and this system was built by someone long ago. I am a total novice at javascript so I have trouble doing complicated things, but I will do my best to understand your answers. But unfortunately redoing everything from scratch is not really an option at this point.
We have a system of collecting data where clients use a login to verify a member ID, which the system then uses to pull records from an MS Access database to .ASP/html forms so clients can update their data. One of these pages has the following function that runs on form submit to check that data in fields a/b/c sum to the same total as d/e/f/g/h/i. It does this separately for each column displayed (each column is a record in the database, each a/b/c/d/e/f is a field in the record.)
The problem is with this section of the function:
for (var j=0; j<recCnt; j++) {
sumByType = milesSurf[j] + milesElev[j] + milesUnder[j];
sumByTrack = milesSingle[j] + milesDouble[j] + milesTriple[j] + milesQuad[j] + milesPent[j] + milesSex[j];
etc.
It should use javascript FOR to loop through each record and test to see if they sum to the same thing.
In Firefox and IE this is working properly; the fields sum properly into "sumByType" and "sumByTrack". You can see below I added a little alert to figure out what was going wrong:
alert(sumByType + " " + j + " " + recCnt + " " + milesSurf[j] + " " + milesElev[j] + " " + milesUnder[j]);
In Chrome, that alert tells me that the components of "sumByType" and "sumByTrack" (the various "milesXXXXX" variables) are undefined.
My question is: Why in Chrome is this not working properly, when in IE and FFox it is? Any ideas?
Full function code below:
function submitCheck(formy, recCnt) {
//2/10/03: added milesQuad
//---------------checks Q#4 that Line Mileage by type is the same as by track
var milesElev = new Array();
var milesSurf = new Array();
var milesUnder = new Array();
var milesSingle = new Array();
var milesDouble = new Array();
var milesTriple = new Array();
var milesQuad = new Array();
var milesPent = new Array();
var milesSex = new Array();
var sumByType = 0;
var milesLineTrack = new Array(); //this is for Q5 to compare it to mileage by trackage
var j = 0; var sumByTrack = 0; var liney; var yrOp;
//var str = "document.frm.milesElev" + j;
//alert(str.value);
for (var i in document.frm) {
if (i.substring(0, i.length - 1) == "milesElev") {
milesElev[parseInt(i.substring(i.length-1, i.length))] = parseFloat(document.frm[i].value); }
if (i.substring(0, i.length - 1) == "milesSurf") {
milesSurf[parseInt(i.substring(i.length-1, i.length))] = parseFloat(document.frm[i].value); }
if (i.substring(0, i.length - 1) == "milesUnder") {
milesUnder[parseInt(i.substring(i.length-1, i.length))] = parseFloat(document.frm[i].value); }
if (i.substring(0, i.length - 1) == "milesSingle") {
milesSingle[parseInt(i.substring(i.length-1, i.length))] = parseFloat(document.frm[i].value); }
if (i.substring(0, i.length - 1) == "milesDouble") {
milesDouble[parseInt(i.substring(i.length-1, i.length))] = parseFloat(document.frm[i].value); }
if (i.substring(0, i.length - 1) == "milesTriple") {
milesTriple[parseInt(i.substring(i.length-1, i.length))] = parseFloat(document.frm[i].value); }
if (i.substring(0, i.length - 1) == "milesQuad") {
milesQuad[parseInt(i.substring(i.length-1, i.length))] = parseFloat(document.frm[i].value); }
if (i.substring(0, i.length - 1) == "milesPent") {
milesPent[parseInt(i.substring(i.length-1, i.length))] = parseFloat(document.frm[i].value); }
if (i.substring(0, i.length - 1) == "milesSex") {
milesSex[parseInt(i.substring(i.length-1, i.length))] = parseFloat(document.frm[i].value); }
if (i.substring(0, i.length -1) == "milesLineTrack") {
milesLineTrack[parseInt(i.substring(i.length-1, i.length))] = document.frm[i].value; } //12/13/02 used to be parseFloat(document.frm[i].value)
if (i.substring(0,5)=="Lines") {
liney = document.frm[i].value;
if (parseInt(liney)<1 || isNaN(liney)) {
alert("Each mode must have at least 1 line. Please correct the value in question #2.");
document.frm[i].select(); return false; }}
if (i.substring(0,8)=="yearOpen") {
yrOp = document.frm[i].value;
if (parseInt(yrOp)<1825 || isNaN(yrOp)) {
alert("Please enter a year after 1825 for question #3");
document.frm[i].select(); return false; }
}
}
for (var j=0; j<recCnt; j++) {
sumByType = milesSurf[j] + milesElev[j] + milesUnder[j];
sumByTrack = milesSingle[j] + milesDouble[j] + milesTriple[j] + milesQuad[j] + milesPent[j] + milesSex[j];
//---------------to round sumByTrack and sumByType from a long decimal to a single decimal place, like frm 7.89999998 to 7.9.
sumByTrack = sumByTrack * 10;
if (sumByTrack != parseInt(sumByTrack)) {
if (sumByTrack - parseInt(sumByTrack) >= .5) {
//round up
sumByTrack = parseInt(sumByTrack) + 1; }
else { //truncate
sumByTrack = parseInt(sumByTrack); }}
sumByTrack = sumByTrack / 10;
sumByType = sumByType * 10;
if (sumByType != parseInt(sumByType)) {
if (sumByType - parseInt(sumByType) >= .5) {
//round up
sumByType = parseInt(sumByType) + 1; }
else { //truncate
sumByType = parseInt(sumByType); }}
sumByType = sumByType / 10;
//-------------end of rounding ---------------------------
if (sumByType != sumByTrack) {
if (isNaN(sumByType)) {
sumByType = "(sum of 4.a., b., and c.) "; }
else {
sumByType = "of " + sumByType; }
if (isNaN(sumByTrack)) {
sumByTrack = "(sum of 4.d., e., f., g., h., and i.) "; }
else {
sumByTrack = "of " + sumByTrack; }
alert("For #4, the 'End-to-End Mileage By Type' " + sumByType + " must equal the 'End-to-end Mileage By Trackage' " + sumByTrack + ".");
alert(sumByType + " " + j + " " + recCnt + " " + milesSurf[j] + " " + milesElev[j] + " " + milesUnder[j]);
return false;
}
//alert (milesLineTrack[j] + " " + milesSingle[j] + " " + 2*milesDouble[j] + " " + 3*milesTriple[j] + " " + 4*milesQuad[j] + " " + 5*milesPent[j] + " " + 6*milesSex[j]);
var singDoubTrip = (milesSingle[j] + 2*milesDouble[j] + 3*milesTriple[j] + 4*milesQuad[j] + 5*milesPent[j] + 6*milesSex[j])
//----------round singDoubTrip to one digit after the decimal point (like from 6.000000001 to 6.0)
singDoubTrip = singDoubTrip * 10;
if (singDoubTrip != parseInt(singDoubTrip)) {
if (singDoubTrip - parseInt(singDoubTrip) >= .5) {
//round up
singDoubTrip = parseInt(singDoubTrip) + 1; }
else { //truncate
singDoubTrip = parseInt(singDoubTrip); }}
singDoubTrip = singDoubTrip / 10;
//----------end round singDoubTrip-----------------------------------------
if (parseFloat(milesLineTrack[j]) != singDoubTrip) {
//var mlt = milesLineTrack[j];
//if isNaN(milesLineTrack[j]) { mlt =
alert("For column #" + (j+1) + ", the mainline passenger track mileage of " + milesLineTrack[j] + " must equal the single track plus 2 times the double track plus 3 times the triple track plus 4 times the quadruple track plus 5 times the quintuple track plus 6 times the sextuple track, which is " + singDoubTrip + ".");
return false;
}
}
//---------------------end of checking Q#4----------------
//return false;
}
I think for (var i in document.frm) is the problem. You should not enumerate a form element, there will be plenty of unexpected properties - see Why is using "for...in" with array iteration a bad idea?, which is especially true for array-like objects. I can't believe this works properly in FF :-)
Use this:
var ele = document.frm.elements; // or even better document.getElementById("frm")
for (var i=0; i<ele.length; i++) {
// use ele[i] to access the element,
// and ele[i].name instead of i where you need the name
}
Also, you should favour a loop over those gazillion of if-statements.
Below is my code. The problem is that recordsOut[0] is always undefined, whatever I try.
I know it has to do with the callback result. I tried to add some delays to give it more time to give a result back, but that did not help.
Any idea (with example please)? Very much appreciated.
function getAddress(id, searchValue) {
geo.getLocations(searchValue, function(result) {
if (result.Status.code == G_GEO_SUCCESS) {
var recordsOutStr = id + ';' + searchValue + ';';
for (var j = 0; j < result.Placemark.length; j++)
recordsOutStr += result.Placemark[j].address + ';' + result.Placemark[j].Point.coordinates[0] + ';' + result.Placemark[j].Point.coordinates[1];
recordsOut.push(recordsOutStr);
alert(recordsOutStr);
}
else {
var reason = "Code " + result.Status.code;
if (reasons[result.Status.code])
reason = reasons[result.Status.code]
alert('Could not find "' + searchValue + '" ' + reason);
}
});
}
function delay(ms)
{
var date = new Date();
var curDate = null;
do
{
curDate = new Date();
}
while (curDate - date < ms);
}
function processData()
{
objDataIn = document.getElementById("dataIn");
objDataOut = document.getElementById("dataOut");
if (objDataIn != null)
{
//alert(objDataIn.value);
if (objDataOut != null) {
recordsIn = explode(objDataIn.value, ';', true);
//for (i = 0; i < recordsIn.length; i++)
for (i = 0; i <= 5; i++)
{
addressStr = recordsIn[i]['address'] + ', ' +
recordsIn[i]['postalcode'] + ' ' +
recordsIn[i]['city'] + ', ' +
recordsIn[i]['country'];
getAddress(recordsIn[i]['id'], addressStr); //This will set resultStr
delay(200);
}
delay(5000);
alert('***' + recordsOut[0] + '***');
alert('***' + recordsOut[1] + '***');
alert('***' + recordsOut[2] + '***');
alert('***' + recordsOut[3] + '***');
alert('***' + recordsOut[4] + '***');
}
}
document.frmGeoCoder.submit();
}
Make sure that you have already defined recordsOut like this:
var recordsOut = [];
If you do it like this - var recordsOut; - it will be undefined.
If that doesn't work for you, please post the rest of the code, so we can see exactly what's going on.