Leveraging Hotwire for Dynamic Input Field Label Pluralization

Dynamic Label Updates in Rails with Stimulus and Hotwire

I encountered an issue while working on a dynamic input field. The field allows users to input a number, with accompanying text indicating the type of input, like “nights.” It seemed straightforward until I realized the hardcoded label “nights” doesn’t work when the user enters the number 1. To address this, I needed a way to dynamically adjust the label based on the user’s input. I chose to use Stimulus since I was using a Ruby on Rails app and Stimulus integrates nicely. Here is an image of what I would like to happen:

Setting Up the Stimulus Controller

First, I created a Stimulus controller named number_input_controller. This controller includes two static values (singular and plural) and one static target (numberText):

static values = {
 singular: { type: String, default: '' },
 plural: { type: String, default: '' },
}
static targets = ['numberText']

To link the controller to the partial containing the input field, I added the data-controller attribute to the parent div:

<div data-controller="number-input">
 <!-- Input field and text go here -->
</div>

The numberText target corresponds to the text (“night” in this case, see first screenshot above) displayed next to the input field. To assign it as a target, I wrapped the text in a div with this attribute. It looks something like this:

<div data-number-input-target="numberText"><%= text %></div>

Now that we have our target set we can move on to the values we set in the controller.

Stimulus “values” lets you pass data to your JavaScript controller through HTML attributes and automatically keeps everything in sync, like magic.

I want to pass information to my controller, specifically the plural and singular values of night. I want to do this because depending on the value the user inputs, I want to render one or the other.

Stimulus automatically creates properties to get and set these values, so you can do things like reading the singular or plural (this.singularValue or this.pluralValue), changing it, or checking if it exists (this.hasSingularValue or this.hasPluralValue).

Plus, it watches for changes in these values for you, so if the HTML attribute changes, your controller can react by defining a special method named singularValueChanged().

So, “values” are just a neat way to put data into the controller and keep everything in sync, allowing your webpage to behave smoothly.

If you want to read more, you can check out the Stimulus handbook here.

Setting Singular and Plural Values

Next, I defined the singular and plural values that the controller will use to update the target dynamically. These values are set like this:

# For example, if the text is "night":
data-number-input-singular-value="<%= text %>"
data-number-input-plural-value="<%= text.pluralize %>"

Here, <%= text %> is the singular form, and <%= text.pluralize %> generates the plural form.

Adding the Input Field

The next step is to ensure that the label updates when the input field is interacted with. To do this, I attached an action to the input field. The input fields we are using are a bit complex so instead I will show a generic example:

<input data-action="number-input#updateNumberText" />

This action triggers the updateNumberText method in the Stimulus controller whenever the user interacts with the input field.

Here’s the updateNumberText method in the Stimulus controller:

updateNumberText(event) {
 this.numberTextTarget.textContent =
   event.target.value == 1 ? this.singularValue : this.pluralValue
}

This method checks the input field’s value and updates the text accordingly:

  • If the value is 1, it uses the singularValue (e.g., “night”).
  • For all other values, it uses the pluralValue (e.g., “nights”).

The textContent of the numberTextTarget is dynamically updated to reflect the appropriate label.

Summary

When a user interacts with the input field:

  1. The controller receives the input value.
  2. Based on the value (1 or otherwise), the numberTextTarget is updated with either the singular or plural form.
  3. The displayed text next to the input field changes dynamically, ensuring grammatical accuracy.

This setup allows for clean, reusable code that can handle any singular/plural text dynamically. 🎉

If you’re looking for a team to help you discover the right thing to build and help you build it, get in touch.

Published on September 11, 2025