How do I preserve the `this` from a previous JS state and transfer it to another?

时间秒杀一切 提交于 2019-12-11 18:07:49

问题


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:


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) %>");


来源:https://stackoverflow.com/questions/31355648/how-do-i-preserve-the-this-from-a-previous-js-state-and-transfer-it-to-another

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!