2

I have a simple JavaScript function that sums user input. The function is working fine when I tested it without the form tag. But when I use the same code inside the form tag. The console shows the error

TypeError: total is not a function

my code

function total() {
  a = Number(document.getElementById('qty').value);
  b = Number(document.getElementById('amount').value);
  c = a * b;
  document.getElementById('totalPrice').value = c;
}
<form>
  <div>
    <label>Part Quantity</label>
    <input type="number" name="quantity" class="form-control" placeholder="Part Quantity" min="1" id="qty" onkeyup="total()">
  </div>
  <div>
    <label>Part Price</label>
    <input type="number" name="price" class="form-control" min="1" placeholder="Part Price" id="amount" onkeyup="total()">
  </div>
  <div>
    <label>Total Price(in USD)</label>
    <input type="text" name="total" readonly="" class="form-control" min="1" placeholder="Total Price" id="totalPrice">
  </div>
  <div class="col-lg-12 col-md-12 col-xs-12 col-sm-12 order-btn">
    <button type="submit" class="btn btn-danger pull-right" name="order">
Order Now
</button>
  </div>
</form>

I have tried this aswell

onkeyup="return javascript:total()"

which gives me console error. The syntax is stated javascript function not working in form

SyntaxError: unexpected token: ':'

7
  • 4
    Try to put your script after the </form> tag Commented Mar 26, 2019 at 7:06
  • 1
    Please rename your function name and try Commented Mar 26, 2019 at 7:08
  • Check this w3schools.com/jsref/tryit.asp?filename=tryjsref_onkeyup Commented Mar 26, 2019 at 7:08
  • cant replicate the same error Commented Mar 26, 2019 at 7:09
  • placing script before <form > or after </form> tag gives the same error. Commented Mar 26, 2019 at 7:10

5 Answers 5

2

You cannot name a function same as any of the form element's name or id value. In this case, you have an input:

<input type="text" name="total" readonly="" class="form-control" min="1" placeholder="Total Price" id="totalPrice">

And your function is

function total

It happens because when you are doing,

onkeyup="total()"

this is as good as (because you can access form elements using DOM APIs),

onkeyup="this.form.total()"

And in this case, this.form.total is not a function, as it is part of the form. Hence you get the error:

TypeError: total is not a function
Sign up to request clarification or add additional context in comments.

Comments

0

Please try this, Just rename your function name

function calculateTotal() {
  a = Number(document.getElementById('qty').value);
  b = Number(document.getElementById('amount').value);
  c = a * b;
  document.getElementById('totalPrice').value = c;
}
<form>
  <div>
    <label>Part Quantity</label>
    <input type="number" name="quantity" class="form-control" placeholder="Part Quantity" min="1" id="qty" onkeyup="calculateTotal()">
  </div>
  <div>
    <label>Part Price</label>
    <input type="number" name="price" class="form-control" min="1" placeholder="Part Price" id="amount" onkeyup="calculateTotal()">
  </div>
  <div>
    <label>Total Price(in USD)</label>
    <input type="text" name="total" readonly="" class="form-control" min="1" placeholder="Total Price" id="totalPrice">
  </div>
  <div class="col-lg-12 col-md-12 col-xs-12 col-sm-12 order-btn">
    <button type="submit" class="btn btn-danger pull-right" name="order">
Order Now
</button>
  </div>
</form>

Comments

0

input name="total" with function total{} in the same form on you example, so you should change one.

Comments

0

To do this without inline event handlers and a more modern coding style you could do something like this.

    <form>
        <div>
            <label>Part Quantity</label>
            <input type="number" name="quantity" class="form-control" placeholder="Part Quantity" min="1" id="qty" />
        </div>
        <div>
            <label>Part Price</label>
            <input type="number" name="price" class="form-control" min="1" placeholder="Part Price" id="amount" />
        </div>
        <div>
            <label>Total Price(in USD)</label>
            <input type="text" name="total" readonly="" class="form-control" min="1" placeholder="Total Price" id="totalPrice">
        </div>
        <div class="col-lg-12 col-md-12 col-xs-12 col-sm-12 order-btn">
            <button type="submit" class="btn btn-danger pull-right" name="order">
                Order Now
            </button>
        </div>
    </form>

    <script>
        const obj=(id)=>{ return document.getElementById( id ) };
        document.querySelectorAll( 'input[type="number"].form-control' ).forEach( input => {
            input.addEventListener('keyup', e=>{
                obj('totalPrice').value=Number( obj('qty').value ) * Number( obj('amount').value )
            })
        })
    </script>

Comments

0

Function cannot have same name as pre-existing property. reference

When you create form, you get generated HTML Form DOM Object, and every input within that form is child element. When you create input, and add name attribute, it actually creates property that is named as input's name attribute value and can be accessed using it like this:

formObject.inputAttributeNameValue

Sample:

var theForm = document.getElementById("the_form");

console.log(theForm.total);
<form id="the_form">
  <div>
  <div>
    <label>Total Price(in USD)</label>
    <input type="text" name="total" readonly="" class="form-control" min="1" placeholder="Total Price" id="totalPrice">
  </div>
  </div>
</form>

So you must avoid conflict between function names and property names. Otherwise, it will throw error TypeError: <functionName> is not a function.

You will notice that I have changed event to oninput that occurs whenever input value is change, so total price will calculate on any change, even changing value with spinner, not only after onkeyup event:

//note: function needs to be unique compared to inputs' name values 
function totalPriceCalculated() { 
  a = Number(document.getElementById('qty').value);
  b = Number(document.getElementById('amount').value);
  c = a * b;
  document.getElementById('totalPrice').value = c;
}
<form>
  <div>
    <label>Part Quantity</label>
    <input type="number" name="quantity" class="form-control" placeholder="Part Quantity" min="1" id="qty" oninput="totalPriceCalculated()">
  </div>
  <div>
    <label>Part Price</label>
    <input type="number" name="price" class="form-control" min="1" placeholder="Part Price" id="amount" oninput="totalPriceCalculated()">
  </div>
  <div>
    <label>Total Price(in USD)</label>
    <input type="text" name="total" readonly="" class="form-control" min="1" placeholder="Total Price" id="totalPrice">
  </div>
  <div class="col-lg-12 col-md-12 col-xs-12 col-sm-12 order-btn">
    <button type="submit" class="btn btn-danger pull-right" name="order">
Order Now
</button>
  </div>
</form>

See more about error caused when function shares a name with pre-existing property: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_function#Function_shares_a_name_with_a_pre-existing_property

Note: Be careful about function placement in your HTML and scope. It should be placed directly inside of <head> or at the bottom, before closing </body> tag, but not within window.onload

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.