How do I specify a specific form in Rails 3.2 with UJS when multiple forms are on the page?

StackOverflow https://stackoverflow.com/questions/20672711

  •  19-09-2022
  •  | 
  •  

Question

I have a partial containing many posts and many comments. I would like to update the page via UJS when a comment is added. However, right now when I submit a new comment it creates a number of extra div elements (based on how many comment forms are currently on the page). I'm new to UJS and not sure how to traverse the DOM so that I can prepend the comment to the form its submitted on. Below is my code, any help would be greatly appreciated. Note: this is a post partial that is rendered in a page with many posts, so there are multiple '.comment-form' classes on the DOM.

<article class="post speech-bubble-post">
  <header class="group">

    <div class="post-header-thumb">
      <a href="<%= user_url(post.user) %>">
        <img class="circular-thumb" src="<%= post.user.profile_photo(:thumb) %>" alt="">
      </a>
    </div>

    <div class="user-info">
      <div class="name">
        <%= post.user.full_name %>
      </div>
      <div class="role">
        <!-- user.role_in_course -->
      </div>
      <div class="post-time">
        posted <%= time_ago_in_words(post.created_at) %> ago
      </div>
    </div>
    <% if post.user == current_user || post.course.has_write_permission?(current_user) %>
      <div class="post-controls">
        <div class="post-edit">
          <%= link_to "Edit Post", edit_post_url(post) %>
        </div>
        <form class="post-delete" action="<%= post_url(post) %>" method="POST">
          <input
            type="hidden"
            name="authenticity_token"
            value="<%= form_authenticity_token %>">

          <input
            type="hidden"
            name="_method"
            value="DELETE">

          <input type="submit" value="Delete Post">
        </form>
      </div>
    <% end %>
  </header>

  <p class="post-content">
    <%= post.body %>
  </p>
</article>

<% post.comments.each do |comment| %>
  <div class="comment">
    <%= render comment %>
  </div>
<% end %>

<form 
  class="comment-form" 
  action="<%= post_comments_url(post) %>" 
  method="POST" 
  data-remote="true">

  <input
     name="authenticity_token"
     type="hidden"
     value="<%= form_authenticity_token %>">

  <label for="comment_body"></label>
  <textarea rows="1" cols="50" name="comment[body]" id="comment_body"></textarea>

  <input type="hidden" name="comment[post_id]" value="<%= post.id %>">

  <input type="submit" class="comment-submit-button" value="Comment">
</form>

<script>
$(document).ready(function(event) {

    $(".comment-form ").on("ajax:success", function(event, data){

      var $form = $(this)

      $form.prepend(data);
      $form[0].reset();
    });
});
</script>
Was it helpful?

Solution

You can do something like

<form id="post-<%= post.id %>" class="comment-form" ...>

or

<form data-post_id="post-<%= post.id %>" class="comment-form" ...>

And then pick that up with JS if you'd like.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top