diff --git a/components/table/demo/default-filter.md b/components/table/demo/default-filter.md new file mode 100644 index 00000000000..2b28d5f9308 --- /dev/null +++ b/components/table/demo/default-filter.md @@ -0,0 +1,14 @@ +--- + order: 6 + title: + en-US: Default filter + zh-CN: 默认筛选 +--- + +## zh-CN + +通过设置 filter 对象的 `{ byDefault: true }` 属性来默认启用一个筛选器。注意,你必须同时自行设置过滤后应当展示的列表项,为了保持数据流的清晰和数据的一致性,ng-zorro 不会为你做这项工作。详情请见 demo。 + +## en-US + +you can enable a filter by default by setting a `filter` object's property: `{ byDefault: true }`. Be aware that you should set the filtered table contents by yourself. In order to keep clarity and consistency of data, ng-zorro would not do default filtering for you. Please refer to the demo. \ No newline at end of file diff --git a/components/table/demo/default-filter.ts b/components/table/demo/default-filter.ts new file mode 100644 index 00000000000..ae77c040f38 --- /dev/null +++ b/components/table/demo/default-filter.ts @@ -0,0 +1,83 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-table-default-filter', + template: ` + + + + Name + Age + Address + + + + + {{data.name}} + {{data.age}} + {{data.address}} + + + ` +}) +export class NzDemoTableDefaultFilterComponent { + nameList = [ + { text: 'Joe', value: 'Joe', byDefault: true }, + { text: 'Jim', value: 'Jim' } + ]; + addressList = [ + { text: 'London', value: 'London', byDefault: true }, + { text: 'Sidney', value: 'Sidney' } + ]; + sortName = null; + sortValue = null; + listOfSearchName = [ 'Joe', 'London' ]; // You need to change it as well! + searchAddress: string; + data = [ + { + name: 'John Brown', + age: 32, + address: 'New York No. 1 Lake Park' + }, + { + name: 'Jim Green', + age: 42, + address: 'London No. 1 Lake Park' + }, + { + name: 'Joe Black', + age: 32, + address: 'Sidney No. 1 Lake Park' + }, + { + name: 'Jim Red', + age: 32, + address: 'London No. 2 Lake Park' + } + ]; + displayData = [ ]; // You need to change it as well! + + sort(sort: { key: string, value: string }): void { + this.sortName = sort.key; + this.sortValue = sort.value; + this.search(); + } + + filter(listOfSearchName: string[], searchAddress: string): void { + this.listOfSearchName = listOfSearchName; + this.searchAddress = searchAddress; + this.search(); + } + + search(): void { + /** filter data **/ + const filterFunc = item => (this.searchAddress ? item.address.indexOf(this.searchAddress) !== -1 : true) && (this.listOfSearchName.length ? this.listOfSearchName.some(name => item.name.indexOf(name) !== -1) : true); + const data = this.data.filter(item => filterFunc(item)); + /** sort data **/ + if (this.sortName) { + this.displayData = data.sort((a, b) => (this.sortValue === 'ascend') ? (a[ this.sortName ] > b[ this.sortName ] ? 1 : -1) : (b[ this.sortName ] > a[ this.sortName ] ? 1 : -1)); + } else { + this.displayData = data; + } + } +} diff --git a/components/table/doc/index.en-US.md b/components/table/doc/index.en-US.md index d7e2b10165d..4eb1058672c 100644 --- a/components/table/doc/index.en-US.md +++ b/components/table/doc/index.en-US.md @@ -109,7 +109,7 @@ Filter property | Property | Description | Type | Default | | -------- | ----------- | ---- | ------- | | `[nzShowFilter]` | Whether show filter | boolean | - | -| `[nzFilters]` | Filter options, `text`,and `value` for callback | `Array<{ text: string; value: any }>` | - | +| `[nzFilters]` | Filter options, `text`, and `value` for callback, `byDefault` to enable filter by default | `Array<{ text: string; value: any; byDefault?: boolean }>` | - | | `[nzFilterMultiple]` | Whether filter multiple mode | boolean | true | | `(nzFilterChange)` | Filter change callback `value` | `EventEmitter` | - | diff --git a/components/table/doc/index.zh-CN.md b/components/table/doc/index.zh-CN.md index 0b740d2d5ef..773fce86093 100644 --- a/components/table/doc/index.zh-CN.md +++ b/components/table/doc/index.zh-CN.md @@ -118,7 +118,7 @@ Table 组件同时具备了易用性和高度可定制性 | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | `[nzShowFilter]` | 是否显示过滤 | boolean | - | -| `[nzFilters]` | 过滤器内容, 显示数据 `text`,回调函数传出 `value` | `Array<{ text: string; value: any }>` | - | +| `[nzFilters]` | 过滤器内容, 显示数据 `text`,回调函数传出 `value`,设置 `byDefault` 以默认应用过滤规则 | `Array<{ text: string; value: any; byDefault?: boolean }>` | - | | `[nzFilterMultiple]` | 是否为多选过滤器 | boolean | true | | `(nzFilterChange)` | 过滤器内容选择的 value 数据回调 | `EventEmitter` | - | diff --git a/components/table/nz-th.component.ts b/components/table/nz-th.component.ts index 715b145d977..888d896c7d8 100644 --- a/components/table/nz-th.component.ts +++ b/components/table/nz-th.component.ts @@ -15,7 +15,7 @@ import { toBoolean } from '../core/util/convert'; import { NzDropDownComponent } from '../dropdown/nz-dropdown.component'; /* tslint:disable-next-line:no-any */ -export type NzThFilterType = Array<{ text: string; value: any }>; +export type NzThFilterType = Array<{ text: string; value: any; byDefault?: boolean }>; export interface NzThItemInterface { text: string; @@ -37,6 +37,7 @@ export class NzThComponent { private _showFilter = false; private _showCheckbox = false; private _showRowSelection = false; + private _hasDefaultFilter = false; el: HTMLElement; hasFilterValue = false; multipleFilterList: NzThItemInterface[] = []; @@ -192,8 +193,8 @@ export class NzThComponent { } reset(): void { - this.initMultipleFilterList(); - this.initSingleFilterList(); + this.initMultipleFilterList(true); + this.initSingleFilterList(true); this.search(); this.hideDropDown(); this.hasFilterValue = false; @@ -234,16 +235,27 @@ export class NzThComponent { return this._filters; } - initMultipleFilterList(): void { + initMultipleFilterList(force?: boolean): void { this.multipleFilterList = this.nzFilters.map(item => { - return { text: item.text, value: item.value, checked: false }; + const checked = force ? false : !!item.byDefault; + if (checked) { this._hasDefaultFilter = true; } + return { text: item.text, value: item.value, checked }; }); + this.checkDefaultFilters(); } - initSingleFilterList(): void { + initSingleFilterList(force?: boolean): void { this.singleFilterList = this.nzFilters.map(item => { - return { text: item.text, value: item.value, checked: false }; + const checked = force ? false : !!item.byDefault; + if (checked) { this._hasDefaultFilter = true; } + return { text: item.text, value: item.value, checked }; }); + this.checkDefaultFilters(); + } + + checkDefaultFilters(): void { + if (!this.nzFilters || this.nzFilters.length === 0 || !this._hasDefaultFilter) { return; } + this.updateFilterStatus(); } constructor(private elementRef: ElementRef, private renderer: Renderer2) { diff --git a/components/table/nz-th.spec.ts b/components/table/nz-th.spec.ts index 96e20097a83..44ced2ad3e7 100644 --- a/components/table/nz-th.spec.ts +++ b/components/table/nz-th.spec.ts @@ -10,7 +10,7 @@ describe('nz-th', () => { beforeEach(fakeAsync(() => { TestBed.configureTestingModule({ imports : [ NzTableModule ], - declarations: [ NzThTestNzTableComponent ], + declarations: [ NzThTestNzTableComponent, NzThTestTableDefaultFilterComponent ], providers : [ NzMeasureScrollbarService ] }); TestBed.compileComponents(); @@ -256,6 +256,24 @@ describe('nz-th', () => { }).toThrow(); }); }); + describe('nz-th with default filter in nz-table', () => { + let fixture; + let testComponent; + let th; + let table; + beforeEach(() => { + fixture = TestBed.createComponent(NzThTestTableDefaultFilterComponent); + fixture.detectChanges(); + testComponent = fixture.debugElement.componentInstance; + th = fixture.debugElement.query(By.directive(NzThComponent)); + table = fixture.debugElement.query(By.directive(NzTableComponent)); + }); + // It's a fake test to pass codecov, because default displayData should be configured by user. + it('should default filter work', () => { + expect(testComponent.displayData.length).toBe(0); + expect(testComponent.nzThComponent.hasFilterValue).toBe(true); + }); + }); }); @Component({ @@ -314,6 +332,90 @@ export class NzThTestNzTableComponent { expand = false; } +@Component({ + selector: 'nz-demo-table-default-filter', + template: ` + + + + Name + Age + Address + + + + + {{data.name}} + {{data.age}} + {{data.address}} + + + ` +}) +export class NzThTestTableDefaultFilterComponent { + nameList = [ + { text: 'Joe', value: 'Joe', byDefault: true }, + { text: 'Jim', value: 'Jim' } + ]; + addressList = [ + { text: 'London', value: 'London', byDefault: true }, + { text: 'Sidney', value: 'Sidney' } + ]; + sortName = null; + sortValue = null; + listOfSearchName = [ 'Joe', 'London' ]; + searchAddress: string; + data = [ + { + name: 'John Brown', + age: 32, + address: 'New York No. 1 Lake Park' + }, + { + name: 'Jim Green', + age: 42, + address: 'London No. 1 Lake Park' + }, + { + name: 'Joe Black', + age: 32, + address: 'Sidney No. 1 Lake Park' + }, + { + name: 'Jim Red', + age: 32, + address: 'London No. 2 Lake Park' + } + ]; + displayData = [ ]; + + @ViewChild(NzThComponent) nzThComponent: NzThComponent; + + sort(sort: { key: string, value: string }): void { + this.sortName = sort.key; + this.sortValue = sort.value; + this.search(); + } + + filter(listOfSearchName: string[], searchAddress: string): void { + this.listOfSearchName = listOfSearchName; + this.searchAddress = searchAddress; + this.search(); + } + + search(): void { + /** filter data **/ + const filterFunc = item => (this.searchAddress ? item.address.indexOf(this.searchAddress) !== -1 : true) && (this.listOfSearchName.length ? this.listOfSearchName.some(name => item.name.indexOf(name) !== -1) : true); + const data = this.data.filter(item => filterFunc(item)); + /** sort data **/ + if (this.sortName) { + this.displayData = data.sort((a, b) => (this.sortValue === 'ascend') ? (a[ this.sortName ] > b[ this.sortName ] ? 1 : -1) : (b[ this.sortName ] > a[ this.sortName ] ? 1 : -1)); + } else { + this.displayData = data; + } + } +} + @Component({ selector: 'nz-disable-th', template: `