javascriptjquerytogglefacebook-comments

jQuery: Avoid assigning different ids to toggle a repeated element


Using SCSS as the CSS preprocessor and jQuery I have the comment section obtained with the code below. I would that .comment-box would only show up for its respective reply button, i.e. below the one that was clicked, instead of showing below all the existent .reply-btn. I'd like to avoid having to write individual #id for each comment box...

How could this be done? I tried to use

$("<div class='comment-box'/>")

in the jQuery code but it didn't work out =(

Thanks in advance for your help!

P.S.: Here's my CodePen in case you find it easier https://codepen.io/fergos2/pen/BaaqVOv

$(document).ready(function() {
  
  // showing the comment section
  $('.comment-btn').click(function() {
    $('.comment-btn').toggleClass('active');
    $('.comments-container').toggleClass('active');
  });
  
  // showing the comment box within comments
  $('.reply-btn').click(function() {
    $('.reply-btn').toggleClass('active');
    $('.comment-box').toggleClass('active');
  });
});
body {
  background-color: #BFF5FF;
  margin: 0;
  padding: 40px;
}

.main-container {
  width: 50vw;
  margin: 0 auto;
}

.post-container {
  background-color: white;
  border: 1px solid darkgrey;
  padding: 20px 20px 0 20px;
}

.comment-btn {
    text-decoration: none;
    padding: 10px;
    display: flex;
    justify-content: flex-end;
    
    > i {
      color: #03CCF2;
    }
  }

.comment-btn.active {
  > i {
    color: #D95FA4;
  }
}

.comments-container {
  display: none;
  
  .comment {
    background-color: white;
    padding: 10px;
    opacity: .8;
    border-radius: 100px;
    overflow-wrap: break-word;
    margin-block-start: 10px;
  }
  
  .comment-reply {
    margin-left: 50px;
  }
  
  .reply-btn {
    font-size: 10px;
    color: blue;
    text-decoration: none;
    
    &--comment {
      padding-left: 10px;
    }
    
    &--reply {
      padding-left: 60px;
    }
  }
  
  .reply-btn.active {
    color: #D95FA4;
  }
}

.comments-container.active {
  display: block;
}

.comment-box-main, 
.comment-box {  
  form {
    input {
      margin-top: 10px;
      outline: none;
      border: 1px solid black;
      border-radius: 100px;
      width: 100%;
      padding: 10px 0;
      padding-left: 10px;
    }
  }
}

.comment-box {
  display: none;
}

.comment-box.active {
  display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<div class="main-container">
  <div class="post-container">
  Lorem ipsum dolor sit amet consectetur adipisicing elit. Explicabo rem consectetur, delectus distinctio similique est saepe, maxime veniam culpa eius aliquid iusto voluptas dolore soluta libero, repudiandae harum natus a.
  <a href="#" class="comment-btn"><i class="fa fa-comment"></i></a>
</div>

  <div class="comments-container">
    <div class="comment-list">
     <div class="comment">Lorem ipsum dolor sit amet consectetur adipisicing elit. 
  </div>
  <a href="#" class="reply-btn reply-btn--comment">Reply</a>
  <div class="comment-box">
    <form>
      <input type="text" placeholder="Write a reply...">
    </form>
  </div>
  <div class="comment comment-reply">Some reply</div>
  <a href="#" class="reply-btn reply-btn--reply">Reply</a>
  <div class="comment-box">
    <form>
      <input type="text" placeholder="Write a reply...">
    </form>
  </div>
  <div class="comment comment-reply">Some reply</div>
  <a href="#" class="reply-btn reply-btn--reply">Reply</a>
  <div class="comment-box">
    <form>
      <input type="text" placeholder="Write a reply...">
    </form>
  </div>
  
  <div class="comment">Lorem ipsum dolor sit amet consectetur adipisicing elit. 
  </div>
  <a href="#" class="reply-btn reply-btn--comment">Reply</a>
  <div class="comment-box">
    <form>
      <input type="text" placeholder="Write a reply...">
    </form>
  </div>
  <div class="comment">Lorem ipsum dolor sit amet consectetur adipisicing elit. 
  </div>
  <a href="#" class="reply-btn reply-btn--comment">Reply</a>
  <div class="comment-box">
    <form>
      <input type="text" placeholder="Write a reply...">
    </form>
  </div>
  </div>
    <div class="comment-box-main">
      <form>
        <input placeholder="Write a comment..."></input>
      </form>
    </div>
  </div>
  
</div>


Solution

  • Working on a given code and HTML Structure you might try that:

    // showing the comment box within comments
    $('.reply-btn').click(function(e) {
        $(e.target).toggleClass("active");
        $(e.target).next().toggleClass("active");
    });
    

    It uses the fact that your "reply button" triggers an event from which you can read which "reply" button exactly was clicked (e.target). Then you switch the class of that element and the one next to it (the reply section).