So I have a view that has renders HTML that looks like this :
What is happening now is when the user adds a new comment, it is now added to the top of that list, i.e. the div.social-comment
that is highlighted. However, I want it to be added after the last in the list, not as the first. How do I do that?
This is what the create.js.erb
looks like:
$(".question-<%= @comment.commentable.id %>").prepend("<%= j (render partial: 'comments/comment', locals: { comment: @comment}) %>");
How can I achieve what I want?
Edit 1
My bad, I wasn't fully clear with the original question.
I can't just use .append
, due to the presence of a form field that is currently at the bottom of that list of children.
If I do use append, this is what the modified HTML looks like:
Note the .row .question-46-new
appears before the last .social-comment
.
So that ends up producing this:
Which is obviously what I don't want.
What I want is for the new comment to appear right above that Write Comment
textbox, and at the end of the list of existing comments.
Edit 2
This is what my DOM tree looks like after attempting Pranav's suggestion:
Edit 3
After the latest attempt from Pranav, these are the results.
I tried this:
$(".question-<%= @comment.commentable.id %>").children(".social-comment").last().after("<%= j (render partial: 'comments/comment', locals: { comment: @comment}) %>");
That works well when there are existing comments, it just adds it to the last of the existing ones. When there are no existing comments though, the new comment just disappears.
Here is a picture of the DOM tree when there are no comments:
Here is a picture of the DOM tree after the comment has been added, using the above .js.erb
:
No change. For what it's worth, I also tried it with the other suggestion:
$(".question-<%= @comment.commentable.id %> > .social-comment:last").after("<%= j (render partial: 'comments/comment', locals: { comment: @comment}) %>");
And I get similar behavior. It works when there are existing comments, but doesn't work when there are none.
Edit 4
When I use the :before
suggestion from Pranav, this is the result.
This is what my comment section looks like when I add one comment, when there was none before (notice the spacing is off and the alignment with the other DOM elements looks weird):
Then this is what it looks like when there is an existing comment (notice how weird the alignment looks):
But if I refresh, this is what it looks like (which is how it should look, but just not how it looks immediately after the comment is added):
Use append()
instead of prepend()
method.
$(".question-<%= @comment.commentable.id %>").append("<%= j (render partial: 'comments/comment', locals: { comment: @comment}) %>");
Since you are updated the question, you can't do it using above code. Instead what you can do is get the last social-comment
element inside the div and then append it after the element. You can use :last
to get the last one and after()
method to append after the last element.
$(".question-<%= @comment.commentable.id %> .social-comment:last").after("<%= j (render partial: 'comments/comment', locals: { comment: @comment}) %>");
UPDATE 2:
Since there is nested div with same class you need to get only direct children instead. So either use child selector (>
)
$(".question-<%= @comment.commentable.id %> > .social-comment:last").after("<%= j (render partial: 'comments/comment', locals: { comment: @comment}) %>");
or use children()
and last()
.
$(".question-<%= @comment.commentable.id %>").children(".social-comment").last().after("<%= j (render partial: 'comments/comment', locals: { comment: @comment}) %>");
Also if the last div's class is always in format like parent id
followed by -new
(eg: question-36
and question-36-new
) then you can done it using before()
method.
$(".question-<%= @comment.commentable.id %>-new").before("<%= j (render partial: 'comments/comment', locals: { comment: @comment}) %>");