A few weeks ago, I started building this Rails app to help me become a better writer. It’s a simple app that is meant to motivate me to write every day by keeping track of streaks and awards points based on number of words written.
When I first began building the writing interface in the app, I wanted to make it easy to save my work, and decided that a Google docs style autosave feature would work well. With jQuery and AJAX, it’s really simple.
First, I have a view template for the writing page:
.saved
Saved
= @post_today.updated_at.strftime("%l:%M:%S%P")
%article.writing-area
%textarea.col-sm-6
= @post_today.content
This doesn’t actually use a full fledged form to update the model, since we’ll be saving the model in the background via AJAX. All it has is a text area that contains the post as it was last updated, so I can continue writing if I had already started the post.
In order to update the post in the background, I used a simple Javascript function to submit the contents of the textarea.
function autoSave() {
var content = $("textarea").val();
$.post('/update_post', {content: content})
}
setInterval(autoSave, 10000);
$.post is just a wrapper around jQuery’s $.ajax function that shortens the amount of code you have to write in order to send a post request.
The piece that’s really important is setInterval. It takes two arguments: a function, and time in milliseconds. In the above example, setInterval will run autoSave every ten seconds. Note that I don’t pass in autoSave with parentheses like you would when calling a regular function. This is because the function needs to be passed in as a piece of data to be used by setInterval. If I had passed in autoSave(), it would have returned the value of the function once and exited.
The request is sent with the parameters as a Javascript object, and gets sent to the controller just like any form submission would.
class PostsController < ApplicationController
def update
@post = current_user.posts.today
# If nothing has been written, don't update the model
return if params[:content].nil?
@post.update_attribute(:content, params[:content])
respond_to do |format|
format.js
end
end
end
When the post is saved, it renders Javascript back to the browser:
$(".saved").html("Saved <%= Time.now.strftime('%l:%M:%S%P') %>")
This notifies the user that their post saved by changing the time it was last updated:

There isn’t much to it, and it’s a really simple way to improve your user experience.