#859·stimulus

Feature request: data-[identifier]-model to implement equivalent of Vue's v-model

Author: christophehenryCreated Sep 17, 2025Updated Sep 17, 2025

So this is a pattern I frenquently come accross when using Stimulus on forms: reacting to <input>'s value change like displaying parts of a form according to a checkbox. Currently, the way I implement it is like this:

xml
<input type="checkbox" data-action="[identifier]#OnChange" />
<fieldset data-[identfier]-target="fieldset"></fieldset>
javascript
import {Controller} from "Stimulus";

class FormController extends Controller {
    static targets = ["fieldset"]

    onChange({target: {checked}}) {
        if(checked) { this.fieldsetTarget.setAttribute("hidden", "hidden"); }
        else { this.fieldsetTarget.removeAttribute("hidden", "hidden"); }
    }
}

However, since events are only fired on user interactions, this forces us to add some boilerplate to get the correct display upon init:

xml
<input data-[identfier]-target="checkbox" type="checkbox" data-action="[identifier]#OnChange" />
<fieldset data-[identfier]-target="fieldset"></fieldset>
javascript
import {Controller} from "Stimulus";

class FormController extends Controller {
    static targets = ["fieldset", "checkbox"]

    onChange({target: {checked}}) {
        this.mutateFieldsetVisibility(checked)
    }

    checkboxTargetConnected(el) {
        this.mutateFieldsetVisibility(el.checked);
    }

    mutateFieldsetVisibility(visible) {
        if(checked) { this.fieldsetTarget.setAttribute("hidden", "hidden"); }
        else { this.fieldsetTarget.removeAttribute("hidden", "hidden"); }
    }
}

Just to get the correct init, we need to declare a target on the input that will only be used once in the controller's lifetime.

What I propose propose to add a new data-[identifier]-model that would work exactly like Vue's v-model:

xml
<input data-[identfier]-model="checkbox" type="checkbox" />
<fieldset data-[identfier]-target="fieldset"></fieldset>
javascript
import {Controller} from "Stimulus";

class FormController extends Controller {
    static targets = ["fieldset"]
    static models = ["checkbox"]

    checkboxModelChange(value) {
        // or can be accessed through `this.checkboxModel`
        if(value) { this.fieldsetTarget.setAttribute("hidden", "hidden"); }
        else { this.fieldsetTarget.removeAttribute("hidden", "hidden"); }
    }
}

If this is too inconvenient to implement, can you indicate me how to leverage Stimulus' API to implement it as an extension similar to stimulus-use? This would require dynamic target and value binding and I don't believe this can be done after controller's initialize() lifecycle phase, can it?