Skip to content

Commit

Permalink
feat(module:table): support default filter
Browse files Browse the repository at this point in the history
close #1872

add spec and fix bug
  • Loading branch information
Wendell committed Aug 3, 2018
1 parent 8e7a6cb commit 439b65f
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 10 deletions.
14 changes: 14 additions & 0 deletions components/table/demo/default-filter.md
Original file line number Diff line number Diff line change
@@ -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.
83 changes: 83 additions & 0 deletions components/table/demo/default-filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Component } from '@angular/core';

@Component({
selector: 'nz-demo-table-default-filter',
template: `
<nz-table #filterTable [nzData]="displayData">
<thead (nzSortChange)="sort($event)" nzSingleSort>
<tr>
<th nzShowSort nzSortKey="name" nzShowFilter [nzFilters]="nameList" (nzFilterChange)="filter($event,searchAddress)">Name</th>
<th nzShowSort nzSortKey="age">Age</th>
<th nzShowSort nzSortKey="address" nzShowFilter [nzFilterMultiple]="false" [nzFilters]="addressList" (nzFilterChange)="filter(listOfSearchName,$event)">Address</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of filterTable.data">
<td>{{data.name}}</td>
<td>{{data.age}}</td>
<td>{{data.address}}</td>
</tr>
</tbody>
</nz-table>`
})
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;
}
}
}
2 changes: 1 addition & 1 deletion components/table/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<any[] 丨 any>` | - |

Expand Down
2 changes: 1 addition & 1 deletion components/table/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<any[]丨 any>` | - |

Expand Down
26 changes: 19 additions & 7 deletions components/table/nz-th.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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[] = [];
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
104 changes: 103 additions & 1 deletion components/table/nz-th.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('nz-th', () => {
beforeEach(fakeAsync(() => {
TestBed.configureTestingModule({
imports : [ NzTableModule ],
declarations: [ NzThTestNzTableComponent ],
declarations: [ NzThTestNzTableComponent, NzThTestTableDefaultFilterComponent ],
providers : [ NzMeasureScrollbarService ]
});
TestBed.compileComponents();
Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -314,6 +332,90 @@ export class NzThTestNzTableComponent {
expand = false;
}

@Component({
selector: 'nz-demo-table-default-filter',
template: `
<nz-table #filterTable [nzData]="displayData">
<thead (nzSortChange)="sort($event)" nzSingleSort>
<tr>
<th nzShowSort nzSortKey="name" nzShowFilter [nzFilters]="nameList" (nzFilterChange)="filter($event,searchAddress)">Name</th>
<th nzShowSort nzSortKey="age">Age</th>
<th nzShowSort nzSortKey="address" nzShowFilter [nzFilterMultiple]="false" [nzFilters]="addressList" (nzFilterChange)="filter(listOfSearchName,$event)">Address</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of filterTable.data">
<td>{{data.name}}</td>
<td>{{data.age}}</td>
<td>{{data.address}}</td>
</tr>
</tbody>
</nz-table>`
})
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: `
Expand Down

0 comments on commit 439b65f

Please sign in to comment.