-1

(ETA: I'm working on this for a class and the teacher wants everything to be "oninput"...yes, it's annoying :p )

I'm working on a form where each function miltiplies a number and gives me a "subtotal" on input. I'd like to take the two "subtotal" answers from the two functions and add them togething into a "total" amount. I feel like this should be simple but nothing I've tried works.

Here's what I've got in the javascript that works to give me the two subtotals:


function myCalculator() {
    var qty1 = document.getElementById('qty1').value;
    document.getElementById('subTotalOne').innerHTML = '$ ' + qty1 * 19.99;
}

function myCalculatorTwo() {
    var qty2 = document.getElementById('qty2').value;
    document.getElementById('subTotalTwo').innerHTML = '$ ' + qty2 * 37.99;
}

Here's the important parts of the html:

                    <div class="qty">
                        <label for="qty">Qty</label><br>
                        <input type="number" id="qty1" placeholder="0" oninput="myCalculator()"/><br>
                        <input type="number" id="qty2" placeholder="0" oninput="myCalculatorTwo()"/><br>
                    </div>
                 
                    <div class="price">
                        <label for="price">Price</label>
                        <p>$19.99</p>
                        <p>$37.99</p>
                    </div>
                
                    <div class="subtotal">
                        <label for="subTotal">Total</label><br>
                        <span class="subTotalOne" id="subTotalOne">$</span><br>
                        <span class="subTotalTwo" id="subTotalTwo">$</span><br>
                    </div>
                 
                 
                    <div class="total">
                        <label for="total">Order Total</label><br>
                        <span class="orderTotal" id="orderTotal" oninput="orderTotal()">$</span><br>
                    </div>

I'm trying to add the subTotalOne and subTotalTwo and have them output at orderTotal, essentially. :)

Thanks!

  • Welcome to Stack Overflow! Just to improve your code, it's usually better to avoid inline JS so the code is easier to read and maintain (everything's in "one" place). [Why Should I Avoid Inline Scripting?] (https://softwareengineering.stackexchange.com/questions/86589/why-should-i-avoid-inline-scripting) – bordeaux Aug 02 '20 at 01:10

3 Answers3

0

Here's how you do it:

function orderTotal() {
    const qty1  = document.getElementById('qty1').value;
    const qty2  = document.getElementById('qty2').value;
    const total = parseInt(qty1) + parseInt(qty2);

    document.getElementById('orderTotal').innerHTML = '$ ' + total;
}

Remove the oninput="orderTotal()" in your span element and trigger the above function using a button click e.g. <button onClick="orderTotal()">Calculate Total</button> or maybe when either of your two inputs' value changes. Also consider using const and let instead of var.

https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/

Ray Caballero
  • 435
  • 1
  • 7
  • 14
  • Hi, thanks! I'm working on this for a class and the teacher specifically wants everything to be "oninput" :\ – user14035273 Aug 02 '20 at 01:44
  • If that's the case then you'll have to call the orderTotal() function at the end of both your myCalculator() and myCalculatorTwo() functions. So that the total gets computed every time either of the inputs' value changes. Putting the oninput in the span element makes no sense since it is not something you can type on. – Ray Caballero Aug 02 '20 at 01:49
0

Instead of querying the DOM in Ray's answer--as DOM queries should generally be avoided since they are slow W3 Wiki, you could also consider using a shared variable between the two functions.

Also, consider using something else in place of innerHTML, mostly because of efficiency why-is-element-innerhtml-bad-code.

var total1;
var total2;

function myCalculator() {
    var qty1 = document.getElementById('qty1').value;
    total1 = qty1 * 19.99
    document.getElementById('subTotalOne').textContent = '$ ' + total1;
}

function myCalculatorTwo() {
    var qty2 = document.getElementById('qty2').value;
    total2 = qty2 * 37.99;
    document.getElementById('subTotalTwo').textContent = '$ ' + total2;
}

function orderTotal() {
    document.getElementById('orderTotal').innerHTML = '$ ' + (total1 + total2); 
    //parentheses because '$' isn't a number so the numbers total1 and total2 will be treated like strings and joined together 
}
bordeaux
  • 333
  • 3
  • 15
  • Hi, thank you! Is this supposed to work oninput? (I'm working on this for a class and the teacher wants everything oninput (sorry I forgot to mention that)) This totally makes sense but it does nothing when I try it :( – user14035273 Aug 02 '20 at 02:01
0

//Global variables (concidering ID is unique)
let subTotalOne, subTotalTwo, qty1, qty2, orderTotal;

const setup = () => {
    subTotalOne = document.getElementById('subTotalOne');
  subTotalTwo = document.getElementById('subTotalTwo');
  qty1 = document.getElementById('qty1');
  qty2 = document.getElementById('qty2');
  orderTotal = document.getElementById('orderTotal');
  
  myCalculator();
  myCalculatorTwo();
};

const updateTotal = (target, value) => {
    if(target == null || value == null || Number.isNaN(value)) return;
  
  target.textContent = `$ ${value.toFixed(2)}`;
  target.setAttribute('data-value', value.toFixed(2));
}
const getTotal = () => {
  if(subTotalOne == null || subTotalTwo == null) return 0;

  const [value1, value2] = [
    Number.parseFloat((subTotalOne.dataset?.value ?? 0), 10),
    Number.parseFloat((subTotalTwo.dataset?.value ?? 0), 10)
  ];
  
  if(Number.isNaN(value1) || Number.isNaN(value2)) return;
  else return value1 + value2;
};

const updateOrderTotal = () => updateTotal(orderTotal, getTotal());

const myCalculator = () => {
  const value = Number.parseFloat(qty1.value || 0, 10) * 19.99;
  updateTotal(subTotalOne, value);

  updateOrderTotal();
}

const myCalculatorTwo = () => {
  const value = Number.parseFloat(qty2.value || 0, 10) * 37.99;
  updateTotal(subTotalTwo, value);
  
  updateOrderTotal();
}

window.addEventListener('load', setup);
<div class="qty">
  <label for="qty">Qty</label><br>
  <input type="number" id="qty1" placeholder="0" oninput="myCalculator()" min="0"><br>
  <input type="number" id="qty2" placeholder="0" oninput="myCalculatorTwo()" min="0"><br>
</div>

<div class="price">
  <label for="price">Price</label>
  <p data-value="19.99">$19.99</p>
  <p data-value="37.99">$37.99</p>
</div>

<div class="subtotal">
  <label for="subTotal">Total</label><br>
  <span class="subTotalOne" id="subTotalOne">$</span><br>
  <span class="subTotalTwo" id="subTotalTwo">$</span><br>
</div>


<div class="total">
  <label for="total">Order Total</label><br>
  <span class="orderTotal" id="orderTotal" oninput="orderTotal()">$</span><br>
</div>
Jens Ingels
  • 806
  • 1
  • 9
  • 12