Alternative to message.content.startWith - javascript

I'm working with a discord bot and I'm doing a help command with pages.
I have this set up:
if(message.content.startWith(`${prefix}help`))
and
if(message.content.startWith(`${prefix}help 2`))
If i do >help 2 I get both. Is there any way to stop that from happening?

When using startsWith(">help") (not startWith) it will match ">help 2" because that string does indeed start with ">help". If you want to match these cases more precisely you should put the most specific cases first and use else if for subsequent comparisons.
if (message.content.startsWith(`${prefix}help 2`)) { /* do 2 */ }
else if (message.content.startsWith(`${prefix}help 3`)) { /* do 3 */ }
else if (message.content.startsWith(`${prefix}help 4`)) { /* do 4 */ }
else if (message.content.startsWith(`${prefix}help`)) { /* do other */ }
else if (message.content.startsWith(`${prefix}faq`)) { /* do faq */ }
The code above will only match the second case if the first didn't match.
Further explanation:
When comparing partial strings you need to be careful that you're matching the correct thing. Look at this example:
let names = [ "Roberta", "Robert" ]
// case #1 - fails (wrong order)
names.forEach(name => {
let salutation;
if (name.startsWith("Robert"))
salutation = "Mr.";
else if (name.startsWith("Roberta"))
salutation = "Miss";
console.log("1) "+salutation+" "+name);
})
// case #2 - fails (missing else)
names.forEach(name => {
let salutation;
if (name.startsWith("Roberta"))
salutation = "Miss";
if (name.startsWith("Robert"))
salutation = "Mr.";
console.log("2) "+salutation+" "+name);
})
// case #3 - works
names.forEach(name => {
let salutation;
if (name.startsWith("Roberta"))
salutation = "Miss";
else if (name.startsWith("Robert"))
salutation = "Mr.";
console.log("3) "+salutation+" "+name);
})
Case #1 fails because both names match on the first if-statement because both names actually do start with "Robert". But we didn't want it to match "Roberta" because we have a second check for that start of the string. However the code never went into the second if-statement because it already matched on the first one. By reversing the order of checking and putting the check for "Roberta" first we get the right behaviour because it's more specific ('Robert' doesn't start with 'Roberta' but 'Roberta' does start with 'Robert'). So the important part is to order your if-statements to match with the most specific before the more general values.
Case #2 fails because even if the first if-statement matches, the second one can also match. We want to use else if to make sure that if something earlier in the code has already matched that we don't keep checking other cases.

A better way to do this would be to check the page number for your help command:
if(msg.startsWith(prefix)){
let args = msg.slice(1).split(" ");
let command = args.shift(); //shift removes the first element of the array and returns it
if(command === 'help'){
let helpPage = args[0] || "1"; //take the page from the msg if supplied, otherwise default to page 1;
if(helpPage === "1"){ /* send page 1 */ }
else if(helpPage === "2"){ /* send page 2 */ }
// and so on
}
}

Related

check if string does not contain values

I am using indexOf to see if an email contains anything other than a particular text.
For example, I want to check if an email DOES NOT include "usa" after the # symbol, and display an error message.
I was first splitting the text and removing everything before the # symbol:
var validateemailaddress = regcriteria.email.split('#').pop();
Then, I check if the text doesn't include "usa":
if(validateemailaddress.indexOf('usa')){
$('#emailError').show();
}
Something with the above check doesn't seem right. It works - I can enter an email, and if it does not include 'usa', then the error message will show.
Regardless, when I add an additional check, like if the email does not include "can", then the error message shows no matter what.
As follows:
if(validateemailaddress.indexOf('usa') || validateemailaddress.indexOf('can')){
$('#emailError').show();
}
As stated, using the above, the error message will show regardless if the email includes the text or not.
All I want to do is check if the email includes 'usa' or 'can', and if it doesn't, then show the error message.
How can I make this work?
Here is a simple JavaScript function to check if an email address contains 'usa' or 'can'.
function emailValid(email, words) {
// Get the position of # [indexOfAt = 3]
let indexOfAt = email.indexOf('#');
// Get the string after # [strAfterAt = domain.usa]
let strAfterAt = email.substring(indexOfAt + 1);
for (let index in words) {
// Check if the string contains one of the words from words array
if (strAfterAt.includes(words[index])) {
return true;
}
}
// If the email does not contain any word of the words array
// it is an invalid email
return false;
}
let words = ['usa', 'can'];
if (!emailValid('abc#domain.usa', words)) {
console.log("Invalid Email!");
// Here you can show the error message
} else {
console.log("Valid Email!");
}
You can do something like that, using includes:
const validateEmailAdress = (email) => {
const splittedEmail = email.split('#').pop();
return (splittedEmail.includes('usa') || splittedEmail.includes('can'))
}
console.log("Includes usa: ", validateEmailAdress("something#gmail.usa"))
console.log("Includes can: ", validateEmailAdress("something#gmail.can"))
console.log("Does not includes: ", validateEmailAdress("something#gmail.com"))
There are several ways to check, if a string contains/does not contain a substring.
String.prototype.includes
'String'.includes(searchString); // returns true/false
String.prototype.indexOf
// returns values from -1 to last postion of string.
'String'.indexOf(searchString);
// In combination with ~ this can work similar to includes()
// for strings up to 2^31-1 byte length
// returns 0 if string is not found and -pos if found.
~'String'.indexOf(searchString);
With the help of Regular Expressions:
// substring must be escaped to return valid results
new RegExp(escapedSearchString).test('String'); // returns true/false if the search string is found
'String'.match(escapedSearchString); // returns null or an array if found
So overall you can use allmost all methods like:
if ('String'.function(searchString)) {
// 'String' includes search String
} else {
// 'String' does not include search String
}
Or in case of indexOf:
if ('String'.indexOf(searchString) > -1) {
// 'String' includes search String
} else {
// 'String' does not include search String
}
// OR
if (~'String'.indexOf(searchString)) {
// 'String' includes search String
} else {
// 'String' does not include search String
}
I believe this regular expression match is what you're looking for
System.out.println(myString.matches("(.)#(.)usa(.*)"));

adding regex int to a var

I'm trying to make a irc bot that takes input like this user: +1 I want to have a end result where I can have a main number being added to, from the # someone types with +#.
expected output: #x added: 1 rep: 1 executed[+] second execution
#x added: 1 rep: 2 executed[+]
actual output #x added: +1 rep: +1undefined executed[+] second is identical.
I've tried using Number(commandName), along with toString().replace(/\D\s/g,'') I got some promising results but they seemed to have some problems so I scrapped that code...
so in conclusion how can I add the numbers together and avoid the +?
const tmi = require('tmi.js');
// Define configuration options
const opts = {
identity: {
username: "x",
password: "x"
},
channels: [
"#x"
]
};
// Create a client with our options
const client = new tmi.client(opts);
// Register our event handlers (defined below)
client.on('message', onMessageHandler);
client.on('connected', onConnectedHandler);
// Connect to Twitch:
client.connect();
const totalnum = 0;
// Called every time a message comes in
function onMessageHandler(target, context, msg, self) {
if (self) {
return;
} // Ignore messages from the bot
// Remove whitespace from chat message
let commandName = msg.trim();
var regexadd = /([+]\d*)[^+\s]/;
// If the command is known, let's execute it
if (regexadd.exec(commandName)) {
var totalnum = addem(commandName, totalnum);
console.log(target, `added:`, commandName, `rep:`, totalnum, `executed[+]`)
} else {
console.log(`* Unknown command ${commandName}`);
}
function addem(x, y) {
return (x + y);
}
}
// Called every time the bot connects to Twitch chat
function onConnectedHandler(addr, port) {
console.log(`* Connected to ${addr}:${port}`);
}
I found a few things that appear to be wrong with your code:
You're not adding numbers. addem()'s first parameter is the name of the command, it should be the number captured in your regex capture group.
Your regex includes the + sign in the capture group, you probably wanted to exclude it
You should parse the result of exec to a hint either with ParseInt() or implicitly with +
You use RegExp.prototype.exec() instead of RegExp.prototype.match() to retrieve a capture group.
Here's what this could look like
var regexadd = /\+(\d*)[^+\s]/;
if (regexadd.exec(commandName)) {
var totalnum = addem(+commandName.match(regexadd)[1], totalnum);
console.log(target, `added:`, commandName, `rep:`, totalnum, `executed[+]`)
}
I also think it would be best to use RegExp.prototype.test() instead of RegExp.prototype.exec() for your if statement - you will limit results to true or false.

Javascript Math.log() help wanted

World!
I'm trying to create a program in Javascript that takes the log of a number typed into an HTML input. Unfortunately i've encountered a problem where it wont accept the string with the .replace().
Its Function:
I.E: When log(10) is calculated, the function should first remove the first 4 char's "log(" next remove the last parenthesis ")" and then take the log of the no. between.
HTML includes style elements, button and input form and an output < DIV >.
//Function
function calculate()
{
var inputString = document.getElementById("inpstr");
var output = document.getElementById("output");
//TESTING CODE
/*
if (inputString.value.startsWith("log(").endsWith(")"))
{
console.log(output.innerHTML = inputString.value.substring(4, 20).replace(")", ""));
}
else
{
output.innerHTML = "false";
}
*/
//Math.log() calc *****DOESNT WORK*****
if (inputString.value.startsWith("log(").endsWith(")"))
{
output.innerHTML = Math.log(inputString.value.replace(")", "").substring(4, 20));
}
else
{
output.innerHTML = inputString.value;
}
event.preventDefault();
}
If someone can give me an effective solution that would be much appreciated.
Thanks,
Syntax
Since Math.log() accepts only number values and you're trying to pass a string to it, you should first parse this value into a float number and then pass it to the log function:
let val = parseFloat(inputString.value.replace(")", "").substring(4, 20));
output.innerHTML = Math.log(val);
I'm guessing I got downvoted for being lazy, so here is the quick info. Gonras got it right relating to what you want to extract, but he forgot to check that what's being input is actually a log.
That's where the regex below comes in handy! I'm matching the field to:
^ start of word, since we want to match the entire field.
log(
([-.\d])) any consecutive sequence () of numbers (\d), -, and '.', represented by the []. The \(...\) makes sure to save this inner part for later.
$ is end of word, see 1.
res will be null if there is no match. Otherwise, res[0] is the entire match (so the entire input field) and res[1] is the first 'capture group', at point 3 - which is presumably the number.
This of course fails for multiple "-" inside, or "." etc... so think it over.
//Function
function calculate()
{
var inputString = document.getElementById("inpstr");
var output = document.getElementById("output");
var res = /^log\(([-.\d]*)\)$/.exec(inputString.value);
if (res)
output.innerHTML = Math.log(res[1]);
else
output.innerHTML = res;
}
document.getElementById("output").innerHTML='start';
calculate()
<div id='output'></div>
<input id='inpstr' value='log(2.71828)'></input>
If I wanted to fix your if to supplement Gonras's solution:
if (inputString.value.startsWith("log(") && inputString.value.endsWith(")"))
Yours fails since startsWith() returns a boolean, which obviously doesn't have a endsWith function.

Unable to Get Output From While Loop in Javascript

I'm working on my final project of the Winter 2017 quarter to demonstrate how to use Regular Expressions in both C# and JavaScript code behind pages. I've got the C# version of my demonstration program done, but the JavaScript version is making me pull what little hair I have left on my head out (no small achievement since I got a fresh buzz cut this morning!). The problem involves not getting any output after applying a Regular Expression in a While loop to get each instance of the expression and printing it out.
On my HTML page I have an input textarea, seven radio buttons, an output textarea, and two buttons underneath (one button is to move the output text to the input area to perform multiple iterations of applying expressions, and the other button to clear all textareas for starting from scratch). Each radio button links to a function that applies a regular expression to the text in the input area. Five of my seven functions work; the sixth is the one I can't figure out, and the seventh is essentially the same but with a slightly different RegEx pattern, so if I fix the sixth function, the seventh function will be a snap.
(I tried to insert/upload a JPG of the front end, but the photo upload doesn't seem to be working. Hopefully you get the drift of what I've set up.)
Here are my problem children from my JS code behind:
// RegEx_Demo_JS.js - code behind for RegEx_Demo_JS
var inputString; // Global variable for the input from the input text box.
var pattern; // Global variable for the regular expression.
var result; // Global variable for the result of applying the regular expression to the user input.
// Initializes a new instance of the StringBuilder class
// and appends the given value if supplied
function StringBuilder()
{
var strings = [];
this.append = function (string)
{
string = verify(string);
if (string.length > 0) strings[strings.length] = string;
}
this.appendLine = function (string)
{
string = verify(string);
if (this.isEmpty())
{
if (string.length > 0) strings[strings.length] = string;
else return;
}
else strings[strings.length] = string.length > 0 ? "\r\n" + string : "\r\n";
}
this.clear = function () { strings = []; };
this.isEmpty = function () { return strings.length == 0; };
this.toString = function () { return strings.join(""); };
var verify = function (string)
{
if (!defined(string)) return "";
if (getType(string) != getType(new String())) return String(string);
return string;
}
var defined = function (el)
{
// Changed per Ryan O'Hara's comment:
return el != null && typeof(el) != "undefined";
}
var getType = function (instance)
{
if (!defined(instance.constructor)) throw Error("Unexpected object type");
var type = String(instance.constructor).match(/function\s+(\w+)/);
return defined(type) ? type[1] : "undefined";
}
}
Within the code of the second radio button (which will be the seventh and last function to complete), I tested the ScriptBuilder with data in a local variable, and it ran successfully and produced output into the output textarea. But I get no output from this next function that invokes a While loop:
function RegEx_Match_TheOnly_AllInstances()
{
inputString = document.getElementById("txtUserInput").value;
pattern = /(\s+the\s+)/ig; // Using an Flag (/i) to select either lowercase or uppercase version. Finds first occurrence either as a standalone word or inside a word.
//result = pattern.exec(inputString); // Finds the first index location
var arrResult; // Array for the results of the search.
var sb = getStringBuilder(); // Variable to hold iterations of the result and the text
while ((arrResult = pattern.exec(inputString)) !==null)
{
sb.appendLine = "Match: " + arrResult[0] ;
}
document.getElementById("txtRegExOutput").value = sb.toString();
/* Original code from C# version:
// string pattern = #"\s+(?i)the\s+"; // Same as above, but using Option construct for case insensitive search.
string pattern = #"(^|\s+)(?i)the(\W|\s+)";
MatchCollection matches = Regex.Matches(userTextInput, pattern);
StringBuilder outputString = new StringBuilder();
foreach (Match match in matches)
{
string outputRegExs = "Match: " + "\"" + match.Value + "\"" + " at index [" + match.Index + ","
+ (match.Index + match.Length) + "]" + "\n";
outputString.Append(outputRegExs);
}
txtRegExOutput.Text = outputString.ToString();
*/
} // End RegEx_Match_The_AllInstances
I left the commented code in to show what I had used in the C# code behind version to illustrate what I'm trying to accomplish.
The test input/string I used for this function is:
Don’t go there. If you want to be the Man, you have to beat The Man.
That should return two hits. Ideally, I want it to show the word that it found and the index where it found the word, but at this point I'd be happy to just get some output showing every instance it found, and then build on that with the index and possibly the lastIndex.
So, is my problem in my While loop, the way I'm applying the StringBuilder, or a combination of the two? I know the StringBuilder code works, at least when not being used in a loop and using some test data from the site I found that code. And the code for simply finding the first instance of "the" as a standalone or inside another word does work and returns output, but that doesn't use a loop.
I've looked through Stack Overflow and several other JavaScript websites for inspiration, but nothing I've tried so far has worked. I appreciate any help anyone can provide! (If you need me to post any other code, please advise and I'll be happy to oblige.)

Lint Error with to.Fixed(2)

So the problem I am having is that whenever I try to make the to.Fixed(2); at the end of my g_fTotal I get a lint error and it also doesn't show up in the txtTotal field. IT shows up in the filed when I take the toFixed off but I need to have the total show only two decimal points. What am I doing wrong here?
// 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 = "$" + g_fTotal.toFixed(2);
This is the whole code below.
// 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.
*/
/* ****** 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 = "$" + g_fTotal.toFixed(2);
} // 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 GetExtraUpdateTotal(p_iExtraIndex) {
if (g_chkExtras[p_iExtraIndex].checked === true) {
g_sExtras += g_chkExtras[p_iExtraIndex].value + ", ";
g_fTotal += gc_fExtrasPrice;
}
}
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

Categories