Abdul Tolba Abdul Tolba - 1 month ago 6
HTML Question

How to go about incrementing JavaScript variables with onclick & how to wrap around JS arrays?

I am trying to write a webpage that takes input with an HTML form and produces output through textboxes. The output and input are stored in a two dimensional 10x6 array. The webpage allows you to create a new sale/ form which is stored in the next array row, view the previous sale/form (which wraps around if you are at the first sale), and view the next sale/form (which wraps around if you are at the last sale/form). My problem is that I don't know how to increment two variables that control where in the array the information is stored, and how I can view the previous/next sales which also wrap around.

Here is my JavaScript code:

"use strict"; // Use JavaScript in strict mode

// This function will reset all form values except
// for the Sale ID and sale count
function clearForm(){
document.getElementById('coffeeType').value = " ";
document.getElementById('coffeeSize').value = " ";
document.getElementById("subtotal").value = " ";
document.getElementById("salesTax").value = " ";
document.getElementById("total").value = " ";
}

// This function will execute when the user clicks the "New Sale"
// button, which will automatically clear the form and change the
// Sale ID and Sales Count values.
function newSale() {
// The sale count will depend on the length of the array
// Ex: if there are 2 rows ([0] and [1]), the length = 2, thus saleNum = 2
saleNum = salesInfo.length ;
// Reseting the form so the user can eneter new information
document.getElementById("coffeeForm").reset();
document.getElementById("saleID").value = 1000 + saleNum;
document.getElementById("salesCount").value = saleNum;
// Output the salesInfo array into the developer log
console.log(salesInfo);
}

// This function will be used in the previousSale() and nextSale()
// functions to output the previous or next sale into the HTML form
function getSale(saleNumber) {
document.getElementById('coffeeType').value = salesInfo[saleNum].coffeeType;
document.getElementById('coffeeSize').value = salesInfo[saleNum].coffeeSize;
document.getElementById("saleID").value = salesInfo[saleNum].saleID;
document.getElementById("subtotal").value = salesInfo[saleNum].subtotal.toFixed(2);
document.getElementById("salesTax").value = salesInfo[saleNum].salesTax.toFixed(2);
document.getElementById("total").value = salesInfo[saleNum].total.toFixed(2);
}

// This function will show the previous sale when the user clicks
// a button by decrementing/incrementing array values
function previousSale() {
// If the saleNum (salesInfo[index]) value is greater than zero, it will decrement
if (saleNum > 0) {
saleNum--;
}
// If the saleNum is at the oldest sale, it will show the newest sale
else if (saleNum == 0 && salesInfo.length > 1){
// Do something?
}
getSale(saleNum);
}

// This function will show the next sale when the user clicks
// a button by decrementing/incrementing array values
function nextSale() {
// If the saleNum (salesInfo[index]) value is greater than the array length, it will increment
if (saleNum < salesInfo.length - 1) {
saleNum++;
}
// If the saleNum is at the newest sale, it will show the oldest sale
else if (saleNum == salesInfo.length - 1){
// Do something?
}
getSale(saleNum);
}

// This function will verify user input and genereate errors if it is not accepted,
// otherwise is will store information in an array and perform calculations,
// and return output using an HTML form
function confirmForm() {
var coffeeType = document.getElementById('coffeeType').value.toUpperCase(),
coffeeSize = document.getElementById('coffeeSize').value.toUpperCase(),
saleID = document.getElementById('saleID').value;

// If the coffee type is not found in the price object ('L', 'B', or 'D'),
// generate an error and return false.
if (!price[coffeeType]) {
alert("Error: Please enter a valid coffee type (L - Light, B - Blend, D - Dark)!");
return false;
}

// If the coffee size is not found in the price object ('S', 'M', or 'L'),
// generate an error and return false.
if (!price[coffeeType][coffeeSize]) {
alert("Error: Please enter a valid coffee size (S - Small, M - Medium, L - Large).");
return false;
}

// Subtotal will vary depending on coffee type and coffee size, which uses an object
var subtotal = price[coffeeType][coffeeSize];
/* ****** Calculating the sales tax and total ****** */
var salesTax = subtotal * 0.06;
var total = subtotal + salesTax;
/* ************************************************* */

// Assigns salesInfo[saleNum] to salesInfo[saleNum] if it exists, or an empty object if it doesnt
salesInfo[saleNum] = salesInfo[saleNum] || {};

salesInfo[saleNum].saleID = saleID;
salesInfo[saleNum].coffeeType = coffeeType;
salesInfo[saleNum].coffeeSize = coffeeSize;
salesInfo[saleNum].subtotal = subtotal;
salesInfo[saleNum].salesTax = salesTax;
salesInfo[saleNum].total = total;
// Return the output to the user
getSale(saleNum);
return true;

} // end of confirmForm()

// Initializing global variables
var saleNum = 0;

// Using an object array to store coffee prices
var price = {
L: { S: 2.00, M: 2.80, L: 3.60 },
B: { S: 2.50, M: 3.00, L: 3.85 },
D: { S: 2.75, M: 3.20, L: 4.00 }
};

// Empty array that will contain sales information
var salesInfo = [];

// End of JavaScript


Here is my HTML code:

<form id = "coffeeForm">
<p>
<label>Sale ID:
<input type="text" name="saleID" id = "saleID" value = "1000" readonly>
</label>
<label>Sales Count:
<input type="text" name="salesCount" id = "salesCount" value = "1" readonly>
</label>
</p>

<p>
<label>Coffee Type (L - Light, B - Blend, D - Dark):
<input type="text" name="coffeeType" id = "coffeeTypeId">
</label>
</p>

<p>
<label>Coffee Size (S - Small, M - Medium, L - Large):
<input type="text" name="coffeeSize" id = "coffeeSizeId">
</label>
</p>

<p>
<!-- button that will execute javascript functions when clicked by the user, then return the output -->
<button onClick="confirmForm();return false;" class = "button button1">Calculate</button>
</p>
<!--<div id="resultsDiv" style="display:none;">-->
<p>
<label>Subtotal:
<input type="text" name="subtotal" id="subtotal" style = "background-color: #FFFFC2;" readonly>
</label>
</p>
<p>
<label>Sales Tax:
<input type="text" name="salesTax" id="salesTax" style = "background-color: #FFFFC2;" readonly>
</label>
</p>
<p>
<label>Total:
<input type="text" name="total" id="total" style = "background-color: #F3E5AB;" readonly>
</label>
</p>
<p>
<!-- Somehow increment saleNum and saleID here after the form resets-->
<button onClick="resetForm();" class = "button button1">New Sale</button>
<button onClick="previousSale();return false;" class = "button button1">Previous Sale</button>
<button onClick="nextSale();return false;" class = "button button1">Next Sale</button>
<input type="reset" value="Reset" class = "button button1">
</p>
</form>

Answer

You could use an array of objects and use a counter for the inserted sales.

'use strict';

function showDiv() {
    document.getElementById('resultsDiv').style.display = "block";
}

function resetForm() {
    document.getElementById("coffeeForm").reset();
}

function newSale() {
    saleNum = salesInfo.length ;
    document.getElementById("coffeeForm").reset();
    document.getElementById("saleID").value = 1000 + saleNum;
    document.getElementById("salesCount").value = saleNum;
    console.log(salesInfo);
}

function getSale(saleNumber) {
    Object.keys(salesInfo[saleNum]).forEach(function (key) {
        document.getElementById(key).value = salesInfo[saleNum][key];
    });
}

function previousSale() {
    if (saleNum > 0) {
        saleNum--;
    }
    getSale(saleNum);
}

function nextSale() {
    if (saleNum < salesInfo.length - 1) {
        saleNum++;
    }
    getSale(saleNum);
}

function confirmForm() {
    var coffeeType = document.getElementById('coffeeType').value.toUpperCase(),
        coffeeSize = document.getElementById('coffeeSize').value.toUpperCase(),
        saleID = document.getElementById('saleID').value;

    if (!price[coffeeType]) {
        alert("Error: Please enter a valid coffee type (L - Light, B - Blend, D - Dark)!");
        return false;
    }

    if (!price[coffeeType][coffeeSize]) {
        alert("Error: Please enter a valid coffee size (S - Small, M - Medium, L - Large).");
        return false;
    }

    var subtotal = price[coffeeType][coffeeSize];
    var salesTax = subtotal * 0.06;
    var total = subtotal + salesTax;
    salesInfo[saleNum] = salesInfo[saleNum] || {};
    salesInfo[saleNum].saleID = saleID;
    salesInfo[saleNum].coffeeType = coffeeType;
    salesInfo[saleNum].coffeeSize = coffeeSize;
    salesInfo[saleNum].subtotal = subtotal.toFixed(2);
    salesInfo[saleNum].salesTax = salesTax.toFixed(2);
    salesInfo[saleNum].total = total.toFixed(2);
    getSale(saleNum);
    return true;
}

var saleNum = 0,
    price = {
        L: { S: 2.00, M: 2.80, L: 3.60 },
        B: { S: 2.50, M: 3.00, L: 3.85 },
        D: { S: 2.75, M: 3.20, L: 4.00 }
    },
    salesInfo = [];
<form id="coffeeForm" onsubmit="return false;">
<p><label>Sale ID: <input type="text" name="saleID" id="saleID" value="1000" disabled></label><label>Sales Count: <input type="text" name="salesCount" id="salesCount" value="0" disabled></label></p>
<p><label>Coffee Type (L - Light, B - Blend, D - Dark): <input type="text" name="coffeeType" id="coffeeType"></label></p>
<p><label>Coffee Size (S - Small, M - Medium, L - Large): <input type="text" name="coffeeSize" id="coffeeSize"></label></p>
<p><button onClick="confirmForm();return false;" class="button button1">Calculate</button></p>
<p><label>Subtotal: <input type="text" name="subtotal" id="subtotal" style="background-color: #FFFFC2;" readonly></label></p>
<p><label>Sales Tax: <input type="text" name="salesTax" id="salesTax" style="background-color: #FFFFC2;" readonly></label></p>
<p><label>Total: <input type="text" name="total" id="total" style="background-color: #F3E5AB;" readonly></label></p>
<p><button onClick="newSale();" class="button button1">New Sale</button><button onClick="previousSale();return false;" class="button button1">Previous Sale</button><button onClick="nextSale();return false;" class="button button1">Next Sale</button><input type="reset" value="Reset" class="button button1"></p>
</form>