Функция Javascript не работает в html-форме - TypeError: total не является функцией - PullRequest
2 голосов
/ 26 марта 2019

У меня есть простая функция JavaScript, которая суммирует вводимые пользователем данные. Функция работает нормально, когда я тестировал ее без тега формы. Но когда я использую тот же код внутри тега формы. Консоль показывает ошибку

TypeError: total не является функцией

мой код

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>

Я попробовал это также

onkeyup="return javascript:total()"

, что дает мне ошибку консоли. Синтаксис: функция JavaScript не работает в форме

SyntaxError: неожиданный токен: ':'

Ответы [ 5 ]

2 голосов
/ 26 марта 2019

Вы не можете называть функцию так же, как любое другое имя элемента или значение id. В этом случае у вас есть вход:

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

И ваша функция

function total

Это происходит потому, что когда вы делаете,

onkeyup="total()"

это так же хорошо, как (потому что вы можете получить доступ к элементам формы с помощью API DOM),

onkeyup="this.form.total()"

И в этом случае this.form.total не является функцией, так как является частью формы. Следовательно вы получаете ошибку:

TypeError: total is not a function
0 голосов
/ 26 марта 2019

Функция не может иметь то же имя, что и ранее существовавшее свойство. ссылка

Когда вы создаете форму, вы получаете сгенерированный объект DOM HTML-формы, и каждый вход в этой форме является дочерним элементом. Когда вы создаете вход и добавляете атрибут имени, он фактически создает свойство, которое называется значением атрибута имени входного файла, и к нему можно получить доступ, используя его так:

formObject.inputAttributeNameValue

Пример:

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>

Таким образом, вы должны избегать конфликтов между именами функций и именами свойств. В противном случае выдаст ошибку TypeError: <functionName> is not a function.

Вы заметите, что я изменил событие на oninput, которое происходит при изменении входного значения, поэтому общая цена будет рассчитываться при любом изменении, даже при изменении значения с помощью счетчика, а не только после события onkeyup:

//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>

Подробнее об ошибке, вызванной тем, что функция разделяет имя с уже существующим свойством: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_function#Function_shares_a_name_with_a_pre-existing_property

Примечание: Будьте осторожны с размещением функций в вашем HTML и области видимости. Он должен быть расположен непосредственно внутри <head> или внизу, перед закрытием тега </body>, но не внутри window.onload

0 голосов
/ 26 марта 2019

Чтобы сделать это без встроенных обработчиков событий и более современного стиля кодирования, вы можете сделать что-то вроде этого.

    <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>
0 голосов
/ 26 марта 2019

input name = "total" с функцией total {} в той же форме, что и в вашем примере, поэтому вы должны изменить ее.

0 голосов
/ 26 марта 2019

Пожалуйста, попробуйте это, Просто переименуйте имя вашей функции

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...