use of [innerHTML] inside <mat-select><mat-option>

Viewed 3767

I try to use [innerHTML] inside <mat-option> of <mat-select> which works fine for the drop-down list, but not for the selected value.

Versions:

  • Browser Google Chrome 68.0.3440.106 (Official Build) (64-bit)
  • Angular 6.1.6
  • Angular material 6.4.6
  • bootstrap 4.1.3
  • @ng-bootstrap/ng-bootstrap 3.2.0

In my example the used code is

<mat-form-field class="col-11">
  <mat-select 
    [(ngModel)]="node.nodeType" 
    (change)="nodeTypeChanged()" 
    placeholder="{{'node.node_type' | translate}}"
    [compareWith]="compareObjects">
    <mat-option 
      *ngFor="let item of nodeTypes" 
      [value]="item">
      <span [innerHTML]="item.iconVisual.iconCodeHtml"></span>
      <span> {{item.label}}</span>
    </mat-option>
  </mat-select>
</mat-form-field>

The attached screen captures with combo box unselected where the task icon is not rendered and the selected combo box where the icons are correctly rendered, shows the problem.

Selected combo box: icon not rendered

enter image description here

Unselected combo box: all icons rendered

enter image description here

Simplified stackblitz here.

Is this a bug or am I missing something?

3 Answers

The correct answer is to use <mat-select-trigger> element:

like:

 <mat-select-trigger>
            <span [innerHTML]="nodeType.iconHtml"></span>
              <span> {{ nodeType.label }}</span>
        </mat-select-trigger>

This is how it will look the full example: Online Demo

template: `
    <mat-form-field>
      <mat-select [(ngModel)]="nodeType" placeholder="NodeType">
      <mat-select-trigger>
        <span [innerHTML]="nodeType.iconHtml"></span>
          <span> {{ nodeType.label }}</span>
    </mat-select-trigger>
        <mat-option *ngFor="let item of nodeTypes" [value]="item">
          <span [innerHTML]="item.iconHtml"></span>
          <span> {{ item.label }}</span>
        </mat-option>
      </mat-select>
    </mat-form-field>
  `,
  styles: [
    `
      h1 {
        font-family: Lato;
      }
    `
  ]
})

For anyone (future me included) trying this with form control and not ngModel, you can do it like so:

<mat-select #mSelect formControlName="controlName">
  <mat-select-trigger>
    <span [innerHTML]="htmlArray[mSelect.value]"></span>
  </mat-select-trigger>
  <mat-option *ngFor="let html of htmlArray; let idx = index"
              [value]="idx">
     <span [innerHTML]="html"></span>
  </mat-option>
</mat-select>

I was digging into the issue and I found out its a bug within unicode conversion while exporting the hello component.

To fix this issue replace your code with one below

import { Component, Input } from '@angular/core';
import {
svg,
img,
png,
png2x,
png3x,
aliases,
icons,
iconsByUnicodeHex
} from 'font-awesome-assets';

@Component({
selector: 'hello',
template: `
<mat-form-field>
<mat-select [(ngModel)]="nodeType" placeholder="NodeType">
<mat-option *ngFor="let item of nodeTypes" [value]="item">
<span [innerHTML]="item.iconHtml"></span>
<span> {{item.label}}</span>
</mat-option>
</mat-select>
</mat-form-field>`,
styles: [`h1 { font-family: Lato; }`] 
})

export class HelloComponent  {
@Input() name: string;
nodeType ;
nodeTypes = [ 
{
  label: 'Task',
  iconHtml: '<i class="fa">&#xf0e7;</i>'
}, 
{
  label: 'Project',
  iconHtml: svg('briefcase', rgba(0,0,0,0.5))
}
]

ngOnInit() {
this.nodeType = this.nodeTypes[1];
}
}

It should ask you to install the missing package of font-awesome library when your replace your code

Install it and it should work ... let me know if you had any issue

good luck

Related