MultiSelect Component Filtering malfunction after selectAll

Dear Sir or Madam, 

I've come across a behavior of the Multi Select Component which I think looks like a bug. It concerns the filtering functionality.

I am working with mode=Checkbox and filterType=Contains.

Correct behavior: 

When I open the pop-up (with nothing selected) and I start typing in the filter bar, the component searches the items and filters the matches. Then I can check the box and therefore select a desired item.

"Wrong" behavior:

My requirements dictate that all items in the multi select are preselected when the component is populated with data. Hence I am using the (dataBound) event and then I use the selectAll(true) method. So far so good. Next I want to unselect all items and search/filter only one or two. I choose the "Unselect All" option and then i start to type in the filter bar. With the first character I type the component already selects all matches found. It doesn't simply show them, it selects them. Therefore if I type "c" the component selects 4 items (all 4 contain the character "c"). This seems wrong to me. Say I wanted to look for "Cabbage" only, I did not want the 4 items selected.

I've adapted an example of yours to act as a reproduction. See link below.

https://stackblitz.com/edit/angular-ixfx5smx?file=src%2Fapp.component.ts

Kind regards, 

Panagiotis Kolokouris


3 Replies

UD UdhayaKumar Duraisamy Syncfusion Team January 8, 2025 01:09 PM UTC

The behavior you're observing with the MultiSelect component, where filtered items are automatically selected, is caused by invoking the selectAll method within the dataBound event. This event is triggered each time the data source is populated in the popup list, including after each filtering operation. As a result, using selectAll in this event causes the filtered items to be selected by default.



To ensure that all items are selected only when the component is initialized, it is recommended to use the created event instead. This event is triggered only once when the component is created, which allows the selectAll method to be called without affecting the filtering process.


Here’s how you can implement this:

<ejs-multiselect id='multiselectelement' #multiSelect [dataSource]='vegetableData' [fields]='fields'[placeholder]='placeholder' [popupHeight]='height' [mode]='mode' filterType='Contains' [enableGroupCheckBox] ='enableGroupCheckBox' [allowFiltering]='allowFiltering' [filterBarPlaceholder]='filterBarPlaceholder' [showSelectAll]='showSelectAll' (created)="onCreated($event)"></ejs-multiselect>


  public onCreated(eany): void {

    this.multiSelect.selectAll(true);

  }


By handling the selection in the created event, all items will be selected initially, without affecting the filtering functionality.


For your reference, here is a sample demonstrating this approach: Cpxjmve2 (forked) - StackBlitz



PK P Kolokouris January 8, 2025 03:00 PM UTC

Hello and thanks for your reply!

In the simple case where the vegetableData is available at the time the page is initialized, this works fine. However, what if my data come from a server and hence are available later on in time. I can think of two solutions:

  1. I delay the rendering of the ejs-multiselect component with and *ngIf="vegetableData.length>0" div. However in this case the this.multiSelect instance is undefined when the selectAll method must be called. Hence this solution does not work. See example: https://stackblitz.com/edit/angular-ixfx5smx-csjgbhda?file=src%2Fapp.component.ts
  2. If i don't delay the rendering of the ejs-multiselect component strangely the this.multiSelect is ready and although my data is not ready, all items are selected in the dropdown. However i still get a console error which I was hoping to avoid.. See example: https://stackblitz.com/edit/angular-ixfx5smx-nqfgvxjx?file=src%2Fapp.component.ts


UD UdhayaKumar Duraisamy Syncfusion Team January 13, 2025 05:52 AM UTC

To meet your requirement, you can utilize the created event along with the dataBound event. By setting a boolean variable to true within the created event, you can control when to trigger the selectAll method. After calling the selectAll method, reset the boolean to false. This approach ensures that the selection is made only after the data is successfully bound to the component and prevents automatic selection during data filtering.


Here is a code snippet and sample for your reference:

<ejs-multiselect 
           id='multiselectelement' 
#multiSelect 
[dataSource]='vegetableData' 
[fields]='fields'
[placeholder]='placeholder' 
[popupHeight]='height' 
[mode]='mode' 
filterType='Contains' 
[enableGroupCheckBox] ='enableGroupCheckBox' 
[allowFiltering]='allowFiltering' 
[filterBarPlaceholder]='filterBarPlaceholder' 
[showSelectAll]='showSelectAll' 
(created)="onCreated($event)" 
(dataBound)="onDataBound()">
</ejs-multiselect>

  public isCreated: boolean = false;
  public onCreated(e: any): void {
    this.isCreated = true;
  }
  public onDataBound(): void {
    if (this.isCreated) {
      this.multiSelect.selectAll(true);
      this.isCreated = false;
    }
  }

            

You can explore this in more detail with the following sample: MultiSelect Issue v1 (forked) - StackBlitz


Loader.
Up arrow icon