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;
    }

}
3
  • can you add complet code snippet? is the anchor tag overshadowed by some other component's css? Commented May 22, 2019 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 Commented May 22, 2019 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
    Commented May 22, 2019 at 10:57

1 Answer 1

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .