Mention

Mention component.

When To Use#

When need to mention someone or something.

Import this Component Individually#

You can get more detail here.

import { NzMentionModule } from 'ng-zorro-antd/mention';

Examples

Basic usage.

expand codeexpand code
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'nz-demo-mention-basic',
  encapsulation: ViewEncapsulation.None,
  template: `
    <nz-mention [nzSuggestions]="suggestions" (nzOnSelect)="onSelect($event)">
      <input
        placeholder="input here"
        nzMentionTrigger
        nz-input
        [(ngModel)]="inputValue"
        (ngModelChange)="onChange($event)"
      />
    </nz-mention>
  `
})
export class NzDemoMentionBasicComponent {
  inputValue: string = '@afc163';
  suggestions = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];

  onChange(value: string): void {
    console.log(value);
  }

  onSelect(suggestion: string): void {
    console.log(`onSelect ${suggestion}`);
  }
}

async

expand codeexpand code
import { Component, ViewEncapsulation } from '@angular/core';
import { MentionOnSearchTypes } from 'ng-zorro-antd/mention';

@Component({
  selector: 'nz-demo-mention-async',
  encapsulation: ViewEncapsulation.None,
  template: `
    <nz-mention [nzSuggestions]="suggestions" [nzLoading]="loading" (nzOnSearchChange)="onSearchChange($event)">
      <input nzMentionTrigger nz-input [(ngModel)]="inputValue" />
    </nz-mention>
  `
})
export class NzDemoMentionAsyncComponent {
  inputValue: string;
  loading = false;
  suggestions: string[] = [];

  onSearchChange({ value }: MentionOnSearchTypes): void {
    console.log(`search: ${value}`);
    this.loading = true;
    this.fetchSuggestions(value, suggestions => {
      console.log(suggestions);
      this.suggestions = suggestions;
      this.loading = false;
    });
  }

  fetchSuggestions(value: string, callback: (suggestions: string[]) => void): void {
    const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai'];
    setTimeout(() => {
      return callback(users.filter(item => item.indexOf(value) !== -1));
    }, 500);
  }
}

Customize suggestions.

expand codeexpand code
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'nz-demo-mention-avatar',
  encapsulation: ViewEncapsulation.None,
  template: `
    <nz-mention [nzSuggestions]="webFrameworks" [nzValueWith]="valueWith" (nzOnSelect)="onSelect($event)">
      <input nz-input nzMentionTrigger [(ngModel)]="inputValue" />
      <ng-container *nzMentionSuggestion="let framework">
        <nz-avatar nzSize="small" [nzText]="framework.name" [nzSrc]="framework.icon"></nz-avatar>
        <span>{{ framework.name }} - {{ framework.type }}</span>
      </ng-container>
    </nz-mention>
  `,
  styles: [
    `
      .ant-avatar.ant-avatar-sm {
        width: 14px;
        height: 14px;
        margin-right: 8px;
        position: relative;
      }
    `
  ]
})
export class NzDemoMentionAvatarComponent {
  inputValue: string;
  webFrameworks = [
    { name: 'React', type: 'JavaScript', icon: 'https://zos.alipayobjects.com/rmsportal/LFIeMPzdLcLnEUe.svg' },
    { name: 'Angular', type: 'JavaScript', icon: 'https://zos.alipayobjects.com/rmsportal/PJTbxSvzYWjDZnJ.png' },
    { name: 'Dva', type: 'Javascript', icon: 'https://zos.alipayobjects.com/rmsportal/EYPwSeEJKxDtVxI.png' },
    { name: 'Flask', type: 'Python', icon: 'https://zos.alipayobjects.com/rmsportal/xaypBUijfnpAlXE.png' }
  ];

  valueWith = (data: { name: string; type: string; icon: string }) => data.name;

  onSelect(value: string): void {
    console.log(value);
  }
}

Multi lines mode.

expand codeexpand code
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'nz-demo-mention-multilines',
  encapsulation: ViewEncapsulation.None,
  template: `
    <nz-mention [nzSuggestions]="suggestions">
      <textarea nz-input [nzAutosize]="{ minRows: 4, maxRows: 4 }" [(ngModel)]="inputValue" nzMentionTrigger>
      </textarea>
    </nz-mention>
  `
})
export class NzDemoMentionMultilinesComponent {
  inputValue: string;
  suggestions = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];
}

Customize Trigger Token by nzPrefix props. Default to @, Array<string> also supported.

expand codeexpand code
import { Component, ViewEncapsulation } from '@angular/core';
import { MentionOnSearchTypes } from 'ng-zorro-antd/mention';

@Component({
  selector: 'nz-demo-mention-multiple-trigger',
  encapsulation: ViewEncapsulation.None,
  template: `
    <nz-mention [nzSuggestions]="suggestions" (nzOnSearchChange)="onSearchChange($event)" [nzPrefix]="['#', '@']">
      <input
        placeholder="input @ to mention people, # to mention tag"
        nzMentionTrigger
        nz-input
        [(ngModel)]="inputValue"
      />
    </nz-mention>
  `
})
export class NzDemoMentionMultipleTriggerComponent {
  inputValue: string;
  suggestions: string[] = [];
  users = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];
  tags = ['1.0', '2.0', '3.0'];

  onSearchChange({ value, prefix }: MentionOnSearchTypes): void {
    console.log('nzOnSearchChange', value, prefix);
    this.suggestions = prefix === '@' ? this.users : this.tags;
  }
}

Change the suggestions placement.

expand codeexpand code
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'nz-demo-mention-placement',
  encapsulation: ViewEncapsulation.None,
  template: `
    <nz-mention nzPlacement="top" [nzSuggestions]="suggestions" (nzOnSelect)="onSelect($event)">
      <input nzMentionTrigger nz-input [(ngModel)]="inputValue" (ngModelChange)="onChange($event)" />
    </nz-mention>
  `
})
export class NzDemoMentionPlacementComponent {
  inputValue: string;
  suggestions = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];

  onChange(value: string): void {
    console.log(value);
  }

  onSelect(suggestion: string): void {
    console.log(`onSelect ${suggestion}`);
  }
}

Customize suggestions.

expand codeexpand code
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'nz-demo-mention-custom-tag',
  encapsulation: ViewEncapsulation.None,
  template: `
    <nz-mention [nzSuggestions]="webFrameworks" [nzValueWith]="valueWith" (nzOnSelect)="onSelect($event)">
      <input placeholder="@someone" nz-input nzMentionTrigger [(ngModel)]="inputValue" />
      <ng-container *nzMentionSuggestion="let framework">
        <span>{{ framework.name }} - {{ framework.type }}</span>
      </ng-container>
    </nz-mention>
  `
})
export class NzDemoMentionCustomTagComponent {
  inputValue: string;
  webFrameworks = [
    { name: 'React', type: 'JavaScript' },
    { name: 'Angular', type: 'JavaScript' },
    { name: 'Laravel', type: 'PHP' },
    { name: 'Flask', type: 'Python' },
    { name: 'Django', type: 'Python' }
  ];

  valueWith = (data: { name: string; type: string }) => data.name;

  onSelect(value: string): void {
    console.log(value);
  }
}
   

Controlled mode, for example, to work with Form.

expand codeexpand code
import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'nz-demo-mention-controlled',
  encapsulation: ViewEncapsulation.None,
  template: `
    <form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
      <nz-form-item>
        <nz-form-label [nzSm]="6" nzFor="mention">Top coders</nz-form-label>
        <nz-form-control [nzSm]="16" nzErrorTip="More than one must be selected!">
          <nz-mention #mentions [nzSuggestions]="suggestions">
            <input id="mention" placeholder="input here" formControlName="mention" nzMentionTrigger nz-input />
          </nz-mention>
        </nz-form-control>
      </nz-form-item>
      <nz-form-item nz-row style="margin-bottom:8px;">
        <nz-form-control [nzSpan]="14" [nzOffset]="6">
          <button type="button" nz-button nzType="primary" (click)="submitForm()">Submit</button>
          &nbsp;&nbsp;&nbsp;
          <button type="button" nz-button (click)="resetForm()">Reset</button>
        </nz-form-control>
      </nz-form-item>
    </form>
  `
})
export class NzDemoMentionControlledComponent implements OnInit {
  suggestions = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];
  validateForm: FormGroup;
  @ViewChild('mentions', { static: true }) mentionChild: any;

  get mention(): AbstractControl {
    return this.validateForm.get('mention')!;
  }

  constructor(private fb: FormBuilder) {}

  ngOnInit(): void {
    this.validateForm = this.fb.group({
      mention: ['@afc163 ', [Validators.required, this.mentionValidator]]
    });
  }

  mentionValidator = (control: FormControl): { [s: string]: boolean } => {
    if (!control.value) {
      return { required: true };
    } else if (this.mentionChild.getMentions().length < 2) {
      return { confirm: true, error: true };
    }
    return {};
  };

  submitForm(): void {
    this.mention.markAsDirty();
    this.mention.updateValueAndValidity();
    if (this.mention.valid) {
      console.log('Submit!!!', this.mention.value);
      console.log(this.mentionChild.getMentions());
    } else {
      console.log('Errors in form!!!');
    }
  }

  resetForm(): void {
    this.validateForm.reset({
      mention: '@afc163 '
    });
  }
}

Configurate disabled and readOnly.

expand codeexpand code
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'nz-demo-mention-readonly',
  encapsulation: ViewEncapsulation.None,
  template: `
    <nz-mention [nzSuggestions]="suggestions">
      <input
        style="margin-bottom: 10px"
        placeholder="this is disabled Mention"
        nzMentionTrigger
        nz-input
        disabled
        [(ngModel)]="inputValue"
      />
      <input placeholder="this is readOnly Mention" nzMentionTrigger nz-input readOnly [(ngModel)]="inputValue" />
    </nz-mention>
  `
})
export class NzDemoMentionReadonlyComponent {
  inputValue: string;
  suggestions = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];
}

Rendering the mentions.

expand codeexpand code
import { Component, ViewEncapsulation } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@Component({
  selector: 'nz-demo-mention-preview',
  encapsulation: ViewEncapsulation.None,
  template: `
    <nz-tabset>
      <nz-tab nzTitle="Write">
        <nz-mention [nzSuggestions]="suggestions">
          <textarea
            nz-input
            [nzAutosize]="{ minRows: 4, maxRows: 4 }"
            [(ngModel)]="inputValue"
            (ngModelChange)="renderPreView()"
            nzMentionTrigger
          >
          </textarea>
        </nz-mention>
      </nz-tab>
      <nz-tab nzTitle="Preview">
        <pre [innerHTML]="preview"></pre>
      </nz-tab>
    </nz-tabset>
  `
})
export class NzDemoMentionPreviewComponent {
  inputValue: string = 'Switch tab view preview @NG-ZORRO ';
  preview: SafeHtml;
  suggestions = ['NG-ZORRO', 'angular', 'Reactive-Extensions'];

  constructor(private sanitizer: DomSanitizer) {
    this.renderPreView();
  }

  getRegExp(prefix: string | string[]): RegExp {
    const prefixArray = Array.isArray(prefix) ? prefix : [prefix];
    let prefixToken = prefixArray.join('').replace(/(\$|\^)/g, '\\$1');

    if (prefixArray.length > 1) {
      prefixToken = `[${prefixToken}]`;
    }

    return new RegExp(`(\\s|^)(${prefixToken})[^\\s]*`, 'g');
  }

  renderPreView(): void {
    if (this.inputValue) {
      const regex = this.getRegExp('@');
      const previewValue = this.inputValue.replace(
        regex,
        match => `<a target="_blank" href="https://github.com/${match.trim().substring(1)}">${match}</a>`
      );
      this.preview = this.sanitizer.bypassSecurityTrustHtml(previewValue);
    }
  }
}

API#

<nz-mention [nzSuggestions]="suggestions">
 <textarea
    nz-input
    [(ngModel)]="value"
    nzMentionTrigger>
  </textarea>
</nz-mention>

nz-mention#

PropertyDescriptionTypeDefault
[nzMentionTrigger]Trigger element (required)HTMLTextAreaElement | HTMLInputElement-
[nzMentionSuggestion]Customize the suggestion templateTemplateRef<any>-
[nzLoading]Loading modebooleanfalse
[nzNotFoundContent]Suggestion when suggestions emptystring'无匹配结果,轻敲空格完成输入'
[nzPlacement]The position of the suggestion relative to the target, which can be one of top and bottom'button' | 'top''bottom'
[nzPrefix]Character which will trigger Mention to show mention liststring | string[]'@'
[nzSuggestions]Suggestion contentany[][]
[nzValueWith]Function that maps an suggestion's value(any) => string | (value: string) => string
(nzOnSelect)Callback function called when select from suggestionsEventEmitter<any>-
(nzOnSearchChange)Callback function called when search content changesEventEmitter<MentionOnSearchTypes>-

Methods#

NameDescription
getMentionsGet the mentions array in the input[nzMentionTrigger]

nzMentionTrigger#

Trigger element

<nz-mention>
 <textarea nzMentionTrigger></textarea>
</nz-mention>
<nz-mention>
 <input nzMentionTrigger>
</nz-mention>

nzMentionSuggestion#

Customize the suggestion template

  <nz-mention
    [nzSuggestions]="items"
    [nzValueWith]="valueWith">
    <input nz-input nzMentionTrigger>
    <ng-container *nzMentionSuggestion="let item">
        <span>{{ item.label }} - {{ item.value }}</span>
    </ng-container>
  </nz-mention>

MentionOnSearchTypes#

PropertyDescriptionTypeDefault
valueSearch keywordstring-
prefixprefixstring-