quma
quma

Reputation: 5733

Angular Material - matIcon in MatSelect

I use this angular material select in my Angular 5 application:

<mat-form-field style="width:88%;">
    <mat-select placeholder="Contact *" formControlName="contact">
       <mat-option *ngFor="let contact of contacts" [value]="contact">
         <mat-icon [ngStyle]="{'color': contact.color}">home</mat-icon>{{contact.institution}} 
       </mat-option>
    </mat-select>
</mat-form-field>

On the select panel <mat-icon> are listed as expected but if I select one option then the home icon does not appear in <mat-form-field>

How could I also view the home icon in <mat-form-field> once selected?

Upvotes: 47

Views: 71276

Answers (5)

MaxThom
MaxThom

Reputation: 1401

In my case, this is how I solve it. No subscription or template reference. Just add the to override the displayed label and use the same functions.

Hope it helps !

      <mat-form-field appearance="fill">
        <mat-label>Select a state</mat-label>
        <mat-select [(value)]="lifecycleValue">
          <mat-select-trigger>
            <mat-icon matSuffix>{{ getLifecycleStateIcon(lifecycleValue) }}</mat-icon>&nbsp;&nbsp; {{lifecycleValue}}
          </mat-select-trigger>
          <mat-option *ngFor="let state of lifecycleStates"
            [value]="state">
            <mat-icon matSuffix>{{ getLifecycleStateIcon(state) }}</mat-icon> {{ state }}
          </mat-option>
        </mat-select>
      </mat-form-field>
export class DatasetShardEditDialogComponent implements OnInit {
  lifecycleStates: string[] = Object.values(LifecycleState);
  lifecycleValue: LifecycleState;
  ...
  getLifecycleStateIcon(state: LifecycleState): string {
    switch (state) {
      case LifecycleState.Archived: {
        return 'cloud_done';
      }
      case LifecycleState.Error: {
        return 'error';
      }
      case LifecycleState.NoArchive: {
        return 'cloud_off';
      }
      case LifecycleState.NotArchived: {
        return 'cloud_queue';
      }
      case LifecycleState.Unknown: {
        return 'help';
      }
      case LifecycleState.Archiving: {
        return 'cloud_upload';
      }
      default: {
        return '';
      }
    }
  }

Upvotes: 0

cain4355
cain4355

Reputation: 1134

This can be accomplished via the "mat-select-trigger" option. Documentation on the "mat-select" can be found here.

https://material.angular.io/components/select/api#MatSelectTrigger

Below should be a working example of what you are trying to do. Based on what you provided.

<mat-form-field style="width: 88%">
  <mat-select placeholder="Contact *" formControlName="contact">
    <mat-select-trigger>
      <mat-icon>home</mat-icon>&nbsp;{{ contact.institution }}
    </mat-select-trigger>
    <mat-option *ngFor="let contact of contacts" [value]="contact">
      <mat-icon [ngStyle]="{ color: contact.color }">home</mat-icon>{{ contact.institution }}
    </mat-option>
  </mat-select>
</mat-form-field>

And apply styles as necessary.

Upvotes: 71

koral levi
koral levi

Reputation: 31

You can add conditions inside mat-select-trigger using :

  <mat-select matInput formControlName="status" placeholder="select status" required>
              <mat-select-trigger>
                          <ng-container [ngTemplateOutlet]="icons" [ngTemplateOutletContext]="{data:formControls.status.value}"></ng-container>
              </mat-select-trigger>

              <mat-option *ngFor="let currStatus of data.status" [value]="currStatus ">
                           <ng-container [ngTemplateOutlet]="icons" [ngTemplateOutletContext]="{data: currStatus}"></ng-container>
              </mat-option>
  </mat-select>

to avoide duplicate code you can set the mat-icon section in template


<ng-template #icons let-data="data">
             <mat-icon *ngIf="data.key === taskStatus.WAITING">hourglass_empty</mat-icon>
             <mat-icon *ngIf="data.key === taskStatus.IN_PROGRESS">autorenew</mat-icon>
             <mat-icon *ngIf="data.key === taskStatus.COMPLETED">done</mat-icon>
             {{data.value}}
</ng-template>

in ts file:

  public get formControls() { return this.createTaskForm.controls; }

Upvotes: 1

Ahmed Adel Shaker
Ahmed Adel Shaker

Reputation: 59

I had the same issue, and I fixed by subscribing to the contact field of the reactive form, and then update the value of your object here is how.

My Template

<mat-form-field appearance="fill">
  <mat-label>Avatar</mat-label>
  <mat-select formControlName="avatar">
    <mat-select-trigger>
      <mat-icon svgIcon="{{user.avatar}}"></mat-icon> {{user.avatar}}
    </mat-select-trigger>
    <mat-option *ngFor="let avatar of avatars" [value]="avatar">
      <mat-icon svgIcon="{{avatar}}"></mat-icon>{{avatar}}
    </mat-option>
  </mat-select>
</mat-form-field>

My TS Code

this.contactForm.get('avatar').valueChanges.subscribe((value) => {
  this.user.avatar = value;
});

and as you noticed I'm here updating the user object with the selected value, then

<mat-icon svgIcon="{{user.avatar}}"></mat-icon> 

will be updated by the selected avatar.

Upvotes: 1

G. Tranter
G. Tranter

Reputation: 17908

You can add a matPrefix to the form field:

<mat-form-field style="width:88%;">

    <span matPrefix style="margin-right: 8px;"><mat-icon>home</mat-icon></span>

    <mat-select placeholder="Contact *" formControlName="contact">
       <mat-option *ngFor="let contact of contacts" [value]="contact">
         <mat-icon [ngStyle]="{'color': contact.color}">home</mat-icon>{{contact.institution}} 
       </mat-option>
    </mat-select>

</mat-form-field>

If the icon is a property of each contact such as contact.icon then you will need to do a bit more work to bind the currently selected contact's icon property to the mat-icon name:

<mat-form-field style="width:88%;">

    <span *ngIf="select.value" matPrefix style="margin-right: 8px;"><mat-icon>{{select.value.icon}}</mat-icon></span>

    <mat-select #select placeholder="Contact *" formControlName="contact">
       <mat-option *ngFor="let contact of contacts" [value]="contact">
         <mat-icon [ngStyle]="{'color': contact.color}">home</mat-icon>{{contact.institution}} 
       </mat-option>
    </mat-select>

</mat-form-field>

Upvotes: 5

Related Questions