Reputation: 3231
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
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
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