Reputation: 2474
I'm creating a model to show user's following and follower list just like Instagram:
My controller:
def create
@relationship = current_user.active_relationships.new followed_id: @user.id
if @relationship.save
byebug
respond_to :js
else
error_handle
end
end
The follow/unfollow button is a remote (ajax) form. So after it's processed, it go to create.js.erb:
$(".relationship-form").on("ajax:success", function(e, data, status, xhr) {
$(this).replaceWith(
'<%= link_to "Unfollow", relationship_path(@relationship), method: :delete, data: {disable_with: "Loading ..."}, remote: true, class: "btn btn-outline-dark common-btn btn-unfollow relationship-form" %>'
)
});
My destroy.js.erb:
$(".relationship-form").on("ajax:success", function(e, data, status, xhr) {
$(this).replaceWith(
'<%= link_to "Follow", user_relationships_path(@other_user), method: :post, data: {disable_with: "Loading ..."}, remote: true, class: "btn btn-primary common-btn btn-follow relationship-form" %>'
)
});
When I click follow user A
button the first time, it run 1 time.
The problem its that if I click the follow button a second time on user B
, it run js for the last user A
and then run js for user B
(2 times). If I follow user C
, it return for user A
, user B
and user C
and so on...
This is my button form:
<% if is_following.present? %>
<%= link_to "Unfollow", relationship_path(is_following), method: :delete, data: {disable_with: "Loading ..."},
remote: true, class: "btn btn-outline-dark common-btn btn-unfollow relationship-form" %>
<% else %>
<%= link_to "Follow", user_relationships_path(user), method: :post, data: {disable_with: "Loading ..."},
remote: true, class: "btn btn-primary common-btn btn-follow relationship-form" %>
<% end %>
Would be so nice if I could get the "clicked" element, because I can't think a way to name a unique ID for each follow and unfollow state.
Upvotes: 0
Views: 751
Reputation: 2474
Turn out that I just solve it myself. Just a bit silly and dirty way.
So after controller process done, it went to js.erb file and print the result into a "display: none" div:
$("#relationship-result").html(
'<%= link_to "Unfollow", relationship_path(@relationship), method: :delete, data: {disable_with: "Loading ..."}, remote: true, class: "btn btn-outline-dark common-btn btn-unfollow relationship-form" %>'
)
Then in application.js
, we listen for event ajax:success
on buttons we want. So by using this way, we don't get duplicate event listening, thanks @xploshioOn. Then grab the data and replace:
$(document).on("ajax:success", ".relationship-form", function(e, data, status, xhr) {
$(this).replaceWith($("#relationship-result").html());
})
Notice that I use document
because I replace some DOM here. So a little bit trick and dirty but works :v
Upvotes: 0