Я пытаюсь вычислить значение некоторого поля ввода в моем шаблоне Django, используя javascript (onkeyup=(), форма находится в цикле, например, {% for p в прогнозе %} {% endfor %}.
У меня есть эта простая строка для захвата входных значений (ПРИМЕЧАНИЕ: они находятся в цикле)
let stake_amount_input = document.querySelector("#amount").value
let shares_amount_input = document.querySelector("#shares").value
Основываясь на том факте, что у меня есть все эти функции в цикле Django, разве я не должен получать все значения полей ввода при вычислении других объектов в цикле?
Основываясь на том факте, что у меня есть все эти функции в цикле Django, я не должен получать все шансы, когда я console.info(odds)
{% for p in prediction.prediction_data.all %}
<form action = "#" method = "POST">
<input type = "number" value = "" name = "amount" id = "amount" class = "shares" onkeyup = "CalculateNewBalance()">
<input type = "number" value = "" name = "shares" id = "shares" class = "shares" onkeyup = "CalculateNewBalance()">
<script>
function CalculateNewBalance(){
let stake_amount_input = document.querySelector(".amount").value
let shares_amount_input = document.querySelector(".shares").value
let potential_win = document.querySelector(".potential-win")
let potential_win_value = parseFloat(stake_amount_input) * parseInt(shares_amount_input)
potential_win.innerHTML = "$" + potential_win_value
// if the potential_win innerHTML shows Nan, then i want to change the innerHTML to $0.00, but this is not working too
if (potential_win === isNan) {
potential_win.innerHTML = "$0.00"
}
</script>
</form>
{% endfor %}
Обновлено: Мой шаблон
<div class = "mid-area">
<div class = "single-area">
<div class = "item-title d-flex align-items-center justify-content-between">
<span>Choose Stake Amount</span>
</div>
<div class = "d-flex in-dec-val">
<input type = "number" required value = "{{ p.amount }}" name = "amount" placeholder = "amount" class = "shares" />
<div class = "btn-area">
<button class = "plus" type = "button">
<img src = "{% static 'assets/images/icon/up-arrow.png' %}" alt = "icon" />
</button>
<button class = "minus" type = "button">
<img src = "{% static 'assets/images/icon/down-arrow.png' %}" alt = "icon" />
</button>
</div>
</div>
<p id = "error-div" class = "mt-2"></p>
</div>
<div class = "single-area quick-amounts"></div>
<div class = "single-area quick-amounts">
<div class = "item-title d-flex align-items-center">
<p>Choose <b>Shares</b> Amount</p>
</div>
<div class = "d-flex in-dec-val">
<input type = "number" required value = "1" name = "shares" placeholder = "shares" class = "shares" />
<div class = "btn-area">
<button class = "pldus" type = "button">
<img src = "{% static 'assets/images/icon/up-arrow.png' %}" alt = "icon" />
</button>
<button class = "mindus" type = "button">
<img src = "{% static 'assets/images/icon/down-arrow.png' %}" alt = "icon" />
</button>
</div>
</div>
</div>
<div class = "single-area smart-value">
<div class = "item-title d-flex align-items-center">
<p class = "mdr text-capitalize">Potential win</p>
</div>
<div class = "contact-val d-flex align-items-center"><span style = "font-size: 24px;" class = "potential-win">$0.00</span><br /></div>
</div>
</div>



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы должны добавлять уникальное имя каждый раз, когда вы зацикливаетесь. Имена переменных и идентификаторы должны быть уникальными. Для этого вам нужно добавить счетчик или уникальные значения. Проверьте этот ответ, чтобы узнать, как добавить счетчик.
{% for p in prediction.prediction_data.all %}
<form action = "#" method = "POST">
<input type = "number" value = "" name = "amount" id = "amount{{ forloop.counter }}" class = "shares" onkeyup = "CalculateNewBalance()">
<input type = "number" value = "" name = "shares" id = "shares{{ forloop.counter }}" class = "shares" onkeyup = "CalculateNewBalance()">
<script>
function CalculateNewBalance(){
let stake_amount_input{{ forloop.counter }} = document.querySelector(".amount{{ forloop.counter }}").value
let shares_amount_input{{ forloop.counter }} = document.querySelector(".shares{{ forloop.counter }}").value
let potential_win{{ forloop.counter }} = document.querySelector(".potential-win{{ forloop.counter }}")
let potential_win_value{{ forloop.counter }} = parseFloat(stake_amount_input{{ forloop.counter }}) * parseInt(shares_amount_input{{ forloop.counter }})
potential_win{{ forloop.counter }}.innerHTML = "$" + potential_win_value{{ forloop.counter }}
// if the potential_win innerHTML shows Nan, then i want to change the innerHTML to $0.00, but this is not working too
if (potential_win{{ forloop.counter }} === isNan) {
potential_win{{ forloop.counter }}.innerHTML = "$0.00"
}
</script>
</form>
{% endfor %}
{{ forloop.counter }} возвращает список чисел от 1 до числа, пока не запустится цикл for.
Это сделало бы каждый идентификатор уникальным и каждую переменную уникальной. Например, когда цикл выполняется
в первый раз:
let potential_win1 = document.querySelector(".potential-win1").value
во второй раз:
let potential_win2 = document.querySelector(".potential-win2").value
и так далее.
Вместо того, чтобы помещать всю форму и скрипт в цикл, просто добавьте поля ввода внутри цикла, а затем либо установите событие для каждого элемента внутри цикла, либо программно добавьте прослушиватель событий. Я покажу программный подход.
<form action = "#" method = "POST">
{% for p in prediction.prediction_data.all %}
<input type = "number" value = "" name = "amount" class = "shares" onkeyup = "CalculateNewBalance()">
<input type = "number" value = "" name = "shares" class = "shares" onkeyup = "CalculateNewBalance()">
{% endfor %}
</form>
let inputs = document.querySelectorAll('input');
function CalculateNewBalance(e) {
let target = e.target
let potential_win_value;
let potential_win;
if (target.nextElementSibling.classList.contains('potential-win')) {
potential_win = target.nextElementSibling
} else {
potential_win = target.nextElementSibling.nextElementSibling
}
if (target.nextElementSibling.classList.contains('shares')) {
potential_win_value = parseFloat(target.nextElementSibling.value) * parseInt(target.value)
} else {
potential_win_value = parseFloat(target.previousElementSibling.value) * parseInt(target.value)
}
potential_win.innerHTML = "$" + potential_win_value
if (potential_win.innerHTML == '$NaN') potential_win.innerHTML = '$0.00'
}
['input', 'change'].forEach(evt => {
inputs.forEach(input => input.addEventListener(evt, CalculateNewBalance, false))
});
Вот рабочий пример
let inputs = document.querySelectorAll('input');
function CalculateNewBalance(e) {
let target = e.target
let potential_win_value;
let potential_win;
if (target.nextElementSibling.classList.contains('potential-win')) {
potential_win = target.nextElementSibling
} else {
potential_win = target.nextElementSibling.nextElementSibling
}
if (target.nextElementSibling.classList.contains('shares')) {
potential_win_value = parseFloat(target.nextElementSibling.value) * parseInt(target.value)
} else {
potential_win_value = parseFloat(target.previousElementSibling.value) * parseInt(target.value)
}
potential_win.innerHTML = "$" + potential_win_value
if (potential_win.innerHTML == '$NaN') potential_win.innerHTML = '$0.00'
}
['input','change'].forEach( evt => {
inputs.forEach(input => input.addEventListener(evt, CalculateNewBalance, false))
}
);<form action = "#" method = "POST">
<input type = "number" value = "" name = "amount" placeholder = "amount" class = "shares">
<input type = "number" value = "" name = "shares" placeholder = "shares" class = "shares">
<span class = "potential-win">$0.00</span><br />
<input type = "number" value = "" name = "amount" placeholder = "amount" class = "shares">
<input type = "number" value = "" name = "shares" placeholder = "shares" class = "shares">
<span class = "potential-win">$0.00</span><br />
<input type = "number" value = "" name = "amount" placeholder = "amount" class = "shares">
<input type = "number" value = "" name = "shares" placeholder = "shares" class = "shares">
<span class = "potential-win">$0.00</span><br />
</form>Примечание:
- Если вы создаете приложение, которое включает в себя реальные транзакции и расчеты суммы, вы не должны полагаться на расчеты на стороне клиента. обрабатывать его на стороне сервера.
- Не используйте идентификатор внутри цикла, он должен быть уникальным
Привет @DestinyFranks Где находится цикл внутри вашего HTML-кода, если он там есть, добавьте его тоже.
Большое спасибо, ваш код работает так, как ожидалось. Единственное, у меня есть некоторые другие элементы, оборачивающие мои поля ввода, поэтому
nextElementSibling, похоже, не работает, когда я использую свой шаблон. Пожалуйста, что я могу сделать? Я обновил свой код, чтобы включить мой шаблон