skip to Main Content

I am currently struggling to get a function working with a button that has an onclick event to toggle a class. Please can you review the code and help me understand why it is needing two clicks and how to fix it.

function dropdownbuttonclick(element) {
  let coll = $(".dropdown");
  
  for (let i = 0; i < coll.length; i++) {
    //coll[i].addEventListener("click", function () { 
    $(this.firstChild).toggleClass('fa-chevron-down fa-chevron-up');
    var content = this.nextElementSibling;
    //console.log(content);
    
    if (content.style.height === "auto") {
      content.style.height = "75px";
    } 
    else {
      content.style.height = "auto";
    }
    //});
  }
}
if (row.description.length > 50) {
  return "<div width='100%' style='min-height:100px;" + backgrnd + "'><button type='button' class='dropdown' onclick='dropdownbuttonclick(this)'><i class='fa fa-solid fa-chevron-down'></i></button><div class='content' style='margin:20px;'>" + title + "</div></div>";
}

I have tried to change the onclick event but I am not sure how to fix.

3

Answers


  1. The issue in your code is because this will refer to the window as the function was invoked via a onclick attribute.

    As you’re gone to the effort of including jQuery in the page, you should use that to attach your event handlers unobtrusively, and also to set the classes on the elements.

    In addition, it’s better practice to use CSS to update the UI, so simlpy toggling a class to set the height of the element would be a better approach. Try this:

    jQuery($ => {
      $(document).on('click', '.dropdown', e => {
        const $dd = $(e.currentTarget);
        $dd.find('i').toggleClass('fa-chevron-down fa-chevron-up');    
        $dd.siblings('.content').toggleClass('large');
      }); 
    });
    .container {
      min-height: 100px;
    }
    
    .content { 
      margin: 20px;
      height: auto;
      border: 1px solid #C00; /* only for this demo to show the height change */
    }
    
    .content.large {
      height: 75px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <div class="container">
      <button type="button" class="dropdown">
        <i class="fa fa-solid fa-chevron-down"></i>
      </button>
      <div class="content">Title</div>
    </div>

    Finally, note that any CSS/styling should be placed in an external stylesheet, not in the HTML.

    Login or Signup to reply.
  2. I’m guessing with the first click it adds both classes (fa-chevron-down and fa-chevron-up) and the second, takes both classes out. Try separating them:

    $(this.firstChild).toggleClass('fa-chevron-down');
    $(this.firstChild).toggleClass('fa-chevron-up');
    

    Hope this helps !

    Login or Signup to reply.
  3. You could solve the issue by replacing this with the element that the function takes as argument. Furthermore you should use firstElementChild instead of firstChild.

    Working example:

    (i simplified your example a bit)

    function dropdownbuttonclick(element) {
      let coll = $(".dropdown");
      
      $(element.firstElementChild).toggleClass('fa-chevron-down fa-chevron-up');
      var content = element.nextElementSibling;
    
      if (content.style.height === "auto") {
        content.style.height = "75px";
      } 
      else {
        content.style.height = "auto";
      }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" />
    
    <div class="dropdown">
      <div width='100%' style='min-height:100px;'>
        <button 
          type='button' 
          class='dropdown' 
          onclick='dropdownbuttonclick(this)'
        >
          <i class='fa fa-solid fa-chevron-down'></i>
        </button>
    
        <div class='content' style='margin:20px;'>Content</div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search