Select

Select.

Examples

Basic Usage

Simplest of usage.

expand codeexpand code
import { Component, ViewChild } from '@angular/core';
import { SFComponent, SFSchema, SFSelectWidgetSchema } from '@delon/form';
import { NzMessageService } from 'ng-zorro-antd/message';
import { of, delay } from 'rxjs';

@Component({
  selector: 'form-select-simple',
  template: `
    <sf #sf [schema]="schema" (formSubmit)="submit($event)"></sf>
    <button nz-button (click)="updateStatus()">Update Status</button>
  `,
})
export class FormSelectSimpleComponent {
  @ViewChild('sf', { static: false }) private sf!: SFComponent;
  schema: SFSchema = {
    properties: {
      status: {
        type: 'string',
        title: '状态',
        enum: [
          { label: '待支付', value: 'WAIT_BUYER_PAY', otherData: 1 },
          { label: '已支付', value: 'TRADE_SUCCESS' },
          { label: '交易完成', value: 'TRADE_FINISHED' },
        ],
        default: 'WAIT_BUYER_PAY',
        ui: {
          widget: 'select',
          change: (value, orgData) => console.log(value, orgData),
        } as SFSelectWidgetSchema,
      },
      // 标签
      tags: {
        type: 'string',
        title: '标签',
        enum: [
          { label: '待支付', value: 'WAIT_BUYER_PAY' },
          { label: '已支付', value: 'TRADE_SUCCESS' },
          { label: '交易完成', value: 'TRADE_FINISHED' },
        ],
        ui: {
          widget: 'select',
          mode: 'tags',
        } as SFSelectWidgetSchema,
        default: null,
      },
      // 异步数据
      async: {
        type: 'string',
        title: 'Async',
        default: 'WAIT_BUYER_PAY',
        ui: {
          widget: 'select',
          asyncData: () =>
            of([
              {
                label: '订单状态',
                group: true,
                children: [
                  { label: '待支付', value: 'WAIT_BUYER_PAY' },
                  { label: '已支付', value: 'TRADE_SUCCESS' },
                  { label: '交易完成', value: 'TRADE_FINISHED' },
                ],
              },
            ]).pipe(delay(1200)),
        } as SFSelectWidgetSchema,
      },
    },
  };

  constructor(private msg: NzMessageService) {}

  submit(value: {}): void {
    this.msg.success(JSON.stringify(value));
  }

  updateStatus(): void {
    const statusProperty = this.sf.getProperty('/status')!;
    statusProperty.schema.enum = ['1', '2', '3'];
    statusProperty.widget.reset('2');
  }
}
coordinate

Coordinating the selection of provinces and cities is a common use case and demonstrates how selection can be coordinated.

expand codeexpand code
import { Component, ViewChild } from '@angular/core';
import { SFComponent, SFSchema, SFSelectWidgetSchema } from '@delon/form';
import { NzMessageService } from 'ng-zorro-antd/message';
import { of, delay, tap } from 'rxjs';

@Component({
  selector: 'form-select-coordinate',
  template: ` <sf #sf [schema]="schema" [formData]="data" (formSubmit)="submit($event)"></sf> `,
})
export class FormSelectCoordinateComponent {
  @ViewChild('sf', { static: false }) private sf!: SFComponent;
  data = {
    province: 'Zhejiang',
    city: 'Ningbo',
  };
  private cityData: { [place: string]: string[] } = {
    Zhejiang: ['Hangzhou', 'Ningbo', 'Wenzhou'],
    Jiangsu: ['Nanjing', 'Suzhou', 'Zhenjiang'],
  };
  schema: SFSchema = {
    properties: {
      province: {
        type: 'string',
        title: 'Province',
        ui: {
          widget: 'select',
          asyncData: () =>
            of(['Zhejiang', 'Jiangsu']).pipe(
              delay(100),
              tap(() => this.updateCity(this.data.province, this.data.city)),
            ),
          change: i => this.updateCity(i),
        } as SFSelectWidgetSchema,
      },
      city: {
        type: 'string',
        title: 'City',
        ui: {
          widget: 'select',
        } as SFSelectWidgetSchema,
      },
    },
  };

  constructor(private msg: NzMessageService) {}

  submit(value: {}): void {
    this.msg.success(JSON.stringify(value));
  }

  private updateCity(province: string, city: string = ''): void {
    const cityProperty = this.sf.getProperty('/city')!;
    const items = this.cityData[province];
    cityProperty.schema.enum = items;
    cityProperty.widget.reset(city || items[0]);
  }
}
Custom dropdown

Customize the dropdown menu via dropdownRender.

expand codeexpand code
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { SFComponent, SFSchema, SFSelectWidgetSchema } from '@delon/form';
import { NzMessageService } from 'ng-zorro-antd/message';

@Component({
  selector: 'form-select-custom-dropdown-menu',
  template: `
    <sf #sf *ngIf="schema" [schema]="schema" (formSubmit)="submit($event)"></sf>
    <ng-template #dropdownRender>
      <nz-divider></nz-divider>
      <div class="container">
        <input type="text" nz-input #inputElement />
        <a class="add-item" (click)="addItem(inputElement)"><i nz-icon nzType="plus"></i> Add item</a>
      </div>
    </ng-template>
  `,
  styles: [
    `
      nz-divider {
        margin: 4px 0;
      }
      .container {
        display: flex;
        flex-wrap: nowrap;
        padding: 8px;
      }
      input {
      }
      .add-item {
        flex: 0 0 auto;
        padding: 8px;
        display: block;
      }
    `,
  ],
})
export class FormSelectCustomDropdownMenuComponent implements OnInit {
  @ViewChild('sf', { static: false }) private sf!: SFComponent;
  @ViewChild('dropdownRender', { static: true }) private dropdownRender!: TemplateRef<void>;

  schema?: SFSchema;
  statusList: string[] = ['1', '2', '3'];

  constructor(private msg: NzMessageService) {}

  submit(value: {}): void {
    this.msg.success(JSON.stringify(value));
  }

  ngOnInit(): void {
    this.schema = {
      properties: {
        status: {
          type: 'string',
          title: '状态',
          enum: this.statusList,
          default: '1',
          ui: {
            widget: 'select',
            dropdownRender: this.dropdownRender,
          } as SFSelectWidgetSchema,
        },
      },
    };
  }

  addItem(input: HTMLInputElement): void {
    this.statusList.push(input.value);
    const statusProperty = this.sf.getProperty('/status')!;
    statusProperty.schema.enum = this.statusList;
    this.sf.setValue('/status', input.value);
  }
}
Search and Select Users

A complete multiple select sample with remote search, debounce fetch, ajax callback order flow, and loading state.

expand codeexpand code
import { Component } from '@angular/core';
import { SFSchema, SFSchemaEnum, SFSelectWidgetSchema } from '@delon/form';
import { _HttpClient } from '@delon/theme';
import { NzMessageService } from 'ng-zorro-antd/message';
import { map } from 'rxjs';

@Component({
  selector: 'form-select-search',
  template: ` <sf [schema]="schema" (formSubmit)="submit($event)"></sf> `,
})
export class FormSelectSearchComponent {
  schema: SFSchema = {
    properties: {
      status: {
        type: 'string',
        title: '用户',
        ui: {
          widget: 'select',
          serverSearch: true,
          searchDebounceTime: 300,
          searchLoadingText: '搜索中...',
          onSearch: q => {
            return this.http
              .get(`https://api.randomuser.me/?results=5&q=${q}`)
              .pipe(map(res => (res.results as any[]).map(i => ({ label: i.email, value: i.email } as SFSchemaEnum))))
              .toPromise();
          },
        } as SFSelectWidgetSchema,
      },
    },
  };

  constructor(private msg: NzMessageService, private http: _HttpClient) {}

  submit(value: {}): void {
    this.msg.success(JSON.stringify(value));
  }
}

API

schema

PropertyDescriptionTypeDefault
[enum]Data sourceSFSchemaEnumType[]-
[readOnly]Read onlyboolean-

ui

PropertyDescriptionTypeDefault
[asyncData]Asynchronous static data source() => Observable<SFSchemaEnumType[]>-
[size]Size, equals to nzSizestring-
[compareWith]Same with SelectControlValueAccessor(o1: any, o2: any) => boolean(o1: any, o2: any) => o1===o2
[placeholder]Placeholderstring-
[autoClearSearchValue]Whether clear search box when an option is selected, only valid when mode is multiple or tags.booleantrue
[allowClear]Allow clearbooleanfalse
[borderless]Whether has borderbooleanfalse
[autoFocus]Focused by defaultbooleanfalse
[dropdownClassName]className property of dropdown liststring-
[dropdownMatchSelectWidth]Dropdown list and select have same widthbooleantrue
[dropdownStyle]style property of dropdown listobject-
[serverSearch]Whether using server search, won't fliter nz-option in frontend when it is truebooleanfalse
[searchDebounceTime]Debounce time of server searchnumber300
[searchLoadingText]Loading text of searchingstring-
[onSearch]Callback when search content is changed, parameter is search content, must return Promise object(text: string) => Promise<SFSchemaEnum[]>-
[maxMultipleCount]Maximum selected labelsnumberInfinity
[mode]Set mode for nz-select, suggest to add default: null for tags, otherwise, it would initialize an empty label.multiple,tags,defaultdefault
[notFoundContent]Content when dropdown list is emptystring-
[showSearch]Enable search for signle select modebooleanfalse
[showArrow]Whether to show the drop-down arrowbooleantrue(for single select), false(for multiple select)
[tokenSeparators]Separator for automatic word segmentation when it is tags and multiple modestring[][]
[maxTagCount]Maximum count of tagnumber-
[change]Callback function when selected nz-option is changed(ngModel:any丨any[], orgData: SFSchemaEnum丨SFSchemaEnum[])=>void-
[openChange]Callback function when dropdown list is open or closed(status: boolean) => void-
[scrollToBottom]Callback function when dropdown list is scrolled to bottom, can be used to trigger dynamic load() => void-