Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(module:table): support default filter #1893

Merged
merged 1 commit into from
Aug 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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