msmith1114
msmith1114

Reputation: 3231

Rails update element based on AJAX request?

I've been reading a lot about Rails and AJAX and 5.1 Unobtrusive javascript. It explains a lot about responding to Rails version of AJAX calls with a .js file for example.

However what im wanting to do isn't serving up an entire .js file, it's simply updating an element after a <% link_to %> POST request. From my understanding setting remote: true submits it as a AJAX request.

Essentially I have a "Post" which a user can like via a linked Like button. This sends a POST request to the "Post" controller which updates a post to liked and adds a like to the post.

Unfortunately to see the effects of the post being liked (Which is simply that the link changes color as well as the font-awesome icon) you need to refresh the page. I basically want it to update without needing refresh.

I "think" based off what i've read I need to make a respond do and respond via .js to the request with a .js file in the view I want to update (for instance if the controller action is called "like", maybe a like.js.erb file in the view im updating?). But I don't want to serve an entire new page..or would this simply just run the .js?

Then I could do something like $('i.fa-icon#id').style.color = "blue" or something? (Im assuming I can send data from the controller to the .js.erb file?). Not sure the best way to do this, don't rails elements a lot of times have some sort of data-attribute or something (Im still a beginner at this).

Upvotes: 1

Views: 2556

Answers (2)

Nader-a
Nader-a

Reputation: 123

Not sure if I understand the question, but if you want to update like button:

What you want to do is to add an event listener to the button, and when clicked it makes a POST request to whatever route handles the likes(with the correct parameters) and your controller should respond with the like object (or whatever in the database gets stored). Have your post request on success method to grab the like button and change it to whatever you want it to look like

$(“#like-btn”).click(function(){ 
Rails.ajax({
  url: "/some/url/to/like/controller",
  type: "post",
 data: [your post data],
  success: function(data) { $(`#${ data[“btn-name”] }`).attr(“color”, “blue”; }
})    
}

You can stick this script right in the bottom of the html page

You don’t have to do it exactly like this, just giving you an idea of how to set up the pattern of having JavaScript and Ajax handle the post request and updating of the frontend instead of using html buttons

Upvotes: 2

Clara
Clara

Reputation: 2715

Your description is quite correct! Opposed to the other answer, you don't even need a event listener but as you said you want to have a respond_to in the controller. So starting from the html:

# post/index.html.erb
<div id="like-button">
  <%= button_to "Like this post", post_path(@post), remote: true %>
</div>

Note, that when you use a button_to helper it'll be a POST request by default.

If you click it, it'll go to the controller#update, which you want to change to this:

#posts_controller.rb
...
def update
  @post.save
    respond_to do |format|
      format.html { redirect_to post_path(@post) } 
      format.js  # <-- will render `app/views/posts/update.js.erb`
    end
end

Note: the format.html is rendered when JS is disabled. Now in the scenario that JS is enabled, it executes the app/views/posts/update.js.erb file. It can look like this:

const likeButton = document.getElementById('like-button');
likeButton.innerHTML = '<%= j render "posts/liked-link", post: @post %>';

What is the last line doing? Of course, you can change the style directly with the JavaScript, but you can also render a new partial - and this you will create in a new html file:

# app/views/posts/liked_link.html.erb
<div id="like-button ">
 <p>"You liked this post!" </p>
</div>

I just changed the link/button to ap now, but of course you can do whatever you want.

Hope that makes sense :)

Upvotes: 4

Related Questions