Как получить одно значение (щелчок) из цикла 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
}
Вернуться на верх