Skip to main content

SignalDOMChildrenController

Purpose

A controller that listens for changes to the elements that are children/contents/descendents of the element that it is mounted on, and emits a count of the number of elements that are in the child tree to any other Signal controllers that have subscribed by referencing the same nameValue as this controller.

The emitted value can then be used in expressions in other Signal* controllers to enable more complex interactions.

A common use case for this would be to use this controller in conjunction with the SignalVisibilityControllerto show a blank slate message like "You don't have any posts, create one now!" when there are no results on a page, and hide it again when items arrive. Particularly in contexts where contents of a container can arrive and be removed remotely VIA Server-Sent-Events, AJAX, TurboStreams, Websockets and even Third-Party JS interactions with the page.

Other use cases might be to show or hide elements when there is a specific number of items in the child tree, or greater than a certain number.

Actions

ActionPurpose
--

Targets

TargetPurposeDefault
---

Classes

ClassPurposeDefault
---

Values

ValueTypeDescriptionDefault
nameStringThe name/key to send signals using. This name should be the same as the nameValue of the other SignalControllers you want to sync with.-
scopeSelector (Optional)StringA CSS selector to pass to querySelectorAll to limit what elements are included in the count of empty/not-empty. You can use this to ignore certain elements from the countAll child elements of the controller root element

Events

EventWhenDispatched onevent.detail
signal:value:#{nameValue}When the value of the attached input changesThe controller root elementvalueThe new value of the input

Side Effects

None

How to Use


<div data-controller="signal-dom-children" data-demo-target="output" data-signal-dom-children-name-value="notifications">
<!-- Notifications are put into this element by websockets, or a third-party library. -->
<!-- Notifications can be dismissed by clicking "X", which simply removes them from the DOM. -->
<!-- We don't need to call any methods, fire any events, or reference any controllers directly -->
<!-- The controller will emit a signal when elements are added or removed, and inform any listening controllers with the same `nameValue` of how many elements there are -->
</div>

<div
class="alert alert-success my-4"
data-controller="signal-visibility"
data-signal-visibility-name-value="notifications"
data-signal-visibility-show-value="<=0"
>
<!-- This message will only show when there are zero notifications -->
Well done! You've reached inbox zero.
Make yourself a cup of tea, you deserve it.
</div>