0

I'm building one component and I've got selectItem function for it. I need to pass index to that function. For some reason it works only occasionally.

Here is my template where I'm calling it:

<a aria-selected="true" class="slds-path__link" role="option"
                                       id={itemIndex}
                                       onclick={selectItem}
                                       tabindex={pathItem.tabIndex}
                                       data-item={itemIndex}>
</a>

As you can see I'm using data-item attribute to pass index of that item.

Here is my JS function that I'm using:

selectItem(evt) {
        console.log('index: ' + evt.target.dataset.item);
        let itemValue = this._pathItemsEnhanced[evt.target.dataset.item].itemValue;
        console.log('select item action: ' + itemValue);
    }

and here is my console output after clicking on that link several times in row (I was clicking on two links that's why there are outputs with index 3 and 4):

enter image description here

What's wrong with it? Why it doesn't work consistently? I've checked rendered html page and all of those links have proper data-item populated.

here is entire component.

The component itself is made only from html template and javascript.

<template>
    <div class="slds-path">
        <div class="slds-grid slds-path__track">
            <div class="slds-grid slds-path__scroller-container">
                <div class="slds-path__scroller" role="application">
                    <div class="slds-path__scroller_inner">
                        <ul class="slds-path__nav" role="listbox" aria-orientation="horizontal">

                            <template
                                    for:each={pathItemsEnhanced}
                                    for:item="pathItem"
                                    for:index="itemIndex">

                                <template if:true={isSelected} data-item={itemIndex}>

                                <li class="slds-path__item slds-is-current current slds-is-active" role="presentation"
                                        key={pathItem.itemValue}>

                                    <a aria-selected="true" class="slds-path__link" role="option"
                                       id={itemIndex}
                                       onclick={selectItem}
                                       tabindex={pathItem.tabIndex}
                                       data-item={itemIndex}>

                                        <span class="slds-path__stage">
                                            <svg class="slds-icon slds-icon_x-small" aria-hidden="true">
                                                <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#check"></use>
                                            </svg>
                                        </span>

                                        <span class="slds-path__title">{pathItem.itemValue}</span>

                                    </a>

                                </li>

                                </template>

                                <template if:false={isSelected} data-item={itemIndex}>

                                <li class="slds-path__item slds-is-incomplete" role="presentation"
                                        key={pathItem.itemValue}>

                                    <a aria-selected="true" class="slds-path__link" role="option"
                                       id={itemIndex}
                                       onclick={selectItem}
                                       tabindex={pathItem.tabIndex}
                                       data-item={itemIndex}>

                                        <span class="slds-path__stage">
                                            <svg class="slds-icon slds-icon_x-small" aria-hidden="true">
                                                <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#check"></use>
                                            </svg>
                                        </span>

                                        <span class="slds-path__title">{pathItem.itemValue}</span>

                                    </a>

                                </li>

                                </template>

                            </template>

                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
import { LightningElement, track, api } from 'lwc';

export default class Custom_Path extends LightningElement {

    _pathItems = [];
    _pathItemsEnhanced = [];
    _selectedItem;

    @api get pathItems() {
        return this._pathItems;
    }

    set pathItems(value) {
        this._pathItems = value;
        this.setPathItemsEnhanced();
    }

    @api get selectedItem() {
        return this._selectedItem;
    }

    set selectedItem(value) {
        this._selectedItem = value;
    }

    @api get pathItemsEnhanced() {
        return this._pathItemsEnhanced;
    }

    setPathItemsEnhanced() {
        if(this._pathItems !== undefined) {

            for(var i = 0; i < this._pathItems.length; i++) {
                var item = {
                    itemValue : this._pathItems[i],
                    itemIndex : (i === 0) ? '0' : '-1'
                };

                console.log('Item value: ' + item.itemValue);
                console.log('Item index: ' + item.itemIndex);

                this._pathItemsEnhanced.push(item);
            }

        }
    }

    selectItem(evt) {
        console.log('index: ' + evt.target.dataset.item);
        let itemValue = this._pathItemsEnhanced[evt.target.dataset.item].itemValue;
        console.log('select item action: ' + itemValue);
//        this._selectedItem = itemValue;
//        const event = new CustomEvent('handleSelect', {
//            detail : itemValue
//        });
//        this.dispatchEvent(event);
    }

    isSelected(evt) {
        console.log('index: ' + evt.target.dataset.item);
        var itemValue = this._pathItemsEnhanced[evt.target.dataset.item].itemValue;
        console.log('isSelected: ' + itemValue);
        for(var j = 0; j <= this._pathItemsEnhanced.length; j++) {
            if(this._pathItemsEnhanced[j].itemValue === this._selectedItem) {
                return true;
            }
            if(this._pathItemsEnhanced[j].itemValue === itemValue) {
                break;
            }
        }
        return false;
    }

}
  • can you add complet code snippet? is the anchor tag overshadowed by some other component's css? – Pranay Jaiswal May 22 at 10:25
  • 1
    I tried similar code , and it works for sure: developer.salesforce.com/docs/component-library/tools/… definitely some other css overshadowing your component – Pranay Jaiswal May 22 at 10:33
  • Small update @PranayJaiswal I know when it is not working. When I click directly on that text. If I click anywhere on that path item where text is not present, it works. – jakub May 22 at 10:57
0

Ok. with help of @Pranay Jaiswal, I've finally found what was causing the issue.

inner content of tag which was firing event, that with actual value was somehow blocking that data-item.

So I've updated that link to look like following code:

<a aria-selected="true" class="slds-path__link" role="option"
   id={itemIndex}
   onclick={selectItem}
   tabindex={pathItem.tabIndex}
   data-item={itemIndex}>

    <span class="slds-path__title"
          data-item={itemIndex}>
        {pathItem.itemValue}
    </span>

</a>

So now even that span contains call to that function and more importantly it contains data-item.

No idea why is it behaving like this, but thanks Pranay for direction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.