advice
advice

Reputation: 5988

Ruby on Rails - Edit/Update Content on Show layout

I'm trying to find out how to implement a system that allows me to update certain fields without navigating away from the current page, and without reloading it.

I've seen this on a lot of websites, including editing comments on StackOverflow.

Example:

You wrote and posted a Comment. While looking at all the posted Comments, there is a 'Edit' button that changes that Comment back into a text_area in place, allowing you to update the text, and a button to save it. Then the updated Comment looks correct, and you didn't need to navigate or refresh.

I believe what they're doing is:

  1. When you click the 'Edit' button, Javascript is generating/displaying a hidden layout with the text_area.
  2. Clicking 'Save' will send a request off in the background, without refreshing the screen.
  3. Javascript will take the updated text and copy it into the old layout, and display that.

Is there any good examples of how to implement this? I'm not even sure what terminology is used for this kind of updating.

Thanks for your help.

Upvotes: 0

Views: 1549

Answers (1)

rob
rob

Reputation: 2296

There exist many examples to reach your goal.

Give me a try to give you a simple example for a better understanding.

Let's say you have a Post model

class Post
end

Your index page like the following (in controller index @posts = Post.all

<% #app/views/posts/index.html.erb %>
<div id="posts">
  <%= render @posts %>
</div>

The post object partial:

<% #app/views/posts/_post.html.erb %>
<div id="<%= dom_id(post)%>">
  <%= post.title %>
</div>

And update your form_for tags with the remote attribute

form_for @post, remote: true

Now your create could add the current post to the div#posts or replace the entire div.

<% #app/views/posts/create.js.erb %>
$("#posts").append('<%=j(render @post)%>') 

Your update could update one entry by replacing the div with the dom_id() for the updated post.

<% #app/views/posts/update.js.erb %>
$("#posts ##{dom_id(@post)}").html('<%=j(render @post)%>') 

That's all.

Upvotes: 2

Related Questions