0

I am building an app in ruby-sinatra that allows you to create posts and then reply to the post. I am trying to make the form for replying to a post appear when the user clicks Reply. However currently my code is only working for the first message div being rendered. All the others have the button to make the form appear but they dont work.

here is my .erb

<div class="message-link more ">
  <div class="comment-square">
    <% message.comments.each do |comment| %>

      <% comment.users.each do |user| %>
      <div><h5><%= user.username %></h5></div>
 
      <% end %>

      <script type="text/javascript">     
        $("#button").click(function() {
        $("#fn").show();
        $("#ln").show();
      });
      </script>
                    
      <p class="comment-text"><%= comment.text %>
        <input id="button" type="button" value="Reply"><br>
      </p>
        <div id="fn" hidden><input type="text" /></div><br>

      <% end %>
    </div>
 </div>

can anyone spot why?

TheMayerof
  • 113
  • 2
  • 10

1 Answers1

1

You are referencing the button before it is rendered so it is not going to find it. Next issue is you have the code in a loop so you are generating a bunch of elements with the same id.

Instead use event delegation to catch the button clicks. You can than use it to find the element to show.

$(".message-link").on("click", "input.reply", function () {
  $(this).closest('.comment-square').find(".fn").toggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="message-link more ">
  <div class="comment-square">
    <div>
      <h5>XXX</h5>
    </div>
    <p class="comment-text">Foo Bar
      <input class="reply" type="button" value="Reply"><br>
    </p>
    <div class="fn" hidden><input type="text" /></div><br>
  </div>
  <div class="comment-square">
    <div>
      <h5>XXX</h5>
    </div>
    <p class="comment-text">Foo Bar
      <input class="reply" type="button" value="Reply"><br>
    </p>
    <div class="fn" hidden><input type="text" /></div><br>
  </div>  
</div>

The script should appear after the message-link div or be wrapped in document ready.

epascarello
  • 185,306
  • 18
  • 175
  • 214
  • I would use `$(document).on("click", ".message-link input.reply", function () {..})` instead to delegate the event from the document instead of attaching the handlers directly to the elements. – max Jan 07 '21 at 23:52
  • @max So it has to bubble more? Only reason to move it up if both the elements are dynamic. – epascarello Jan 08 '21 at 14:28
  • If ` – epascarello Jan 08 '21 at 14:31
  • Idempotency in itself is a nice thing and is a good future proofing. The cost of letting the event bubble is pretty trivial and you need to weight that against the cost of attaching a handler to each element if there are many elements. – max Jan 08 '21 at 14:34
  • Your opinion vs my opinion. Have a nice day. – epascarello Jan 08 '21 at 14:34