CableReady is zero-config, meaning that there is no elaborate setup ritual. Still, there are several ways to tweak how things work, especially when it comes to integrations with other libraries.
You can add your own operations to CableReady by creating an initializer:
config/initializers/cable_ready.rbCableReady.configure do |config|config.add_operation_name :jazz_handsend
Then you need to add your operation's implementation to the CableReady client, ideally before you import your Stimulus controllers and/or ActionCable channel subscribers. Note that while the Ruby
Now you can call your custom operation like any other. Any options passed to the operation when it is queued will be sent as part of the broadcast to the client.
You can find inspiration for your own operations by checking out how the "factory default" operations were implemented. The
innerHtml methods are an excellent starting point.
If you need for your custom operation to support multi-element selectors, you will need to import the
You can now call your custom operation with
select_all: true and you will see a console log message for every matching element.
cable_ready["visitors"].jazz_hands(selector: ".hand", select_all: true, thumbs: 2).broadcast
The morphdom library supports providing a callback function to decide whether a DOM element should be morphed; if this callback returns false for an element, neither that element nor any of that element's children will be morphed.
There is also a corresponding callback function that will run only if an element did get morphed. So this is not "before and after", but "should I and did I?" By adding our own callback functions, we can add support for interacting with other libraries which would otherwise be difficult or impossible.
shouldMorph, sequentially executes an array of functions called
shouldMorphCallbacks. It comes factory installed with two callbacks that you can probably leave alone:
verifyNotPermanent. If you're not using StimulusReflex, you could experiment with
slice to remove
verifyNotPermanent for a small performance boost. 🤷
These callbacks need to return true if the element should be morphed, or else return false to skip it. All callbacks must return a boolean value, even if the purpose of of the callback is to perform some kind of meta-transformation on the elements, as you'll see with the Alpine example in a moment.
Your shouldMorph callback function will receive three parameters: the
options passed to the
fromEl, which is the element before it is (potentially) morphed, and
toEl, which is the element
fromEl will (potentially) be morphed into.
The primary use case of a shouldMorph callback is to skip elements that meet a certain criteria - or don't. This could be handy if you need to protect part of the DOM:
A sneaky second use of shouldMorph callbacks is to assume the function will return true, but use it as an opportunity to prepare the incoming element by copying something from the outgoing element. This is important for AlpineJS users, who need to clone Alpine's internal state machine so that components are properly initialized:
didMorph, sequentially executes an array of functions called
didMorphCallbacks. These callbacks will only fire for elements which were successfully morphed.
Your didMorph callback function will receive two parameters: the
options passed to the
morph method, and
el, which is the element after it has been morphed.
In the following example, users of the Shoelace web component UI toolkit can add the
hydrated CSS class to every morphed element with a tagname that starts with "SL-".
Do you love CableReady's
perform method, but wish that it returned a Promise? You are in luck!
By default, CableReady will generate a warning in your Console Log if you attempt to execute an operation on a selector that does not exist. Sometimes, this isn't desirable and you just want to silently ignore missing elements. This can be achieved by passing an object with
emitMissingElementWarnings: false as the second parameter to
An example of this behavior at work is in the Optimism channel subscriber class, which can occasionally generate validation warnings for fields that don't exist in your View: