0

i'm trying to generate a simple subtotal amount for a small shopping cart project and it does not seem like the function can see the input value

my input HTML is: <input id="valueTest1" type="text" value="0" data-price="10.99">

and i just need simply the data-price to * the value entered and then show in my subtotal HTML (shown below)

<div id="itemTotal1" class="subtotal-price">£0.00</div>

here is my function..

function calculateSubTotal() {
    let subtotal = 0;
    for (i = 1; i <= itemTotal1; i++) {

        itemID = document.getElementById('valueTest1');
        if (typeof itemID === 'undefined' || itemID === null) {
            alert("No such item - " + "valueTest1");
        } else {
            subtotal = subtotal + parseFloat(valueTest1.value) * parseFloat(itemID.getAttribute("data-price"));
        }

    }
    console.log(valueTest1.value)
    document.getElementById('itemTotal1').innerHTML = "£" + subtotal;
}

I can console.log the input (valueTest1.value) outside of the function and it shows 0 but when i try to console.log the input in the function i get nothing, any help would be appreciated.

ShrewdStyle
  • 500
  • 2
  • 5
  • 14
  • 1
    `parseFloat(valueTest1.value)` Do you mean `parseFloat(itemID.value)`? If you provide your code as a runnable snippet you'll be more likely to get an answer. – benbotto Feb 05 '20 at 19:38
  • How and when are you calling the function? – Teemu Feb 05 '20 at 19:38
  • what is `itemTotal1`? – Calvin Nunes Feb 05 '20 at 19:39
  • 2
    Side note, you should probably scope the variables `i` and `itemID` using `let` and `const`, respectively. – benbotto Feb 05 '20 at 19:39
  • @CalvinNunes the itemTotal1 is my section for the total amount of the item amount * price – ShrewdStyle Feb 05 '20 at 19:53
  • @Teemu i'm calling the function as soon as the value in the input - valueTest1.value is entered but the function doesn't look like it can see anything entered – ShrewdStyle Feb 05 '20 at 19:54
  • @ShrewdStyle is your section? but I mean, is it a number? a node? an array? If it is not a number the for loop will never run – Calvin Nunes Feb 05 '20 at 19:55
  • @CalvinNunes it is a number which should be getting passed in, i have added a separate function in my code to increase the number using a button... maybe this is stopping it from seeing the value? https://codepen.io/ShrewdStyle/project/editor/APmkPz – ShrewdStyle Feb 05 '20 at 20:07
  • 1
    you never set or even initializate the variable `itemTotal1` – Calvin Nunes Feb 05 '20 at 20:08
  • @CalvinNunes ahhhh thank you, i will sort that out now, makes sense why the function cannot see the input now – ShrewdStyle Feb 05 '20 at 20:11

2 Answers2

1

You got some changes to do on your HTML and JS files. First, you could do something more "generic" to use, so you can reuse it on every input and button.

HTML:

<section id="shopping-cart">
    <div class="shopping-cart">
        <!-- <div class="title">
            Online Store
        </div> -->
        <div class="title">
            <ul>
                <li>Online Store</li>
                <li>Quantity</li>
                <li>Price</li>
                <li>Subtotal</li>
            </ul>
        </div>

        <!-- Product 1 -->
        <div class="item">
            <div class="buttons">
                <span class="delete-btn"></span>
                <span class="like-btn"></span>
            </div>

            <div class="image">
                <img src="/img/shop/cup.webp" alt="#">
            </div>

            <div class="description">
                <span>Cyberpunk 2077</span>
                <span>Coffee Mug</span>
                <span>Multi-color</span>
            </div>

            <div class="quantity">
                <button onclick="Input_ChangeValue(this, '-');" class="minus-btn">
                    <img src="/img/shop/minus-btn.png" alt="#">
                </button> <!-- Check the parameter values! -->
                <input id="valueTest1" type="text" value="0" data-price="10.99" onchange="calculateSubTotal(this);"> <!-- Calculate when the user inputs value -->
                <button onclick="Input_ChangeValue(this, '+');" class="plus-btn">
                    <img src="/img/shop/plus-btn.png" alt="#">
                </button> <!-- Check the parameter values! -->
            </div>

            <div id="itemPrice1" class="total-price">£10.99</div>
            <div id="itemTotal1" class="subtotal-price">£0.00</div>
        </div>
        <!-- Product 2 -->
        <div class="item">
            <div class="buttons">
                <span class="delete-btn"></span>
                <span class="like-btn"></span>
            </div>

            <div class="image">
                <img src="/img/shop/t-shirt.jpg" alt="#">
            </div>

            <div class="description">
                <span>Cyberpunk 2077</span>
                <span>T-Shirt</span>
                <span>Multi-color</span>
            </div>

            <div class="quantity">
                <button onclick="Input_ChangeValue(this, '-');" class="minus-btn">
                    <img src="/img/shop/minus-btn.png" alt="#">
                </button>
                <input id="valueTest2" type="text" value="0" data-price="15.99" onchange="calculateSubTotal(this);">
                <button onclick="Input_ChangeValue(this, '+');" class="plus-btn">
                    <img src="/img/shop/plus-btn.png" alt="#">
                </button>
            </div>

            <div id="itemPrice2" class="total-price">£<span>15.99</span></div>
            <div id="itemTotal2" class="subtotal-price">£<span>0.00</span></div>
        </div>

        <!-- Product 3 -->
        <div class="item">
            <div class="buttons">
                <span class="delete-btn"></span>
                <span class="like-btn"></span>
            </div>

            <div class="image">
                <img src="/img/shop/jacket1.jpg" alt="#">
            </div>

            <div class="description">
                <span>Cyberpunk 2077</span>
                <span>Womens Jacket</span>
                <span>Dark</span>
            </div>

            <div class="quantity">
                <button onclick="Input_ChangeValue(this, '-');" class="minus-btn">
                    <img src="/img/shop/minus-btn.png" alt="#">
                </button>
                <input type="text" id="valueTest3" value="0" data-price="24.99" onchange="calculateSubTotal(this);">
                <button onclick="Input_ChangeValue(this, '+');" class="plus-btn">
                    <img src="/img/shop/plus-btn.png" alt="#">
                </button>
            </div>

            <div id="itemPrice3" class="total-price">£<span>24.99</span></div>
            <div id="itemTotal3" class="subtotal-price">£<span>0.00</span></div>
        </div>
    </div>
</section>

JS:

function Input_ChangeValue(trigger, operation) {
  let inputChange = trigger.parentElement.querySelector("input");

  if (inputChange != null) {
    let actualValue = parseInt(inputChange.value);
    let nextValue = 0;

    switch (operation) {
      case "-":
        nextValue = actualValue - 1;
        break;
      case "+":
        nextValue = actualValue + 1;
        break;
    }

    if (nextValue <= 0) nextValue = 0; //don't allow negative numbers

    inputChange.value = nextValue;

    calculateSubTotal(inputChange);
  }
}

function calculateSubTotal(inputElement) {

  let subTotalDiv = inputElement.parentElement.parentElement.querySelector(".subtotal-price");

  if (inputElement != null && subTotalDiv != null) {
    //input found
    let qty = parseFloat(inputElement.value);
    let price = parseFloat(inputElement.getAttribute("data-price"));
    let subtotal = qty * price;

    //for debugging
    console.log(subtotal);
    subTotalDiv.innerHTML = `£${subtotal}`;
  }
}

Still there are a couple of validations you should check, like inputs accepting only numbers or the Subtotal column only showing the first 2 decimal places.

Good luck!

FF-
  • 732
  • 9
  • 19
  • Thank for yeah that was definitely mixed up, however after i've corrected it my function still cannot see my HTML, the console is just empty when i try to console.log the itemID.value still – ShrewdStyle Feb 05 '20 at 19:55
  • Well, if i omit your "for" clause, and use it directly, is giving me the value correctly. [Check it out](https://jsbin.com/zehadupili/edit?html,js,console,output) – FF- Feb 05 '20 at 20:01
  • ahhh i see you are right, here is my full setup in codepen... i think it must be something in my HTML? https://codepen.io/ShrewdStyle/project/editor/APmkPz – ShrewdStyle Feb 05 '20 at 20:06
  • yes that is my goal, i was going to do a separate function for each SubTotal – ShrewdStyle Feb 05 '20 at 20:12
  • Well, there are a couple of things that could be better implemeted. You should change the way you change values from your buttons to something more "generic".The same thing can be said about your Subtotal calculation. I made a couple of changes to your HTML and JS. [Check it out](https://jsbin.com/cixuwijeko/edit?html,js,output). If this is what you were looking for, i can edit the answer, so you can accept it :) – FF- Feb 05 '20 at 20:55
  • Thank you so much for this help, i tried your original answer and i was missing the function which you added in the input onchange="calculateSubTotal()" and it's now working, I have just looked at your new post and it works even better than the original, i will have a coffee now and study this for a while, thank you again... is there a way to add people on StackOverflow? – ShrewdStyle Feb 05 '20 at 21:06
  • Not that I’m aware of. – FF- Feb 05 '20 at 21:53
1

Your loop is redundant here - you are multiplying a single value from an element with another value from the same element.

I would go with the easier to read and safer:

    <body>
    <script>
        function calculateSubTotal() {
            let subtotal = 0;
            let item = document.getElementById('valueTest1');
            let itemTotal = document.getElementById('itemTotal1');

            if (typeof item === 'undefined' || item === null) {
                alert("No such item - " + " valueTest1");
            }

            let itemCount = parseFloat(item.value);
            if (!isNaN(itemCount)) {
                let itemPrice = parseFloat(item.getAttribute('data-price'));

                if (!isNaN(itemPrice )) {
                    subtotal += itemCount * itemPrice;
                }
            }

            itemTotal1.innerHTML = "£" + subtotal;
        }
    </script>

    <input id="valueTest1" type="text" value="0" data-price="10.99" onblur="javascript:calculateSubTotal()">

    <div id="itemTotal1" class="subtotal-price">£0.00</div>
</body>
Steve Padmore
  • 1,710
  • 1
  • 12
  • 18