dropdown with pure javascript

2

Talk to people, good morning, I need a help with a dropdown. every donation in the database I have a button that I click on the items that have been donated.

I have the following line of code:

user-donation.js

const dropdownBtns = document.querySelectorAll('.arrow img');
for (dropdownBtn of dropdownBtns){
    dropdownBtn.onclick = dropDown;
}
function dropDown(){
    const contents = document.querySelectorAll('.dropdown-content');
    for (let content of contents){
        content.classList.toggle("show");
    }
}

user-donations.js

<div class="dropdown">
    <div class="arrow">
        <img src="{% static 'images/arrow-down-icon.png' %}" alt="" id="arrow">
    </div>
    <div class="dropdown-content">
        <ul class="list-itens">
            {% for item in donation.items %}
            <li>{{item.material.name}} x{{item.quantity}}</li>
            {% endfor %}
        </ul>
    </div>
</div>

But when I click on any of the dropdownBtn I show the items of all donations and not just the one I want.

Someone can help me?

    
asked by anonymous 13.11.2018 / 14:48

1 answer

4

Place a parameter in the dropDown() function from where you can find the source of the click.

function dropDown(e){...
                  ↑

To know which element was clicked and which called the function, you use:

e.target

With this you can get to the next .dropdown-content element related. This element is the parent's brother of the clicked button. You arrive at it with:

e.target.parentNode.nextElementSibling;
              ↑             ↑
             pai   irmão adjacente do pai

Example:

const dropdownBtns = document.querySelectorAll('.arrow_img');
for (dropdownBtn of dropdownBtns){
    dropdownBtn.onclick = dropDown;
}
function dropDown(e){
   let alvo = e.target.parentNode.nextElementSibling;
   alvo.classList.toggle('show');
}
.dropdown-content{
   display: none;
}
.show{
   display: block;
}
<div class="dropdown">
    <div class="arrow">
        <img src="https://cdn3.iconfinder.com/data/icons/woothemesiconset/32/blue_arrow_down.png"alt="" class="arrow_img">
    </div>
    <div class="dropdown-content">
        <ul class="list-itens">
            {% for item in donation.items %}
            <li>{{item.material.name}} x{{item.quantity}}</li>
            {% endfor %}
        </ul>
    </div>
</div>
<div class="dropdown">
    <div class="arrow">
        <img src="https://cdn3.iconfinder.com/data/icons/woothemesiconset/32/blue_arrow_down.png"alt="" class="arrow_img">
    </div>
    <div class="dropdown-content">
        <ul class="list-itens">
            {% for item in donation.items %}
            <li>{{item.material.name}} x{{item.quantity}}</li>
            {% endfor %}
        </ul>
    </div>
</div>
  

Note: in the button images you are using id="arrow" . I imagine these buttons will be repeated, they will repeat the same    id , which is incorrect. A id must be unique on the page. Replace the    id="arrow" by class="arrow_img" .

If you want to hide what is open when it shows another, change the code of for by adding a if to remove the .show class from what is open:

const dropdownBtns = document.querySelectorAll('.arrow_img');
for (dropdownBtn of dropdownBtns){
    dropdownBtn.onclick = dropDown;
}
function dropDown(e){

   let alvo = e.target.parentNode.nextElementSibling;

   const contents = document.querySelectorAll('.dropdown-content');
   for (let content of contents){
      if(alvo != content) content.classList.remove('show');
   }

   alvo.classList.toggle('show');

}
.dropdown-content{
   display: none;
}
.show{
   display: block;
}
<div class="dropdown">
    <div class="arrow">
        <img src="https://cdn3.iconfinder.com/data/icons/woothemesiconset/32/blue_arrow_down.png"alt="" class="arrow_img">
    </div>
    <div class="dropdown-content">
        <ul class="list-itens">
            {% for item in donation.items %}
            <li>{{item.material.name}} x{{item.quantity}}</li>
            {% endfor %}
        </ul>
    </div>
</div>
<div class="dropdown">
    <div class="arrow">
        <img src="https://cdn3.iconfinder.com/data/icons/woothemesiconset/32/blue_arrow_down.png"alt="" class="arrow_img">
    </div>
    <div class="dropdown-content">
        <ul class="list-itens">
            {% for item in donation.items %}
            <li>{{item.material.name}} x{{item.quantity}}</li>
            {% endfor %}
        </ul>
    </div>
</div>
    
13.11.2018 / 15:17