How do I preserve the `this` from a previous JS st

2019-08-30 04:04发布

So I have a view that has a simple_form, which looks like this:

<%= simple_form_for([node, Comment.new], html: { id: "new_comment_card-#{@card_number}"}, remote: true) do |f| %>
        <%= f.error_notification %>
        <%= f.input_field :message, as: :text, id: "card-input-field-#{@card_number}", class: "input-field", placeholder: "Share your thoughts", cols: "30", rows: "10" %>
        <%= f.button :submit %>
<% end %>

This form appears multiple times on the same view, hence the dynamic id specified.

When that button is pressed, some JS intercepts the submit like so (to ensure the submit sends the right credentials for the right form):

  $(".input-submit").click(function(event) {
      event.preventDefault();
      $(this).closest('form').submit();
  });

Otherwise sometimes the last rendered form would get submitted and that leads to all manner of issues.

When that is submitted, eventually it leads to CommentsController#Create which looks like this:

  def create
    @node = Node.find(params[:node_id])
    @comment = current_user.comments.new(comment_params)
    @comment.node = @node

    respond_to do |format|
      if @comment.save and @node.save
        format.html
        format.js
      else
        format.html
        format.js
      end
    end
  end

That then looks for and executes - create.js.erb. I want my create.js.erb to do 3 things:

  1. Add the newly saved comment to the top of the current div#id=card-comments, perhaps with a little animation to show the new comment.
  2. Push the other list of existing comments down to make way for the newly created comment from Step 1.
  3. Remove the text from the input field, so the user can add another comment without refreshing, perhaps with a little jiggle/highlight/animation.

I am not sure how to achieve this - JS is not my strong suit.

I tried doing this in my create.js.erb, but I have all sorts of weird behavior including duplicating the entire content of the comments on 1 card to the comments on another card:

$('#card-comments').append("<%= j (render partial: 'nodes/comment', collection: @node.comments) %>");

How do I achieve the above?

1条回答
乱世女痞
2楼-- · 2019-08-30 04:24

If the user can submit comments on multiple cards on the page, it should submit a parameter to the controller indicating which card the comment was submitted on and the JS should replace the comments of that specific card. Currently your jQuery selector is on #card-comments which doesn't match a specific card. Perhaps place the comments in a div with a specific ID similar to the form and replace all the comments of that div:

$('#card-<%= params[:node_id] %>-comments').html("<%= j (render partial: 'nodes/comment', collection: @node.comments) %>");
查看更多
登录 后发表回答