JavaScript and Array's - javascript

EDIT I originally posted this with my version of the J.S but it's so far off no one can even help so i'm starting over. Here is the pseudocode i have done that needs to be translated into a Javascript program. Any help is appreciated!
I am a beginning programmer i understand this code will have multiple errors, that's why i am here. Array's and loops have given me much trouble while trying to learn them and especially with formatting them in JavaScript. The things i know are incorrect or still need i commented out i still need them, i also know i'm not passing anything i just can't seem to wrap my head around how to get them there. I'm also not sure if while gather input i'm using alter and prompt correctly. In the display function the spacing is necessary for when it will be displayed. Corrections and explanations are greatly appreciated.
Module main()
//Declare local variables
Declare endProgram = “no”
While endProgram == “no”
Declare Real notGreenCost[12]
Declare Real goneGreenCost[12]
Declare Real savings[12]
Declare String months[12] = “January”, “February”, “March”, “April”, “May”, “June”, “July”, “August”, “September”, “October”, “November”, “December”
//function calls
getNotGreen(notGreenCost, months)
getGoneGreen(goneGreenCost, months)
energySaved(notGreenCost, goneGreenCosts, savings)
displayInfo(notGreenCost, goneGreenCosts, savings, months)
Display “Do you want to end the program? Yes or no”
Input endProgram
End While
End Module
Module getNotGreen(Real notGreenCost[], String months[])
Set counter = 0
While counter < 12
Display “Enter NOT GREEN energy costs for”, months[counter]
Input notGreenCosts[counter]
Set counter = counter + 1
End While
End Module
Module getGoneGreen(Real goneGreenCost[], String months[])
Set counter = 0
While counter < 12
Display “Enter GONE GREEN energy costs for”, months[counter]
Input goneGreenCosts[counter]
Set counter = counter + 1
End While
End Module
Module energySaved(Real notGreenCost[], Real goneGreenCost[], Real savings[])
Set counter = 0
While counter < 12
Set savings[counter] = notGreenCost[counter] – goneGreenCost[counter]
Set counter = counter + 1
End While
End Module
Module displayInfo(Real notGreenCost[], Real goneGreenCost[], Real savings[], String months[])
Set counter = 0
While counter < 12
Display “Information for”, months[counter]
Display “Savings $”, savings[counter]
Display “Not Green Costs $”, notGreenCost[counter]
Display “Gone Green Costs $”, goneGreenCost[counter]
End While
End Module

A few notes:
Currently the program creates a few variables and functions that
don't seem to interact
Most of the edits below are not optimal - there are parts that
could be done by much simpler means (i.e. counter++) - But thats
for you to learn =P
I made quite a few assumptions of what you wanted the program to
do, they might be wrong, they might be right
var notGreenCost = []; //Array lengths don't need to be specified
var goneGreenCost = [];
var savings = [];
var months = ["January", "Feburary", "March", "April", "May", "June"];
//A boolean value (true | false) would suit this better as opposed to "yes"/ "no"
var endProgram = false;
var option = 0;
/* You dont need main functions in javascript
* migrated everything to be global :/
* Delete:
function main(){
// Move this (made it global): var endProgram = "no";
}
*/
// I don't think this is meant to be initMonths..
// Maybe something like getOptions?
function /*initMonths*/getOptions(){
while (endProgram == false){ //lowercase while
//Because prompt would block everything else until it gets input
//we probably want to move the prompt to be after the alerts
alert("options:"); //Clarity
alert("1 to enter data");
alert("2 to display data");
alert("3 to write data to a file");
alert("4 to read data from a file");
//Alter global "option" to take the value of the prompt
option = prompt("What would you like to do? Type:");
//} //I assume you want the rest of the code in this while loop - otherwise it will loop forever
// Delete this bracket (its unmatched): {
// Delete return statement as it will stop the function return option;
// Delete this bracket (its unmatched): }
//Create a variable to take the value of prompt (this should be outside the while loop) but it seem clearer for explanation purposes to be here
var toEnd;
toEnd = prompt("Do you want to end the program (enter yes or no)");
// Javascript uses != for "not equal to" and && for "AND"
while (toEnd != "no" && toEnd != "yes") {
toEnd = prompt("Please enter a value of yes or no");
}
//I think you want to assign the value of toEnd to endProgram
// Note the the below is not the only/best way to do it
if(toEnd == "no") {
endProgram = false;
} else if(toEnd == "yes") {
endProgram = true;
}
// While use brackets not End s
// End While
// End While
}//End while loop here
}
Javascript in a browser cannot alter files - writeToFile, readFromFile have all been removed
I believe you want months to be global, if it is then initMonths is unnecessary
getNotGreen:
function getNotGreen(){
//You don't need to specify types in Javascript
/*Integer*/ var counter = 0
while (counter < 6){ //lowercase while
//I'm assuming you want to combine the values of "Enter NOT GREEN energy costs for" and months[counter] - This is done by using the + sign
//Im also assuming you want to read the value into notGreenCost
//.push adds a value to a array
notGreenCost.push(prompt("Enter NOT GREEN energy costs for" + months[counter]))
//Returning here makes the rest of the function redundant
//}
//return notGreenCost[counter];
//}
//Javascript does not use Set
// Note that below is not the only/best way to do it
/*Set*/ counter = counter + 1
} //End the while loop here
}
getGoneGreen:
function getGoneGreen(){
//Counter should probably be local (not global) - use var
var counter = 0;
while (counter < 6){//lowercase while
//I'm assuming you want to combine the values of "Enter NOT GREEN energy costs for" and months[counter] - This is done by using the + sign
//Im also assuming you want to read the value into notGreenCost
//.push adds a value to a array
goneGreenCost.push(prompt("Enter GONE GREEN energy costs for" + months[counter]));
//See above (getNotGreen)
//}
//return goneGreenCost[counter];
/*Set*/ counter = counter + 1;
}//End while loop here
}
energySaved:
function energySaved(){
//Counter should probably be local (not global) - use var
var counter = 0;
while (counter < 6){//lowercase while
savings[counter] = notGreenCost[counter] - goneGreenCost[counter]
counter = counter + 1;
}
} //I assume you want to end energySaved here?
displayInfo:
function displayInfo(){
//Alert produced individual boxes, i assume you want the following in a single window?
// "\n" is a line break
alert("SAVINGS NOT GREEN GONE GREEN MONTH\n"+
"_________________________________________________\n");
//Counter should probably be local (not global) - use var
var counter = 0;
while (counter < 6){//lowercase while
alert( "$" + savings[counter] + "$" + notGreenCost[counter] + "$" + goneGreenCost[counter] + "" + months[counter]);
counter = counter + 1;
}
} //I assume you want to end displayInfo here?

Related

counter variable is holding 2 values on 2nd pass of the function

I'm making a typing game. When multiple players play the game it runs through the same set of functions again. I'm using the variable j as a counter to advance words when they are typed correctly. For some reason, on the second pass on each upkeystroke, it logs j = 1 & j = whatever the value of the previous players last word + 1 is. When each player plays, I want each set of words they are typing to be the same, so that it is fair. I can't figure out why this is happening or even how the variable has 2 values at the same time?!?!?
What gives?
Here's the code in question, but there's a bunch of callbacks that could be involved, although the only place this variable is called is inside this function.
//advances ship on correct typing
function runRace() {
timer();
var j = 1;
//BUG HERE !! Works fine on first iteration but on second
//iterations value jumps beteween 1 and whatever the next
//one is. It's like on every keystroke it reassigns var j
//back to 1, then back to the element number it was on
//last time
//!!! j has 2 values !!!it's keeping the value from the
//prior running of run race
$(document).keyup(function(e){
var targetWord = $(".toType").text();
var typedWord = $("#word").val();
//while (j < gameWords.length){
console.log("j = " + j);
if(typedWord === targetWord){
$(".player").css({left: "+=15px",});
targetWord = $(".toType").text(gameWords[j]);
$("#word").val("");
j++;
}else {
return
};
//}
});
}
If you need to see the rest of the code to figure this out, it's here. Eventhough it's not running right on jsfiddle for reason, it works other then the bug, locally https://jsfiddle.net/ujsr139r/1/
As i mentioned in my comment you're creating multiple listeners everytime runRace() is called.
You could try something like this instead (please note, this isn't the best way to do this, i'm just demoing. Global variables like j in this case aren't a clever idea.:
var j=1; // global because its outside of your function
$(function(){
$(document).keyup(function(e){
var targetWord = $(".toType").text();
var typedWord = $("#word").val();
//while (j < gameWords.length){
console.log("j = " + j);
if(typedWord === targetWord){
$(".player").css({left: "+=15px",});
targetWord = $(".toType").text(gameWords[j]);
$("#word").val("");
j++;
}else {
return
};
//}
});
});
//advances ship on correct typing
function runRace() {
j = 1;
timer();
}

Not All Check Boxes are Being Selected

When I check the boxes in the HTML file, it doesn't account for more than one being checked. How to I make it add the total of every box that is clicked, not just one?
for (i = 0; i < g_radSize.length; i++) {
if (g_chkExtras[i].checked === true) {
g_sExtras += g_chkExtras[i].value + ", ";
g_fTotal += gc_fExtrasPrice;
}
}
Full Code
// DO NOT DELETE ANYTHING IN THIS FILE
/*jsl:option explicit*/
/*jsl:declare $*//*jsl:declare addEventListener*//*jsl:declare isDigits*//*jsl:declare alert*//*jsl:declare blur*//*jsl:declare clearInterval*//*jsl:declare clearTimeout*//*jsl:declare close*//*jsl:declare closed*//*jsl:declare confirm*//*jsl:declare console*//*jsl:declare Debug*//*jsl:declare defaultStatus*//*jsl:declare document*//*jsl:declare event*//*jsl:declare focus*//*jsl:declare frames*//*jsl:declare getComputedStyle*//*jsl:declare history*//*jsl:declare Image*//*jsl:declare length*//*jsl:declare location*//*jsl:declare moveBy*//*jsl:declare moveTo*//*jsl:declare navigator*//*jsl:declare open*//*jsl:declare opener*//*jsl:declare opera*//*jsl:declare Option*//*jsl:declare parent*//*jsl:declare Number*//*jsl:declare parseInt*//*jsl:declare print*//*jsl:declare prompt*//*jsl:declare resizeBy*//*jsl:declare resizeTo*//*jsl:declare screen*//*jsl:declare scroll*//*jsl:declare scrollBy*//*jsl:declare scrollTo*//*jsl:declare setInterval*//*jsl:declare setTimeout*//*jsl:declare status*//*jsl:declare top*//*jsl:declare window*//*jsl:declare XMLHttpRequest*/
// Constants (Constants are variables that never change throughout the running of your program. They are almost always declared globally.)
var gc_fSandwichPrice = 5.99; // Price for each sandwich (Version 1 and 2 only)
var gc_fExtrasPrice = 1.50; // Price for each extra item
// GLOBAL VARS
// Global object vars
var g_divErrors;
var g_radSandwich;
var g_radSize;
var g_chkExtras;
// Other global vars
var g_fTotal;
var g_sSandwich;
var g_sSize;
var g_sExtras;
// DO IT: Hook up an event handler for window.onload to the Init function.
window.onload = Init;
function Init() {
// DO IT: Change the version number in the line below, if necessary, so it accurately reflects this particular version of Dirty Deli.
document.getElementById("h1Title").innerHTML = "Dirty Deli 1.0";
// DO IT: grab and assign any html objects you need to work with
g_divErrors = document.getElementById("divErrors");
g_radSandwich = document.getElementsByName("radSandwich");
g_radSize = document.getElementsByName("radSize");
g_chkExtras = document.getElementsByName("chkExtras");
// DO IT: Set the innerHTML of spanExtrasPrice to gc_fExtrasPrice. Tip: Use the .toFixed() method to display it with 2 decimal places
document.getElementById("spanExtrasPrice").innerHTML = gc_fExtrasPrice.toFixed(2);
// DO IT: Hook up any event handlers you need
document.getElementById("btnCalculateTotal").onclick = CalculateTotal;
document.getElementById("btnProcessOrder").onclick = ProcessOrder;
// Version 2
// DO IT: You need to hook up an event handler that runs whenever the user selects a different Payment option.
//This is the "onchange" event. I suggest you use an anonymous function, and make use of the *selectedIndex* property to see if they chose the credit card.
//This function will check to see if the user selected the Credit card option. If they did, set the CSS visibility property to "visible", otherwise set it to "hidden".
document.getElementById("selPayment").onchange =
function() {
var divCreditCardInfo = document.getElementById ("divCreditCardInfo");
if (document.getElementById("selPayment").selectedIndex === 2) {
divCreditCardInfo.style.visibility = "visible";
}
else {
divCreditCardInfo.style.visibility = "hidden";
}
};
} // function Init()
// function Init
function CalculateTotal() {
// this function should be called when the user clicks the Calculate Total button. Its purpose is mainly to, well, calculate the total. Remember to hook up an appropriate event handler so this function will be called when they click.
// DO IT: clear out divErrors (set the innerHTML to an empty string)
g_divErrors.innerHTML = "";
// DO IT: Tip: you're going to be adding to g_fTotal. Remember: adding anything to garbage will always give you garbage. So how do you prevent this error?
// Same deal for g_sExtras.
g_fTotal = 0;
g_sExtras = " ";
/* DO IT:
Sandwich code - Version 1
Using an IF statement, see which radio button they checked, and assign the value of the selected sandwich to a global var name g_sSandwich.
If nothing is selected, set divErrors to "Select a sandwich", and exit the function.
Sandwich code - Version 2
Within each IF statement remove the line of code you wrote for Version 1.
Replace it with a call to a function (that you will write) named GetSandwichName().
When you call this function, pass it one parameter - the index of the radSandwich radio button that the user checked.
More info on the function itself is given below.
*/
/* if (g_radSandwich[0].checked === true) {
GetSandwichName(0);
}
else if (g_radSandwich[1].checked === true) {
GetSandwichName(1);
}
else if (g_radSandwich[2].checked === true) {
GetSandwichName(2);
}
else if (g_radSandwich[3].checked === true) {
GetSandwichName(3);
}
else {
g_divErrors.innerHTML = "Select a sandwich";
return;
}
*/
// Version 3
/* CONVERT: Sandwich code
Using a FOR loop and a single IF statement within the loop, see which radio button they checked.
When you find it, set g_sSandwich to the sandwich name
and break out of the loop using the break command.
If nothing is selected, set divErrors to "Select a sandwich", and exit the function.
But how do you know if nothing was selected? Use a boolean variable in the If statement,
then check its value after you get out of the loop.
Remember: Your code should be flexible enough so that if the number
of sandwiches change, your code can still work.
Afterall, that's one of the reasons we're using a loop.
Do NOT call the GetSandwichName() function. Incorporate its code here, and remove it.
*/
var iChecked = false;
var i;
for (i = 0; i < g_radSandwich.length; i++) {
if (g_radSandwich[i].checked) {
iChecked = true;
g_sSandwich = g_radSandwich[i].value;
break;
}
}
if (iChecked === false) {
g_divErrors.innerHTML = "Select a sandwich";
return;
}
// Version 1
/* DO IT:
This is the Size code.
Make sure they selected a size.
Update the total by adding the price of a sandwich (which is already declared as a constant) to the total
If nothing is selected, set divErrors to "Please choose a size", and exit the function.
Tip: An If Statement is the key here.
*/
// Version 2
/*
In this version, the sandwiches are not all the same price.
The price of each sandwich is contained within the title attribute of the radSandwich radio button for that sandwich
(take a look at the html to verify this).
So, modify the IF statement from Version 1. You need to call a function (that you will write) named GetSizeUpdateTotal(). More on that below.
*/
/*
if (g_radSize[0].checked === true) {
GetSizeUpdateTotal(0);
}
else if (g_radSize[1].checked === true) {
GetSizeUpdateTotal(1);
}
else if (g_radSize[2].checked === true) {
GetSizeUpdateTotal(2);
}
else {
g_divErrors.innerHTML = "Please choose a size";
return;
}
*/
// Version 3
/* CONVERT: Size code
Once again, using a FOR loop and a single IF statement within the loop,
see which radio button they checked, get the price and update the total just like you did previously.
Then break out of the loop using the break command.
If nothing is selected, set divErrors to "Please choose a size", and exit the function.
Do NOT call the GetSizeUpdateTotal() function. Incorporate its code here, and remove it.
*/
iChecked = false;
var price;
for (i = 0; i < g_radSize.length; i++) {
if (g_radSize[i].checked) {
iChecked = true;
price = g_radSize[i].title;
price = price.substr(1);
price += Number(price);
g_sSize = g_radSize[i].value;
g_fTotal += price;
break;
}
}
if (iChecked === false) {
g_divErrors.innerHTML = "Please choose a size";
return;
}
/* DO IT:
"Extras" code - Version 1
Using an IF statement, see which extra(s) they checked. For each extra selected, do the following:
Concatenate the value of the selected extra to a global var name g_sExtras.
Update the Total with the price of the Extra.
"Extras" code - Version 2
Remove each IF statement you wrote for Version 1. Replace it with a call to a function (that you will write) named GetExtraUpdateTotal().
When you call this function, pass it one parameter - the index of the chkExtras checkbox that the user checked.
More info on the function itself is given below.
*/
/*
GetExtraUpdateTotal(0);
GetExtraUpdateTotal(1);
GetExtraUpdateTotal(2); */
// Version 3
/* CONVERT: "Extras" code
Again, using a FOR loop and a single IF statement within the loop, do what needs to be done.
Remember NOT to break out of the loop when you find a checked checkbox (there may be more).
Do NOT call the GetExtraUpdateTotal() function. Incorporate its code here, and remove it.
*/
for (i = 0; i < g_radSize.length; i++) {
if (g_chkExtras[i].checked === true) {
g_sExtras += g_chkExtras[i].value + ", ";
g_fTotal += gc_fExtrasPrice;
}
}
/* ****** That's it -- you're done with the loops. ******* */
// END Version 3
/* DO IT:
Optional fun: Remove the trailing comma on the last extra.
HINT: use the length property and the substr() method.
*/
// Version 1
// DO IT: Assign the total to the txtTotal textbox. Include a dollar sign and use .toFixed() to display 2 decimal places
document.getElementById("txtTotal").value = "$" + parseFloat(g_fTotal).toFixed(2); //Got help from stack overflow with the parseFloat than researched on w3schools on how to use it.
} // function CalculateTotal
// Version 2
/* DO IT:
Declare function GetSandwichName().
This function takes one parameter, named p_iSandwichIndex,
which is a radSandwich radio button index, i.e. the index of the Sandwich they selected.
It assigns the value of the selected sandwich to a global var name g_sSandwich.
*/
// END Version 2
// Version 2
/* DO IT:
Declare function GetSizeUpdateTotal().
This function takes one parameter, named p_iSizeIndex, which is a radSize radio button index,
i.e. the index of the radSize radio button that they selected.
The function should assign the *value* of the selected size to a global var name g_sSize.
Also, it must update the Total with the price for the size they selected.
The price is located in the title attribute of the radio button (take a look).
Remember that (using dot notation) you can access any object attribute you want, once you grab the object.
But the price in the title attribute contains a dollar sign,
and you want everything AFTER the dollar sign.
Use the substr() method to get the entire string, starting with the SECOND character in the string.
Look back on our class notes to see how we did this.
Use an alert to see that you got what you intended.
Then, convert that string to a number and add it to the Total.
TIP: Declare local vars as necessary.
*/
// Version 2
/* DO IT:
Declare function GetExtraUpdateTotal().
This function takes one parameter, named p_iExtraIndex, which is a chkExtras checkbox index, i.e. the index of an extra they selected.
Use an if statement to see if this particular checkbox is checked. If it is, then do the following:
Concatenate the value of the selected extra to a global var name g_sExtras.
Update the Total with the price of the Extra.
*/
function ProcessOrder() {
// This function should run when the ProcessOrder button is clicked.
// Version 2
// DO IT: declare any local vars you may need
var txtName = document.getElementById("txtName");
var txtMonth = document.getElementById("txtMonth");
var selPayment = document.getElementById("selPayment");
var selYear = document.getElementById("selYear");
var txtCreditCardNbr = document.getElementById("txtCreditCardNbr");
var month;
// Version 2
// DO IT: Before you do your error checking, does anything need to be initialized to an empty string? Now's the time to do it.
document.getElementById("divOrder").innerHTML = "";
g_divErrors.innerHTML = "";
// Version 2
// DO IT: If the name field is blank, display "Enter customer's name", set the focus and get out.
if (txtName.value === "") {
g_divErrors.innerHTML = "Enter customer's name";
txtName.focus();
return;
}
// Version 2
/* DO IT: Credit Card Code
Use an IF statement to determine if the user selected the credit card option in the selPayment dropdown
If they did, you need to do the following:
if the credit card number field was left blank or the contents of the field is not a number, display (in divErrors) the message shown in the working version, put focus on the card number field and get out.
if the month field was left blank or the contents of the field is not a number, display the message shown in the working version, put focus on the month field and get out.
if the month they entered is less than 1 or > 12, display the message shown in the working version, put focus on the month field and get out.
TIP: Remember to convert the txtMonth value to a number before you do your comparison.
if they neglected to select a year, display the message shown in the working version, put focus on the year field and get out.
*/
// END Version 2
// The following section I got assistance from another classmate.
if (selPayment.selectedIndex === 2) {
if ((txtCreditCardNbr.value === "") || (isDigits(txtCreditCardNbr.value) === false)) {
g_divErrors.innerHTML = "Enter your card number using only digits";
txtCreditCardNbr.focus();
return;
} else if ((txtMonth.value === "") || (isDigits(txtMonth.value) === false)) {
g_divErrors.innerHTML = "Enter month using only digits";
txtMonth.focus();
return;
} else {
month = Number(txtMonth.value);
if ((month < 1) || (month > 12)) {
g_divErrors.innerHTML = "Enter month between 1 and 12";
txtMonth.focus();
return;
}
}
if (selYear.selectedIndex === 0) {
g_divErrors.innerHTML = "Please select a year";
selYear.focus();
return;
}
}
// DO IT: Concatenate the appropriate msg into divOrder. The Welcome msg is within an h3 tag. Every other line is within a p tag. The last line is in bold.
/* Version 1:
Do not include the user's name in the welcome message.
Do not include the "Paid by" statement.
*/
/* Version 2:
Include the user's name in the welcome message.
Include the "Paid by" statement.
*/
document.getElementById("divOrder").innerHTML =
"<h3>Welcome to Dirty Deli!</h3>" + txtName.value + "<br>" +
"You have ordered a " + g_sSize + " " + g_sSandwich + " with " + g_sExtras + "<br>" +
"Your total is " + document.getElementById("txtTotal").value + "<br>" +
"Paid with " + selPayment.value + "<br>" + "<br>" +
"<strong>Have a nice day!</strong>";
} // function ProcessOrder
g_radSize is an array of (one or two )array. hence the loop is running for amount of elements g_radSize contain.
Normally, you should be using g_chkExtras.length instead of g_radSize.length.
for (i = 0; i < g_chkExtras.length; i++) {
if (g_chkExtras[i].checked === true) {
g_sExtras += g_chkExtras[i].value + ", ";
g_fTotal += gc_fExtrasPrice;
}
}

Nested If-else statements being skipped

What I'm building is a game where the computer generates a random number (1-100) and the user must guess the correct number. The goal is for the computer to compare the current guess to the previous guess and spit out a statement: "hot", "cold", "hotter", "colder", etc.
My Code (focus on the JS): CodePen fiddle
//global variables--computer generated guess, and guess log
var answer = Math.floor((Math.random() * 100)+1);
var guessArray = [];
var index = 0;
//user clicks submit button and guess is registered by computer
$("#submit").click( function(){
var guess = $("#guess").val();
guessArray.push(guess);
//prints out the answer and user guesses
$("#answer").text("Answer:" + " "+ answer);
$("#guessArrayPrint").text("You guessed: " + " " + guessArray + " ");
if (answer === guess) {
$("#statement").text("woo hoo right answer");
} else {
var currentDifference = Math.abs(answer-guess);
var currentDiffArray = [];
currentDiffArray.push(currentDifference);
if (index = 0) {
//if-else statement comparing current guess range to answer
if ( currentDifference >=1 && currentDifference <= 10){
$("#statement").text("Ouch! You're hot!");
} else {
$("#statement").text("Brr! You're cold!");
}
} else {
//if-else statement comparing current guess to previous guess
var previousDiff = answer- prevguess;
var prevguess = guessArray [i-1];
if( previousDiff < currentDifference){
$("#statement").text("Ahh! Getting Warmer!");
} else {
$("#statement").text("Brrr...getting colder");
}
}
index++
}
});
My nested if-else statements are not working. When a user inputs a guess, no matter how close to the answer, it always returns the statement "brr.. getting colder", which is in the "else" section.
Ideally when the user inputs their first guess if (index = 0) should run then when the second guess is input, it should move to the "else" statement with the previous guess variables. I tried moving around the variables, changed orders of if/else, and thought maybe it's the placement of index++. Nothing is working. Not sure if something is wrong with my variables , arrays, or the syntax of my if/else statements.
tl;dr: when the program is run only the "else" portion of the nested if-else statement is run. Not sure how to fix… I've gone through my code a number of times. The syntax, the arrays, and variables. Uncertain what's wrong.
You JS has if (index = 0). This should be if (index === 0).
Additionally, you need to cast the value of your input field to a number. You can do this using:
var guess = +$("#guess").val(); // + cast as a number
More syntax errors:
prevguess = guessArray[i - 1] --> prevguess = guessArray[index - 1];
Here is a partial working Fiddle. I ran through some scenarios, and the fiddle really only works if you give the application the right answer. The code has many syntax errors, bad refs and calculations. I would suggest opening the console or a debugger, identifying those issue, and fixing them.
Here is a Fully Functional Demo.

JavaScript using isNaN to validate returns NaN

I have some code here that will make validations of whether or not the input from a text box is NOT an empty string and isNaN. When i do these validations on amounts entered, i would like it to add them up.. however when a user does not enter anything in one or more amount fields the program should just add entered fields. But instead i get NaN showing in the total field.
link to full code: http://jsfiddle.net/KxNqQ/
var $ = function (id) {
return document.getElementById(id);
}
var calculateBills = function () {
var myErrorFlag = "N";
for (i = 1; i <= 4; i++) {
AmountNumber = 'amount' + i;
AmountValue = $(AmountNumber).value;
if (AmountValue != "" && isNaN(AmountValue)) {
$(AmountNumber).style.color = "red";
myErrorFlag = "Y";
} else {
$(AmountNumber).style.color = "black";
myErrorFlag = "N";
}
}
if (myErrorFlag != "Y") {
var Amount = 0;
for (i = 1; i <= 4; i++) {
Amount += parseInt($('amount' + i).value,10);
}
$('total').value = Amount;
}
}
var clearFields = function () {
for (i = 1; i <= 4; i++) {
itemName = 'item' + i;
$(itemName).value = "";
}
for (i = 1; i <= 4; i++) {
amountName = 'amount' + i;
$(amountName).value = "";
}
$('total').value = "";
}
window.onload = function () {
$("clearfields").onclick = clearFields;
$("addbills").onclick = calculateBills;
}
I think you've got your requirements a little bit confused, or at the very least I was confused by them. So in order to answer your question, I'm going to rephrase the requirements so I understand them better. This is a useful exercise that I try to do when I'm not 100% sure of the requirements; if I can't get the requirements right, what's to say I'll get the code right?
So the requirements – as I understand them – are:
Given each amount input
When the input has a value
And that value is a number
Then add the value to the total
And make the input color black
But if the input does not have a value
Or that value is not a number
Then make the input color red
Going through your code, I can see a number of problems with it. First, I noticed that both AmountNumber and AmountValue are global variables, because they were not declared local with the var keyword. So before fixing our code, let's change that. Let's also change the variable names to something that more accurately describe what they are, hopefully making the code easier to understand:
var input = $('amount' + i);
var value = input.value;
Now, note that I chose to store the element in the input variable. This is so we don't have to look it up multiple times within the loop. Looking things up in the DOM can be expensive so we'll want to keep it to a minimum. There are other was to look up elements as well, such as getElementsByClassName, querySelector and querySelectorAll; those are left as an exercise for the reader to research and evaluate.
Next, in each iteration of the loop, you check that AmountValue is not a string and simultaneously is not a number:
if (AmountValue != "" && isNaN(AmountValue)) {
This will be true so long as AmountValue is truthy (which is the case for non-empty strings) and so long as isNaN thinks it's a number (which is the case for strings that contain numbers.) It really is rather confusing; if I understand your code correctly this clause is there to check for invalid input and if it is true should mark the input field red and set a flag. I.e. this is the but clause in the aforementioned requirements.
Let's rewrite this to be the when clause instead, we'll take care of the but later. Before we do that, let's look at the myErrorFlag. It's used – I think – to see whether all input is well formed and in that case, add it all up. Well, validation and summation can be done in one fell swoop, so let's get rid of the flag and sum the values while validating them. So we replace myErrorFlag with a total variable:
var total = 0;
Now, let's get back to our clause. The requirements say:
When the input has a value
And that value is a number
Then add the value to the total
In code, that should look something like this:
if (value && !isNaN(value)) {
total += parseInt(value, 10);
input.style.color = 'black';
}
There are a couple of things going on here. For one, the if statement has been turned on its head a bit from what it was. It first checks to see that value is truthy, then that it is a number. The second check can be a bit tricky to read, because it is essentially a double negation; in english it reads "is not not a number", i.e. "is a number". I'll leave it as an exercise for the reader to figure out whether there's a more easily understood way of writing this check.
Now what about the but clause in our requirements?
But if the input does not have a value
Or that value is not a number
Then make the input color red
Well, it's essentially the inverse of our previous statement, so let's simply add an else clause:
else {
input.style.color = 'red';
}
Because the requirements doesn't mention the total variable in this clause, it is simply ignored and doesn't show up in the end result.
Adding it all up (no pun intended) the code – with comments – looks like this:
var calculateBills = function () {
var total = 0;
for (i = 1; i <= 4; i++) {
// Given each amount input
var input = $('amount' + i);
var value = input.value;
if (value && !isNaN(value)) {
// When the input has a value
// And that value is a number
// Then add the value to the total
total += parseInt(value, 10);
// And make the input color black
input.style.color = 'black';
} else {
// But if the input does not have a value
// Or that value is not a number
// Then make the input color red
input.style.color = 'red';
}
}
$('total').value = total;
};
There are more things that could be learned from this to make for better code. For instance, this code will break if the number of inputs change, or if their id names change. This is because they are selected specifically by their IDs and as such, if those change then this code will no longer function.
Another potential issue is that we're setting inline styles on the inputs as we loop over them. This means that in order to keep this code up to date with the styling of the site, it'll have to change. Generally, mixing styling and functionality like this is not a good idea and should be avoided. One way of doing so is to use class names instead, and toggle these on and off. Incidentally, this could also help the previous problem I mentioned.
There are other problems as well, but we'll leave those for another day. Hope this helps!
Try this
var calculateBills = function () {
var Amount = 0;
for (i = 1; i <= 4; i++) {
var AmountElement = $('amount' + i),
AmountValue = AmountElement.value;
if (AmountValue != "" && !isNaN(AmountValue)) {
AmountElement.style.color = "red";
Amount += parseInt(AmountValue,10);
} else {
AmountElement.style.color = "";
}
}
$('total').value = Amount;
};
Demo
Anyway, instead of using elements with id like id="amount1", id="amount2", id="amount3", etc., you could use classes (e.g class="amount") and get them with .getElementsByClassName

keep add the value without overwrite the function

function checkData() {
var temp = 0;
var totalMarks = countMark(temp);
if (totalMarks != 100)
window.alert("Marks must total 100");
}
function countMark(mark) {
var totalMark = 0;
totalMark += parseInt(mark)
return totalMark;
}
function doAdd() {
var taskid = document.getElementById("taskid").value;
var taskname = document.getElementById("taskname").value;
var taskmark = document.getElementById("taskmark").value;
if (taskid.length === 0)
window.alert("Task Id cannot be empty!");
if (taskname.length === 0)
window.alert("Task name cannot be empty!");
if (taskmark.length === 0)
window.alert("Task Mark cannot be empty!");
else if (!markpattern.test(taskmark))
window.alert("Invalid data in mark field");
var marks = parseInt(document.getElementById("taskmark"));
if (marks < 0 || marks > 100)
window.alert("Marks out of range. Please re-enter");
countMark(marks);
}
My question is when i keep call the doAdd() function. my marks will keep adding . want to do like passing reference like in C++ . my function countMark(...) will keep adding .
after that, when my form submitted, my form will call the function checkData()
If my totalmark is not 100 . will prompt out the alert and error.
but my code is not working . I guess that my countMark function wrong somewhere
If I understand you correctly, you're looking for the equivalent of a static variable - something that gets initialized the first time the function is called, and keeps it's value for subsequent calls.
Take a look at this related question: https://stackoverflow.com/a/1535650/2444111
The top answer (by CMS) is talking about class-based static variables, which are not quite the same thing.
The second answer (by Pascal MARTIN) is what you're looking for. It takes advantage of the fact that JS functions are also objects, and stores the variable as a property of the function object. This is a better solution than using a global variable (or a property of window, which is what a global actually is)
There are several issues in your code and it's really hard to say what your intention was. But I will address what I found.
In the following piece of code you are requesting a DOM Element and try to parse it as an Integer. The result of that type convertion is always NaN. Maybe wanted to get the value attribute of your element, like you did before. (Also, don't request the same element multiple times. Request it once, save the result in a variable and use that variable from that on).
var marks = parseInt(document.getElementById("taskmark"));
if (marks < 0 || marks > 100)
window.alert("Marks out of range. Please re-enter");
countMark(marks);
Your function countMark is pretty useless, because it will always return whatever Number you pass to it (see comments in your code).
function countMark(mark) {
var totalMark = 0; //create a new variable with value 0
totalMark += parseInt(mark) //add "mark" to that variable
return totalMark; //return that variable => 0 + mark = mark (and if mark = NaN => 0 + mark = NaN)
}
Maybe you wanted to make totalMark a global variable, than you would need to define it outside of your function:
var totalMark = 0;
function countMark(mark) {
totalMark += parseInt(mark);
return totalMark;
}
Last but not least, lets analyse your function checkData:
function checkData() {
var temp = 0; //create a local variable with value 0
var totalMarks = countMark(temp); //pass 0 to countMark => return 0 => totalMarks = 0
if (totalMarks != 100) //always true since totalMarks is always 0
window.alert("Marks must total 100"); //will always alert
}

Categories

Resources