How to use Stimulus in your Rails App

Tejasvi Raut
Engineering at Classpro
3 min readNov 12, 2018

--

Stimulus binds events to the HTML elements just by specifying attributes in the HTML elements. The stimulus has helped me to build cleaner and reusable code.

Consider building a rails app, you have to filter data on different index pages all over your app. To do so you have to bind DOM elements to your javascript events and write javascript functions for each index page. The conventional way would be to create index.js and write javascript functions for each index page. While the functional logic remains same in all index.js files. That leads to redundant code.

To reuse code and easily bind elements we can use Stimulus. To integrate Stimulus with or without web packer use this link.

Stimulus is a small framework revolving around just three main concepts: Controllers, actions, and targets.

Controllers: Stimulus’ purpose is to connect DOM elements to JavaScript objects. Those objects are called controllers.

Actions: The action which is to be performed on some event triggered.

Targets: DOM Element on which the change is to be reflected. The change can be in its attribute or value, we can access these target elements in our controller.

Let's start with our search filter example, we will first create a filter controller under app/javascripts/controllers/filters_controller.js:

import { Controller } from "stimulus";
import _ from "lodash";
export default class extends Controller {
static targets = ["submit"];
debouncedSubmit = _.debounce(this.submit, 500); submit() {
this.submitTarget.click();
}
onSearchKeyup() {
this.debouncedSubmit();
}
}

Well, this is a hell lot of code here. We will understand it in chunks later. First, let’s check how will we connect this to our DOM element.

It is as simple as adding data-controller attribute with the value of our controller name that is “filters” in our case. We have connected our controller to our filter form element, you can check the following snippet.

= form_with( url: students_path, method: 'get', data: { controller: 'filters' }) do |form|  = form.text_field :search, placeholder: 'Search', data: { action: 'keyup->filters#onSearchKeyup' }  = form.submit 'Search', name: nil, class: 'd-none', data: { target: 'filters.submit' }

As we have connected our controller to our DOM element we are ready to go.

Now we have to add an action on which we want our filter to work. We may trigger it on key press (Enter key: using code 13) or on key up. Here I have demonstrated it on key up. We have to set data-action attribute with setting its value to “action->controller-name#invoking-function” on our search text-field as demonstrated in above snippet. This will trigger the onSearchKeyup() on every key up.

In our onSearchKeyup() we have called debouncedSubmit() which in return submits after every 500ms. I have used Lodash debounce method that delays invoking function until after wait milliseconds have elapsed since the last time the debounced function was invoked.

The submit() which is passed as an argument to debounce function triggers the click event of our submit button of the filter form which is our submit target. We set it by setting data-target attribute to “controller-name.target-name”. You need to include index.js in which you need to update the list.

Stimulus helps the code to be reusable and maintainable. We can connect this controller to all search fields in our rails app.

--

--