We’re building an app that requires users to input a regex. We’d like to build a feature that gives users the ability to test their regex, before saving. The feature will work a lot like Rubular. Users will be able to test their regex against various strings.
This post explains how to build the feature using Stimulus, within a Rails 7 application.
1. Generating a view/controller
First we’ll create a new view/controller, to serve the HTML form. We can use the Rails CLI to generate it:
rails g controller admin index
2. Adding a basic form
The HTML form code can be added to the newly generated view template, app/views/admin/index.html.erb
:
1
2
3
4
5
6
7
8
9
<h1>Regex tester</h1>
<div>
Regex: <input type="text">
<br />
Example: <input type="text">
<br />
<button>Test regex</button>
</div>
For this tutorial, the form will be very simple. It will comprise of a regex input field, an example string input field and a button to trigger the test process.
3. Adding a Stimulus controller
When the user clicks the button it should trigger some JavaScript. This will be handled by a Stimulus controller. We can create a file under app/javascript/controllers/admin_controller.js
and add the Stimulus controller boilerplate:
1
2
3
4
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
}
This logic imports the framework’s built-in Controller
class and extend it. This is where the custom JavaScript code can be added.
4. Connecting the form to the Stimulus controller
Right now there is no connection between the form and the Stimulus controller. To connect them, we can add a data-controller
attribute to the outer div:
1
<div data-controller="admin">
The Stimulus controller is called admin_controller.js
so the data-controller
value must be "admin"
.
5. Adding targets to fields
Stimulus allows us to add ‘targets’ to fields that we want to reference in the controller. This makes referencing fields easier, as opposed to manually searching the DOM.
We’ll add a target for both the regex field and example string field:
1
2
3
4
5
6
7
8
9
<h1>Regex tester</h1>
<div data-controller="admin">
Regex: <input data-admin-target="regex" type="text">
<br />
Example: <input data-admin-target="exampleString" type="test">
<br />
<button>Test regex</button>
</div>
Because the controller is admin_controller.js
the attribute name must be data-admin-target
. The attribute value dictates how these targets are referenced in the controller. We’ll use regex
as the value for the first and exampleString
as the value for the second.
6 Adding targets to the Stimulus controller
To use targets within the Stimulus controller we must define a targets
var:
1
2
3
export default class extends Controller {
static targets = [ "regex", "exampleString" ]
}
This allows targets to be accessed via this.regexTarget
and this.exampleStringTarget
.
7. Adding a data action
The last step is to get the form button working. That requires a data-action
attribute:
1
<button data-action="admin#test">Test regex</button>
We’ll set the value of data-action
to "admin#test"
which will invoke a function called test
, in the Stimulus controller.
8. Testing with an alert
The final piece of the puzzle is to write the test
function, in the Stimulus controller. For now, the function will just call alert()
:
1
2
3
test() {
alert('hello!')
}
At this point, we can test in the browser. When the button is clicked it will trigger a browser alert. This verifies that Stimulus is wired up correctly
9. Adding regex logic
Now it’s time to add the regex testing logic. We can use JavaScript’s RegExp.prototype.test()
to run the test. We can access the regex and test string using their targets:
1
2
3
4
5
test() {
const regex = new RegExp(this.regexTarget.value);
alert(regex.test(this.exampleStringTarget.value))
}
This logic will alert with true
or false
depending on whether the regex matches.
10. Adding field color validation
The last thing we need to do is update the function to set the field color based on the outcome of the regex test. We can create a conditional based on the outcome of RegExp.prototype.test()
and use that to set the borderColor
.
1
2
3
4
5
6
test() {
const regex = new RegExp(this.regexTarget.value);
const regexTestColor = regex.test(this.exampleStringTarget.value) ? "green" : "red"
this.exampleStringTarget.style.borderColor = regexTestColor
}
That’s it! The feature is working and can be tested in the browser. The regex test feature now sets the border red/green depending on whether the test passes or fails.