How to specify event handlers when using lit-html?
Asked Answered
A

2

7

The main documentation under [Writing Templates] the following example for binding an event handler with lit-html is provided.

html`<button @click=${(e) => console.log('clicked')}>Click Me</button>`

Adding this a simple page with the default render and html functions imported and calling render however doesn't seem to render the button. If you remove the @click event binding then the button is rendered. There must be something I'm missing or a serious bug in the library.

version: 0.10.2

The links below relate to how events handler bindings work in lit-html:

Accusative answered 13/8, 2018 at 2:29 Comment(0)
C
14

The previous accepted answer was wrong. lit-extended is deprecated and that workaround only worked for a period in 2018 while lit-html was switching over to the new syntax.

The correct way to consume an event is:

html`<button @click=${e => console.log('clicked')}>Click Me</button>`

You can configure the event by assigning an object with a handleEvent method too:

const clickHandler = {

    // This fires when the handler is called
    handleEvent(e) { console.log('clicked'); }

    // You can specify event options same as addEventListener
    capture: false;
    passive: true;
}

html`<button @click=${clickHandler}>Click Me</button>`

There is also lit-element which gives you a base for building web components with Lit and TypeScript enhancements to move the boilerplate noise of creating event handlers into decorators:

@eventOptions({ capture: false, passive: true })
handleClick(e: Event) { console.log('clicked'); }

render() {
    return html`<button @click=${this.handleClick}>Click Me</button>`
}
Coreencorel answered 13/12, 2018 at 7:49 Comment(0)
A
-4

It appears that in order to use event handler bindings one must not use the standard lit-html API but instead lit-extended which appears to be distributed along with lit-html. Changing import statement to import lit-extended and changing the attribute syntax as shown below seems to work for me.

Before:

import { html, render } from "lit-html";

html`<button @click=${(e) => console.log('clicked')}>Click Me</button>`

After (working):

import { html, render } from "lit-html/lib/lit-extended";

html`<button on-click=${(e) => console.log('clicked')}>Click Me</button>`

Note that the @click syntax didn't seem to work for me at all regardless of what several examples show in the GitHub issues as well as the main documentation. I'm not sure if the above syntax is the preferred way or only way to do event binding but it seems to be one that is at least working.

To me it looks like this may be a good candidate for contributing improvements to the lit-html documentation.

Accusative answered 13/8, 2018 at 3:1 Comment(3)
It seems like on-click is the only way to add an event listener. See relevant code snippet here. There's also a comment saying that lit-extended will be deprecated soon. I believe a lot of lit-html's API will be changing until they release 1.0.0.Anguine
For people reading this in the future, i can confirm that as of @polymer/lit-element version 0.6.0 the correct way to handle events is: <button @click="${(e) => this._clickHandler(e)}">Click me!</button>Cuenca
A it turns out there was an unfortunate timing of when the documentation was released on the website and when the new version of lit-html was released which changed the syntax. As I understand the docs and latest release are now in sync with each other now. github.com/Polymer/lit-html/issues/432Accusative

© 2022 - 2024 — McMap. All rights reserved.