lit/lit-element

Howto define event handler in html

MichaelPeter opened this issue · 4 comments

Hello Dear lit-element community,

my goal is it to consume a event like this:

html:
<my-comp navigationtitle='Navigation Event' onlink-clicked='javascript:alert("bla")'></my-comp>

now the problem is in the code below the "onclick internal" alert is shown, but not the "bla" alert in the html.
What am I missing? Does the event handler maybe need to be called link-clicked? Thank you for your help.

Or is this not yet possible to implement like that and I need this.shadowRoot.addEventListener()?

FYI: The render() renders into the ShadowDOM

background Code: mycomp


  handleClick(e) {

    alert("onclick internal");

    var val = {
      detail: {
        linkId: e.target.id,
        linkhref: e.target.href
      },
      bubbles: true, // To exit shadow dom boundaries
      composed: true // To exit shadow dom boundaries
    };

    //alert(e.linkId);    
    var ev = new CustomEvent('link-clicked', val /*cloneInto(val)*/);
    this.dispatchEvent(ev);
  }

  render() {
      return html`
        <my-panel paneltitle="${this.navigationtitle}" size="small">
            <nav slot="body" class="link-list">
              <ul>${this.linklist.map(i => html`<li ?isactive="${i.active}"><a id="${(i.id) ? i.id : i.label}" href="${i.href}" @click="${this.handleClick}">${i.label}</a></li>`)}</ul>
            </nav>
        </my-panel>
      `;
  }
}

I also asked at the WICG here regarding this issue if it should be added to the standard.

WICG/webcomponents#908

They said it should be up to teh frameworks to implement it. So essencially lit-element would neen an option to publish events, and if then the getAttribute returnes something for on + "eventname", the content need to be parsed as javascript.

Would it be possible to add that?

Greetings Michael

You can do this with a custom property converter.

Given how insecure this is, I'm not sure we want to include this in core though.

Putting javascript code like this directly inline in your HTML is generally considered very bad for page security.

As @justinfagnani mentioned, it's possible to create a property converter that sets the property to a specific value when an attribute is set.

static properties = {
  "onlink-clicked": {type: String, converter: literalToJs}
}

You'd need to implement literalToJs there by parsing the javascript: off the string and then probably eval'ing it. You'd then need to add an event listener that invokes the function.

Again, we do not recommend doing this because of the security implications.

Hope. that helps.

Hi sorry forgot to close this

Solved this with the @ event syntax, didn't know it was also possible for custom events outside litelenent

@link-clicked='(e)=>alert(e.detail.myparam)'