Skip to content →

Stimulus.js Tutorial: How Do I Remotely Update My Model from a checkbox?

First, I’m going to assume you’ve read the Stimulus handbook, cover to cover, like I have.

Let’s say you have a Todo app, with a model Todo that has a string title, and a boolean field, completed. We are going to use Stimulus to update our model remotely on the server, when we check off the todo. And we’re going to use a nifty javascript API called fetch() to make it all happen.

So, in our Todos Controller, we’ll pull out all of our Todo records:

class TodosController < ApplicationController 
  def index
     @todos = Todo.all
  end
end
And in index.html.erb, we’ll display the Todos, and put in the decorations that Stimulus will use:
<table>
  <% @todos.each do |todo| %>
    <tr data-controller="todo" 
          data-todo-update-url="<%= todo_path(todo) %>">
      <td>
        <input type="checkbox" 
                    data-action="todo#toggle" 
                    data-target="todo.completed" 
                    <% if todo.completed %> checked <% end %> >
        <%= todo.title %>
      </td>
    </tr>
  <% end %>
</table>
Now, let’s create our todo_controller.js and add the toggle method we specified above:
import { Controller } from "stimulus"
export default class extends Controller {
    static targets = [ "completed" ]
    toggle(event) {
        // Code to follow
    }
}
Inside the toggle(event) function, let’s start by getting the value of the checkbox, and put it into a FormData object:
let formData = new FormData()
formData.append("todo[completed]", this.completedTarget.checked);
Let’s post that data to the "update-url" value we set on the Todo row. We’ll set the method to PATCH so that it gets routed to our todo#update on our controller. The credentials and headers included ensure we send the session cookie and the CSRF protection token and prevent an ActionController::InvalidAuthenticityToken error.
fetch(this.data.get("update-url"), {
      body: formData,
      method: 'PATCH',
      dataType: 'script',
      credentials: "include",
      headers: {
              "X-CSRF-Token": getMetaValue("csrf-token")
       },
})
We can take the Response object and verify that our request was successful. If there was an error, we’ll revert the checkbox change.
.then(function(response) {
    if (response.status != 204) {
        event.target.checked = !event.target.checked 
    }
})
Now, let’s go back to our ruby controller, and add our update method:
def update
  @todo = Todo.find_by_id params[:id]
  @todo.update todo_params
  @todo.save
  respond_to do |format|
    format.js
  end
end

private 

def todo_params
  params.require(:todo).permit(:title, :completed)
end
Now when we check or uncheck one of the check boxes, an AJAX request is sent to our Rails app, and stimulus handles the response.

Comments or Questions? Find me on twitter @jpbeatty

Want To Learn More?

Try out some more of my Stimulus.js Tutorials.

Excited for Stimulus?

Drop your email below, and you won’t miss the next Stimulus Tutorial


Published in ruby on rails Stimulus JS

One Comment

  1. […] Now we have some slick interactivity on our web page. Depending on where this fits into your app, you’ll want to also save the changes, but I think that depends on what your editing. Here’s a tutorial that you could work from to remotely save the changes, also using stimulus. […]

Comments are closed, but trackbacks and pingbacks are open.