Onclick event is not working

javascriptlightning-web-components

I have a small problem, so I created a getter from which I get values, I wanted to assign an onclick to the last one, but it didn't work. If I assign the values ​​, as in the commented code, everything works fine, someone can correct me where I make a mistake

 <ul class="list">
  <!-- <li class="item">
    <img src="some.img.link" class="list-image" />
    <lightning-formatted-rich-text class="list-item" value="My Profile"></lightning-formatted-rich-text>
  </li>
  <li class="item">
    <img src="some.img.link" class="list-image" />
    <lightning-formatted-rich-text class="list-item" value="My Events"></lightning-formatted-rich-text>
  </li>
  <li class="item">
    <img src="some.img.link" class="list-image" />
    <lightning-formatted-rich-text class="list-item" value="My Orders"></lightning-formatted-rich-text>
  </li>
  <li class="item" onclick={handleLogout}>
    <img src="some.img.link" class="list-image" />
    <lightning-formatted-rich-text class="list-item" value="Log Out"></lightning-formatted-rich-text>
  </li> -->
  <template for:each={menuData} for:item="el">
    <li class="item" key={el.id}>
      <img src={el.img} class="list-image" />
      <lightning-formatted-rich-text class="list-item" value={el.title}></lightning-formatted-rich-text>
    </li>
  </template>
</ul>
  

**JS**
get menuData() {
    return [
        {
            title: 'My Profile',
            img: 'https://salesforce-hcp-prod.s3.eu-central-1.amazonaws.com/Salesforce/GLOBMX/icons/person.png'
        },
        {
            title: 'My Events',
            img: 'https://salesforce-hcp-prod.s3.eu-central-1.amazonaws.com/Salesforce/GLOBMX/icons/people.png'
        },
        {
            title: 'My Orders',
            img: 'https://salesforce-hcp-prod.s3.eu-central-1.amazonaws.com/Salesforce/GLOBMX/icons/bag.png'
        },
        {
            title: 'Log Out',
            img: 'https://salesforce-hcp-prod.s3.eu-central-1.amazonaws.com/Salesforce/GLOBMX/icons/exit.png',
            onclick: () => this.handleLogout()
        },


    ];
}

handleLogout() {
    const logoutUrl = `${basePath.replace(/\/s$/i, '')}/secur/logout.jsp?retUrl=${basePath}`;
    window.open(logoutUrl, '_self');

}

Best Answer

You could use an iterator and utilize it's first/last properties to do this.

This can be a little clumsy looking as you can see:

<template iterator:it={menuData}>
  <li if:false={it.last} class="item" key={it.value.id}>
    <img src={it.value.img} class="list-image" />
    <lightning-formatted-rich-text class="list-item" value={it.value.title}></lightning-formatted-rich-text>
  </li>
  <li if:true={it.last} onclick={handleLogout} class="item" key={it.value.id}>
    <img src={it.value.img} class="list-image" />
    <lightning-formatted-rich-text class="list-item" value={it.value.title}></lightning-formatted-rich-text>
  </li>
</template>

One solution is to mark the item and logout if the title (or something else) matches the expected logout text.

<template for:each={menuData} for:item="el">
  <li class="item" key={el.id} data-title={el.title} onclick={handleClick}>
    <img src={el.img} class="list-image" />
    <lightning-formatted-rich-text class="list-item" value={el.title}></lightning-formatted-rich-text>
  </li>
</template>

JS:

handleClick = (e)=>{
  let title = e.currentTarget.dataset.title;
  if (title.toLowerCase() === 'log out'){
    //do your logout stuff
  }
  else {
    e.preventDefault();
  }
}

You could also find the last item in javascript and add the event handler to it in the renderedCallback.

Related Topic