Как получить одно значение (щелчок) из цикла for в проекте JS addEventListener Django
Я пытаюсь подключить JS внутри моего проекта Django и получаю сообщение в консоли, что
HTMLCollection(2) [p.currency-one, p.currency-one]
HTMLCollection(2) [input.amount-one, input.amount-one]
app.js:21 Uncaught TypeError: c1.addEventListener is not a function
at app.js:21:4
(anonymous) @ app.js:21
JS-файл
const c1 = document.getElementsByClassName("currency-one");
const c2 = document.getElementById("currency-two");
const amount1 = document.getElementsByClassName("amount-one");
const amount2 = document.getElementById("amount-two");
const swap = document.getElementById("swap");
const theRate = document.getElementById("rate");
console.log(c1,amount1)
function calculate() {
const curr1 = c1.innerHTML;
const curr2 = c2.innerHTML;
const rate = parseInt(amount1.value) / parseFloat(amount2.innerHTML);
theRate.innerText = `You can buy maximum -> you wallet money ${amount1.value} ${curr1} = ${rate} ${curr2}`;
}
// THIS PART OF THE CODE does not know how to get two pieces of information from one //class, how to get through it ?
c1.addEventListener("change", calculate);
amount1.addEventListener("input", calculate);
c2.addEventListener("change", calculate);
amount2.addEventListener("input", calculate);
swap.addEventListener("click", () => {
const flash = c1.value;
c1.value = c2.value;
c2.value = flash;
calculate();
});
view.py
def a(request,crypto_name, fiat_currency=None):
buttons = [
{"currency_type": "USD", "active": "", "display_text": "USD"},
{"currency_type": "EUR", "active": "", "display_text": "Euro"},
{"currency_type": "CNY", "active": "", "display_text": "Chinese Yuan"},
{"currency_type": "JPY", "active": "", "display_text": "Japanese Yen"},
]
for button in buttons:
if button['currency_type'] == fiat_currency:
button['active'] = 'active'
crypto_detail_view = load_detail_crypto(crypto_name,fiat_currency)
user_purchased_currencies = UserPurchasedCurrencies.objects.filter(user = request.user)
user_walet_info_amount_and_name = [x for i in user_purchased_currencies for x in (i.currency_amount,i.currency)]
x = crypto_name
context = {
"crypto_detail_view" : crypto_detail_view,
"buttons" : buttons,
"crypto_name" : crypto_name,
"fiat_currency" : fiat_currency,
"user_walet_info_amount_and_name" : user_walet_info_amount_and_name,
"user_purchased_currencies" : user_purchased_currencies,
}
return render(request, 'web/a.html', context)
html
{% extends "web/layout.html" %}
{% block body %}
<br><br><br>
<div id="jumbotron" class="jumbotron" style="text-align: center; margin-top:-50px">
<h1 id="devise" class="display-5">Devise </h1>
<h5>Exchange Rate Converter</h5>
<img src="image.jpg" class="image" style="width:100px; margin-bottom:-50px; " >
</div>
<div class="container">
<div class="page-header" id="banner">
<div class="row">
<div class="col-sm-15">
<h1 style="align-content: center;"> </h1>
<p class="lead" style="margin-left:280px; font-size:2rem">
</p>
</div>
</div>
</div>
<div class="row">
{% for item in buttons %}
{% for money_purchased in user_purchased_currencies %}
{% if item.currency_type != money_purchased.currency %}
{% else %}
<div class="col-4 col-md-4" >
<p class="currency-one">{{item.display_text}}</p>
<a href="{% url 'a' crypto_name=crypto_name fiat_currency=item.currency_type %}" class="btn btn-outline-dark {{item.active}}" role="button" >{{item.display_text}}</a>
</div>
<input type="number" class="amount-one" value="{{money_purchased.currency_amount}}" style="width:100%" />
{% endif %}
{% endfor %}
{% endfor %}
</div>
<br>
<div class="swap-btn">
<button type="button" id="swap" class="btn btn-outline-primary mx-auto d-block" >Swap <i class="fa fa-refresh" aria-hidden="true"></i></button>
</div>
<div class="rate" id="rate"></div>
<br>
{% for crypto in crypto_detail_view %}
<div class="container">
<div class="currency">
<p class="form-control" id="currency-two">{{crypto.name}}</p>
<br>
<p class="form-control" type="number" id="amount-two" style="width:100%">{{crypto.price}}</p>
</div>
</div>
{% endfor %}
<script src="/static/js/app.js"></script>
{% endblock %}
Я хотел бы получить только эти два, но только эти нажатые значения
c1.addEventListener("change", calculate);
amount1.addEventListener("input", calculate);
часть кода во views проверяет какие валюты купил пользователь, когда пользователь нажимает на USD например, он получает сколько USD он должен использовать и когда он уже выбрал/нажал, то код в JS должен выбрать соответствующую сумму и название валюты. Как это сделать? С использованием циклов?
<div class="row">
{% for item in buttons %}
{% for money_purchased in user_purchased_currencies %}
{% if item.currency_type != money_purchased.currency %}
{% else %}
<div class="col-4 col-md-4" >
<p class="currency-one">{{item.display_text}}</p>
<a href="{% url 'a' crypto_name=crypto_name fiat_currency=item.currency_type %}" class="btn btn-outline-dark {{item.active}}" role="button" >{{item.display_text}}</a>
</div>
<input type="number" class="amount-one" value="{{money_purchased.currency_amount}}" style="width:100%" />
{% endif %}
{% endfor %}
{% endfor %}
</div>
проблема существует здесь:
c1.addEventListener("change", calculate);
amount1.addEventListener("input", calculate);
c2.addEventListener("change", calculate);
amount2.addEventListener("input", calculate);
вы пытаетесь использовать контекст "addEventListener" на "getElementsByClassName", а этот getElementsByClassName относится ко многим элементам, поскольку вы поместили эти элементы в цикл for, поэтому это className будет читаться как массив
решение следующее:
вам следует зациклить эти классы, а именно p.currency-one и input.amount-one, как сказано в консоли, после чего вы можете применить вашу функцию eventListener.
например:
const c1 = document.getElementsByClassName("currency-one");
for(var i = 0; i < c1.length; i++) {
# apply your code here
}