Created
April 10, 2023 12:25
-
-
Save bennadel/84da1c22818a3b866b7a134d14013a03 to your computer and use it in GitHub Desktop.
Listen For Stimulus Custom Events Outside Of Hotwire
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfscript> | |
emojis = [ | |
{ | |
name: "Grinning Face", | |
hex: "1F600" | |
}, | |
{ | |
name: "Heart", | |
hex: "2764 FE0F" | |
}, | |
{ | |
name: "Fire", | |
hex: "1F525" | |
} | |
]; | |
</cfscript> | |
<cfmodule template="./tags/page.cfm"> | |
<cfoutput> | |
<div id="myDiv"> | |
<p> | |
<input id="myInput" type="text" autofocus /> | |
</p> | |
<p> | |
<cfloop item="emoji" array="#emojis#"> | |
<button | |
data-controller="emoji" | |
data-action="emoji##emitEmoji" | |
data-hex="#encodeForHtmlAttribute( emoji.hex )#"> | |
#encodeForHtml( emoji.name )# | |
</button> | |
</cfloop> | |
</p> | |
</div> | |
<!--- LEGACY LOGIC. ---> | |
<script type="text/javascript"> | |
// Even though our Emoji controller is a Stimulus controller, the events that | |
// it emits are still native DOM (Document Object Model) events. Which means, | |
// we can create "bridge" code that glues our legacy logic and our Hotwire | |
// logic together as we migrate a legacy application. In this case, I'm going | |
// to listen for the custom event, "emoji" (from the "emoji" controller), and | |
// then use it to insert the desired emoji into the input using the following | |
// legacy logic. | |
myDiv.addEventListener( | |
"emoji:emoji", | |
( event ) => { | |
console.group( "Emoji Event" ); | |
console.log( "Glyph:", event.detail.emoji ); | |
console.log( "Hex:", event.detail.hex ); | |
console.log( "Codepoints:", event.detail.codepoints ); | |
console.groupEnd(); | |
// Legacy logic to insert emoji in input. | |
var insertAt = myInput.selectionEnd; | |
var nextSelectionAt = ( insertAt + event.detail.emoji.length ); | |
myInput.value = ( | |
myInput.value.slice( 0, insertAt ) + | |
event.detail.emoji + | |
myInput.value.slice( insertAt ) | |
); | |
myInput.focus(); | |
myInput.selectionStart = myInput.selectionEnd = nextSelectionAt; | |
} | |
); | |
</script> | |
</cfoutput> | |
</cfmodule> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Import core modules. | |
import { Application } from "@hotwired/stimulus"; | |
import { Controller } from "@hotwired/stimulus"; | |
// ----------------------------------------------------------------------------------- // | |
// ----------------------------------------------------------------------------------- // | |
export class EmojiController extends Controller { | |
/** | |
* I emit the "emoji" event for the associated hex-encoded code-points. | |
*/ | |
emitEmoji( event ) { | |
var codepoints = event.target.dataset.hex | |
.split( " " ) | |
.map( | |
( hex ) => { | |
return( parseInt( hex, 16 ) ); | |
} | |
) | |
; | |
this.dispatch( | |
"emoji", | |
{ | |
detail: { | |
emoji: String.fromCodePoint( ...codepoints ), | |
hex: event.target.dataset.hex, | |
codepoints: codepoints | |
} | |
} | |
); | |
} | |
} | |
// ----------------------------------------------------------------------------------- // | |
// ----------------------------------------------------------------------------------- // | |
window.Stimulus = Application.start(); | |
// When not using the Ruby On Rails asset pipeline / build system, Stimulus doesn't know | |
// how to map controller classes to data-controller attributes. As such, we have to | |
// explicitly register the Controllers on Stimulus startup. | |
Stimulus.register( "emoji", EmojiController ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<button | |
data-controller="emoji" | |
data-action="emoji#emitEmoji" | |
data-hex="2764 FE0F"> | |
Red Heart | |
</button> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment