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:
- 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. - Push the other list of existing comments down to make way for the newly created comment from Step 1.
- 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?
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: