I have a simple web component that contains a <slot>
. It handles form data and inside I have UI elements that emit data change/selected events. I'm wondering how the web component can react on events emitted from slot content. Something along these lines:
<my-form-handler>
<my-player-selector player-id="master"></my-player-selector>
<my-player-selector player-id="challenger"></my-player-selector>
<my-weapons-selector default="sword"></my-weapons-selector>
</my-form-handler>
I know I could write <my-form-handler ondataSelected="someFunction">
presuming the selector elements emit dataSelected
events. But that would require the code to live in the containing page instead of my-form-handler.
I'm not using any framework (Vue, Angular, React), just vanilla JS.
You can define in your custom element <my-form-handler>
a handler in the constructor()
or in the connectedCallback()
method.
customElements.define( 'my-form-handler', class extends HTMLElement {
conectedCallabck() {
this.addEventListener( 'dataSelected', dsHandler )
function dsHandler( ev ) {
console.log( ev.type, ev.target.textContent )
}
}
} )
Of course you could use an arrow function if you want that this
refers to the custom element object:
let dsHandler = ev => {
console.log( ev.type, ev.target.textContent )
}
this.addEventListener( 'dataSelected', dsHandler )
You can also define the handler inline:
this.addEventListener( 'dataSelected', ev =>
console.log( ev.type, ev.target.textContent )
)
NB: if you want the event handler to be a custom element method , you'll need to use bind(this)
to be sure it can still access the custom element object.
customElements.define( 'my-form-handler', class extends HTMLElement {
conectedCallabck() {
this.addEventListener( 'dataSelected', this.dsHandler.bind( this ) )
}
dsHandler( ev ) {
console.log( 'recever: %s / emitter: %', this.localName, ev.target.textContent )
}
} )
Alternately, you can opt to a centralized solution with the help of the handleEvent()
interface:
1 Set the custom element itself as the listener:
this.addEventListener( 'dataSelected', this )
2 Implement the handleEvent()
method:
handleEvent( ev ) {
switch( ev.type ) {
case 'dataSelected':
console.log( 'recever: %s / emitter: %', this.localName, ev.target.textContent )
break
}
}
Below a running snippet:
customElements.define( 'my-form-handler', class extends HTMLElement {
constructor() {
super()
this.addEventListener( 'dataSelected', this )
}
handleEvent( ev ) {
console.log( ev.type, ev.target.textContent )
}
} )
customElements.define( 'my-player-selector', class extends HTMLElement {
constructor() {
super()
this.addEventListener( 'click', () =>
this.dispatchEvent( new CustomEvent( 'dataSelected', { bubbles: true } ) )
)
}
} )
<my-form-handler>
<my-player-selector player-id="master">master</my-player-selector>
<my-player-selector player-id="challenger">challenger</my-player-selector>
<my-weapons-selector default="">sword</my-weapons-selector>
</my-form-handler>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With