0

I have to build an app page with several filters that can be choosen from multiple picklists. There isn't a stantard Lightning Web Components that let me choose multiple options from a picklist component, so I decided to use this custom component:

MultiPickList custom component

Live demo

The component works great but there is a problem: if I open a dropdown to choose some options and then I open another one, the previous one doesn't close. This is the behaviour that I get:

enter image description here

I put all the multiPickLists inside a c-filters parent component but the problem is that because of Lightning Locker I can't access child components DOM elements from the parent. If I try to console.log(this.template.querySelectorAll(".ms-picklist-dropdown")) (the element with the class ms-picklist-dropdown is the one that controls if the dropdown is opened or closed with the class slds-is-open) from the c-filters parent component I don't get any element, so I can't remove the class.

Have you got any idea to help me solve this issue? Thank you.

4
  • Have you seen the standard LWC dual list box? - developer.salesforce.com/docs/component-library/bundle/…
    – sfdx bomb
    Mar 6, 2021 at 10:53
  • Yes but I need a dropdown for options...
    – Stefano
    Mar 6, 2021 at 10:55
  • 1
    That code is terrible. It's not a good example of how to write an LWC. That said, you're also barking up the wrong tree--the component itself should be smart enough to close itself when no longer needed. That's the point of a component. I'm trying to fix this, but it might take a moment (that code is terrible).
    – sfdcfox
    Mar 6, 2021 at 13:59
  • @sfdcfox Thank you for your support, I really appreciate it. Let me know if you fix this issue :)
    – Stefano
    Mar 6, 2021 at 14:27

1 Answer 1

2

This code basically suffers from trying to update components outside of itself, resulting in the previous boxes staying open. This was solved by adding/changing the following code:

  @track _mOptions = [];
  _isOpen = false;
  _firstOpen = false;
  _docHandler;

  connectedCallback() {
    this._docHandler = () => {
      if(this._isOpen && !this._firstOpen) {
        this.closeAllDropDown();
      }
      this._firstOpen = false;
    };
    document.addEventListener('click', this._docHandler);
  }
  disconnectedCallback() {
    document.removeEventListener(this._docHandler);
  }
  closeAllDropDown() {
    this._isOpen = false;
  }
  stopPropagation(event) {
    if(!this._firstOpen) {
      event.stopPropagation();
    }
  }
  onDropDownClick(event) {
    this._firstOpen = this._isOpen = true;
  }

And then adding a top-level handler:

<div class="slds-form-element" onclick={stopPropagation}>

After this, and some more cleanup, the result is a relatively functional dropdown. In the interest of brevity, I'm including a link to the forked copy of the live demo you provided.

You'll notice a number of quality-of-life improvements in the code, including eliminating all need for self, proper use of arrow functions, etc.

As a side note, I will also mention that this code doe not currently support keyboard navigation. This is a major problem, but I won't be addressing it here, as that is an entirely separate problem.

I hope you find this update useful as a starting point.

As a final side note, this code is "interesting", but you should probably start from the SLDS Combobox design instead. I realize it means pretty much starting over, but using standard designs helps consolidate the look and feel with Salesforce standard functionality (it's just a shame that lightning-combobox doesn't behave as well as the documented version).

Edit: Also, I noticed some nuance was lost with some of the other functions. You'll want to directly manipulate the data instead of trying to use CSS manipulation as much as possible; this is reflected in the new visible property of the options array. You'll need to fix these problems as well.

1
  • Thank you for the fix and for all the advices, you helped me a lot ! :)
    – Stefano
    Mar 6, 2021 at 16:30

You must log in to answer this question.

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