Skip to content

Conversation

@daz-codes
Copy link

@daz-codes daz-codes commented Jul 27, 2025

Summary

  • Added access to findElement and FindAllElements to the Controller class
  • These already existed in the Scope class, but can now be accessed directly inside the controller
  • Also added more functionality to the methods to allow finding by id and using Stimulus CSS classes

Motivation

This was motivated by being frustrated by having to use this.element.querySelector to get access to elements based on their class or id and also having to prepend . to classes and # to ids. Using document.getelementById also didn't feel right, especially since it wasn't scoped to the root element of the controller.

This PR attempts to make the code look much more 'Stimulus' in style when selecting elements

Usage

Given the following HTML:

<div data-controller="my-controller"
      data-my-controller-active-class="active"
      data-my-controller-loading-classes="busy loading"
    >
      <div id="inside">This is inside</div>
      <div class="busy loading">This is loading</div>
      <div class="active"><p class="intro">This is the intro</p></div>
    </div>
    <div id="outside" class="busy">This is outside</div>

Find Elements scoped inside the root element by passing the id:

this.findElement("inside") will return <div id="inside" class="busy loading">...</div>
this.findElement("outside") will return undefined since it doesn't match any element inside the controller

Find elements using defined classes:

this.getElement(this.activeClass) will return <div class="active">...</div>
this.getElement(this.loadingClasses) will return <div class="busy loading">...</div>

Find element using a standard query selector:

this.getElement(.active p.intro) will return <p class="intro">...</p>

The method looks for items with an id first, then looks to see if any classes have been defined on the controller and last of all falls back to using this.element.querySelector

this.findAllElements works in the same way, but returns an array of all matching elements. It does not look for elements with an id as there should only be one element with an id.

@daz-codes
Copy link
Author

@marcoroth have just squashed the commits. I noticed you ran the CI on this, would it be possible to run it again?

@leevigraham
Copy link

This seems like something that shouldn't be in core. Anything inside should probably be a target. Anything outside could be an outlet.

@daz-codes
Copy link
Author

This seems like something that shouldn't be in core. Anything inside should probably be a target. Anything outside could be an outlet.

We've definitely found times when this was needed and using target didn't work as well. And using document.querySelector just feels awkward and not very Stimulus in style.

It's probably irrelevant anyway since Stimulus seems dead as a project ...

@leevigraham
Copy link

An alternative for this implementation in user land could be a mixin or the ApplicationController pattern:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants