0

How to detect outside the div and inside the div in LWC. I have a child component, which I have used multiple times as a custom picklist and Simple Text. So When I click Simple text the picklist is visible and the text is hidden. So here I am getting issues like when I click any child it opens its picklist but does not close another child's pick list.

childHTML:

<template>
<div class="picklistBlock" id="picklist" data-id="picklist">
    <div if:true={showPicklist} class="picklist-container">
        <lightning-combobox name="picklist" label={label} value={value} placeholder={placeholder} options={options} variant='label-hidden'
        onchange={handleChange}></lightning-combobox>
    </div>
    <div if:false={showPicklist} class="slds-table_edit_container slds-is-relative" id="picklists">
        <span class="slds-grid slds-grid_align-spread slds-cell-edit">
            <span class="slds-truncate" title={value}>{value}</span>
            <button data-id={context} class="slds-button slds-button_icon slds-cell-edit__button slds-m-left_x-small" tabindex="-1" title="Edit" name="tes"
                onclick={handleClick} data-name="myButtonName" >
                <svg class="slds-button__icon slds-button__icon_hint slds-button__icon_lock slds-button__icon_small slds-button__icon_edit slds-icon slds-icon-text-default slds-icon_xx-small"
                    aria-hidden="true">
                    <use xlink:href="/_slds/icons/utility-sprite/svg/symbols.svg?cache=9.37.1#edit"></use>
                </svg>
                <span class="slds-assistive-text">Edit</span>
            </button>
        </span>
    </div>
</div>

child.JS

import { LightningElement, api, track } from 'lwc';

export default class PicklistColumn extends LightningElement {
@api label;
@api placeholder;
@api options;
@api value;
@api context;
@track showPicklist = false;
@track eleId;

renderedCallback(){
    if(!this.eleId){
        this.eleId = this.template.querySelector('.picklistBlock').getAttribute('id');
    }
}

connectedCallback() {
    window.addEventListener("click", (evt) => {
      console.log(evt.currentTarget);
    });
}

handleClick(event){
    this.showPicklist = true;
}

close() { 
    this.showPicklist = false;
}

}

1
  • @sfdcfox Can you please help in this. Aug 5, 2022 at 18:20

1 Answer 1

2

You can achieve this in multiple ways. First one is by dispatching custom event when user clicks icon button and adding unique id to component so parent can distinguish from which child event was dispatched, like this

@api
uniqueId

handleClick(event){
    this.showPicklist = true;
    this.dispatchEvent(new CustomEvent("startedit", {
        detail: {
            uniqueId: this.uniqueId
        }
     }))
}

Then, add @api annotation to close method so it can be called from outside of component

@api
close() { 
    this.showPicklist = false;
}

Now, in parent, handle custom event, by adding handler


    /**
     * Handle startedit event
     * @param {CustomEvent} event 
     */
    handleEditStart(event) {
        const uniqueId = event.detail.uniqueId
        this.template.querySelectorAll("c-child").forEach(component => {
            if(component.uniqueId != uniqueId) {
                component.closePicklist()
            }
        })
    }

Your second options is to make showPicklist api visible by marking it with @api annotation and move its management to parent.

One note about your HTML code. To display standard SVG icon as a button you can use built-in component lightning-button-icon

<template>
    <div class="picklistBlock" id="picklist" data-id="picklist">
        <div if:true={showPicklist} class="picklist-container">
            <lightning-combobox name="picklist" label={label} value={value} placeholder={placeholder} options={options} variant='label-hidden'
            onchange={handleChange}></lightning-combobox>
        </div>
        <div if:false={showPicklist} class="slds-table_edit_container slds-is-relative" id="picklists">
            <span class="slds-grid slds-grid_align-spread slds-cell-edit">
                <span class="slds-truncate" title={value}>{value}</span>
                <lightning-button-icon title="Edit" icon-name="utility:edit" onclick={handleClick}></lightning-button-icon>
            </span>
        </div>
    </div>
</template>
4
  • Hi @ziemniakoss, thanks for your reply, I will check this. But my question is can we handle this by event listener , so if any person clicks outside the screen the picklist also close? Aug 6, 2022 at 12:14
  • Hi, yes you can to this by manipulating focus. To do so you need to add renderedCallback to child component like this renderedCallback() { this.template.querySelector("lightning-combobox")?.focus() } and then add event listener to lightning-combobox that closes picklist like this onblur={closePicklist}. Now when user clicks outside of screen, combobox loses focus and picklist is closed Aug 6, 2022 at 13:29
  • thank you @ziemniakoss, It's worked. Aug 6, 2022 at 14:38
  • HI @@ziemniakoss, Can you tell how will this work for LWC Input Field ? Sep 2, 2022 at 11:02

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.