2

I want to implement mat-select-filter in mat-select module. I have added a search icon for searching the items in the dropdown based on characters entered. I have referred this mat-select-filter and stackblitz but I was not getting the filter field.Below is the code that I've used

search-filter.component.html

 <mat-form-field class="input-permissions">
    <mat-select
      placeholder="Permissions"
      multiple
      [formControl]="permissionsControl"
    >
      <mat-select-filter
        [array]="permissions"
        (filteredreturn)="filteredList=$event"
      ></mat-select-filter>
      <mat-option
        *ngFor="let permission of permissions"
        [value]="permission.value"
      >
        {{ permission.value}}
      </mat-option>
    </mat-select>
  </mat-form-field>

mat-select-filter.component.ts

    export class MatSelectFilterComponent{
       permissions: {{id: 0, value: fruit},{id: 1, value: vegetable} };
       public filteredList = this.permissions.slice();
    }

Any help would be appreciated.

4
  • I believe you have a typo in your code (filteredreturn="filteredList=$event" ). It should be (filteredreturn)="filteredList=$event" Commented May 20, 2020 at 16:20
  • @Yuriy Kravets I have added it by mistake.Could you please provide a solution. Commented May 21, 2020 at 11:56
  • I added some solution for the icon. Please check it. :) Commented May 26, 2020 at 13:06
  • @Paul I'll check on it and added some questions in that solution.Could you please check on that. Commented May 26, 2020 at 13:17

1 Answer 1

7
+50
  1. permissions needs to be an Array and not an object:

    public permissions = [{id: 0, value: 'fruit' },{id: 1, value: 'vegetable'} ];
    public filteredList = this.permissions.slice();
    
  2. You need to specify the displayMember on mat-select-filter and filteredreturn should be filteredReturn:

    <mat-select-filter [array]="permissions" (filteredReturn)="filteredList=$event" [displayMember]="'value'">
    </mat-select-filter>
    
  3. If using a multiple select you need to do the hiding of the non filtered results yourself. Otherwise you could just iterate over filteredList, but in that case old selections are removed on filtering. Iterate over permissions instead and then hide those, which should not be shown.

    <mat-option *ngFor="let permission of permissions" [value]="permission"
        [class.hide]="!isFiltered(permission)">
        {{permission.value}}
    </mat-option>
    

    and the function for checking the filtered elements

    public isFiltered(permission) {
      return this.filteredList.find(item => item.id === permission.id)
    }
    

    and the css for hiding

    .mat-option.hide {
      display: none;
    }
    
  4. There is no default support for adding some icon to the filter - or at least I didn't find one. Nevertheless you can solve this by using css.

    Add this to your index.html to ensure the font is loaded correctly:

    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    

    Add the following to your css. It adds an ::after element containing the search icon as font. Take care to reduce the width of the input element by the space the icon needs (here it's 20px width and 5px padding-left) to ensure it's placed next to each other.

    .mat-filter-input {
      width: calc(100% - 25px) !important;
    }
    
    .mat-filter::after {
      content: "\e8b6";
      font-family: material icons;
      vertical-align: bottom;
      font-size: 20px;
      padding-left: 5px;
    }
    

    I needed to set the encapsulation: ViewEncapsulation.None within the component, since otherwise the styles had the wrong selector. I'm not sure if this is a stackblitz issue or not. Try it without it. If it works you can also remove !important from the width of the input element.

Here is the link to the solution on stackblitz: https://stackblitz.com/edit/mat-select-filter-zuy7ev

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you,I got it working. But an issue is persisting like,I have added more values in the array and applied filter & selected one value.Then again I have applied the filter & selected another value but the previous selected value would be disappeared.Please help on this.
@ChristinaVarghese I modified my solution. Check out the changes in point 3.
Thank you so much, this is working fine for me now.
Could you please help me to write the jest test case for the below code, public isFiltered(permission) { return this.filteredList.find(item => item.id === permission.id) }
I've actually never written angular test cases yet. But I can take a look and try it, if you tell me, what you got so far. Just fork my stackblitz solution, add your code and send the link. When you have this, it might also make sense to create a new question. In that case send me the link to the question. :) I'm curious.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.