From 035db2d84c4349ad8ff55494ce2ccd2453a66c65 Mon Sep 17 00:00:00 2001 From: Nicolas Boix Date: Fri, 22 Nov 2024 16:42:46 +0100 Subject: [PATCH 1/3] feat(module:table): mode hide only for nzCustomColumn (no flex css) --- components/table/doc/index.en-US.md | 8 +- .../table/src/cell/custom-column.directive.ts | 26 ++- components/table/src/table-data.service.ts | 5 +- components/table/src/table.types.ts | 5 + components/table/src/table/table.component.ts | 7 +- .../table/src/testing/custom-column.spec.ts | 196 +++++++++++++----- 6 files changed, 182 insertions(+), 65 deletions(-) diff --git a/components/table/doc/index.en-US.md b/components/table/doc/index.en-US.md index c402d81905e..5dd7bda0766 100644 --- a/components/table/doc/index.en-US.md +++ b/components/table/doc/index.en-US.md @@ -67,7 +67,7 @@ The data passed to `[nzData]` is exported with [Template Context](https://angula | `[nzData]` | Data record array to be rendered | `T[]` | - | | `[nzFrontPagination]` | Whether to paginate data on client. Should be set to `false` if data is to be paginated on server side or if all the data is to be displayed at once in the table without any pagination | `boolean` | `true` | | `[nzTotal]` | Total data count. Should set when `nzFrontPagination` is `false` | `number` | - | -| `[nzCustomColumn]` | Control the display and sorting of table columns, (after enabling `nzWidthConfig` and `[nzWidth]` of `th` will not take effect) | `NzCustomColumn[]` | - | +| `[nzCustomColumn]` | Control the display and sorting of table columns, (after enabling `nzWidthConfig` and `[nzWidth]` of `th` will not take effect) | `NzCustomColumn[] \| NzHiddenColumn[]` | - | | `[nzPageIndex]` | pageIndex , double binding | `number` | - | | `[nzPageSize]` | pageSize, double binding | `number` | - | | `[nzShowPagination]` | Whether to show pagination component at bottom of the table | `boolean` | `true` | @@ -100,7 +100,7 @@ The data passed to `[nzData]` is exported with [Template Context](https://angula | `(nzPageIndexChange)` | Callback when `pageIndex` changes | `EventEmitter` | - | | `(nzPageSizeChange)` | Callback when `pageSize` changes | `EventEmitter` | - | | `(nzCurrentPageDataChange)` | Callback when current pageData changes | `EventEmitter` | - | -| `(nzCustomColumnChange)` | Callback when the table is reordered | `EventEmitter` | - | +| `(nzCustomColumnChange)` | Callback when the table is reordered | `EventEmitter` | - | | `(nzQueryParams)` | Callback with params when working with server side pagination, sorting and filtering | `EventEmitter` | - | ### th @@ -151,7 +151,7 @@ Style property | `[nzLeft]` | Left pixels, used to fixed column to left, auto calc when set to `true` and disable fixed when `false` | `string \| boolean` | - | | `[nzRight]` | Right pixels, used to fixed column to right, auto calc when set to `true` and disable fixed when `false` | `string \| boolean` | - | | `[nzAlign]` | Specify how content is aligned | `'left' \| 'right' \| 'center'` | - | -| `[nzCellControl]` | Set the position of the column, which is the value of the `value` field in the `NzCustomColumn` type | `string` | - | +| `[nzCellControl]` | Set the visibility and position of the column, which is the value of the `value` field in the `NzCustomColumn` type | `string` | - | | `[nzBreakWord]` | Whether insert line breaks within words | `boolean` | `false` | | `[nzEllipsis]` | ellipsis cell content, not working with sorter and filters for now. Only work when nzTableLayout was `fixed` | `boolean` | `false` | @@ -192,7 +192,7 @@ Style property | `[nzLeft]` | Left pixels, used to fixed column to left, auto calc when set to `true` and disable fixed when `false` | `string \| boolean` | - | | `[nzRight]` | Right pixels, used to fixed column to right, auto calc when set to `true` and disable fixed when `false` | `string \| boolean` | - | | `[nzAlign]` | Specify how content is aligned | `'left' \| 'right' \| 'center'` | - | -| `[nzCellControl]` | Set the position of the column, which is the value of the `value` field in the `NzCustomColumn` type | `string` | - | +| `[nzCellControl]` | Set the visibility and position of the column, which is the value of the `value` field in the `NzCustomColumn` type | `string` | - | | `[nzBreakWord]` | Whether insert line breaks within words | `boolean` | `false` | | `[nzEllipsis]` | ellipsis cell content, not working with sorter and filters for now. Only work when nzTableLayout was `fixed` | `boolean` | `false` | diff --git a/components/table/src/cell/custom-column.directive.ts b/components/table/src/cell/custom-column.directive.ts index 9889dc47730..cac51e38e23 100644 --- a/components/table/src/cell/custom-column.directive.ts +++ b/components/table/src/cell/custom-column.directive.ts @@ -29,16 +29,24 @@ export class NzCustomColumnDirective implements OnInit, OnDestroy { if (item.length) { item.forEach((v, i) => { if (v.value === this.nzCellControl) { - if (!v.default) { - this.renderer.setStyle(this.el.nativeElement, 'display', 'none'); + if ('default' in v) { + if (!v.default) { + this.renderer.setStyle(this.el.nativeElement, 'display', 'none'); + } else { + this.renderer.setStyle(this.el.nativeElement, 'display', 'block'); + } + this.renderer.setStyle(this.el.nativeElement, 'order', i); + if (!v?.fixWidth) { + this.renderer.setStyle(this.el.nativeElement, 'flex', `1 1 ${v.width}px`); + } else { + this.renderer.setStyle(this.el.nativeElement, 'flex', `1 0 ${v.width}px`); + } } else { - this.renderer.setStyle(this.el.nativeElement, 'display', 'block'); - } - this.renderer.setStyle(this.el.nativeElement, 'order', i); - if (!v?.fixWidth) { - this.renderer.setStyle(this.el.nativeElement, 'flex', `1 1 ${v.width}px`); - } else { - this.renderer.setStyle(this.el.nativeElement, 'flex', `1 0 ${v.width}px`); + if (v.hidden) { + this.renderer.setStyle(this.el.nativeElement, 'display', 'none'); + } else { + this.renderer.removeStyle(this.el.nativeElement, 'display'); + } } } }); diff --git a/components/table/src/table-data.service.ts b/components/table/src/table-data.service.ts index 50469e408cc..e5702e63e16 100644 --- a/components/table/src/table-data.service.ts +++ b/components/table/src/table-data.service.ts @@ -9,6 +9,7 @@ import { debounceTime, distinctUntilChanged, filter, map, skip, switchMap, takeU import { NzCustomColumn, + NzHiddenColumn, NzTableFilterFn, NzTableFilterValue, NzTableQueryParams, @@ -23,7 +24,7 @@ export class NzTableDataService implements OnDestroy { private frontPagination$ = new BehaviorSubject(true); private pageSize$ = new BehaviorSubject(10); private listOfData$ = new BehaviorSubject([]); - listOfCustomColumn$ = new BehaviorSubject([]); + listOfCustomColumn$ = new BehaviorSubject([]); pageIndexDistinct$ = this.pageIndex$.pipe(distinctUntilChanged()); pageSizeDistinct$ = this.pageSize$.pipe(distinctUntilChanged()); listOfCalcOperator$ = new BehaviorSubject< @@ -129,7 +130,7 @@ export class NzTableDataService implements OnDestroy { updateListOfData(list: readonly T[]): void { this.listOfData$.next(list); } - updateListOfCustomColumn(list: NzCustomColumn[]): void { + updateListOfCustomColumn(list: NzCustomColumn[] | NzHiddenColumn[]): void { this.listOfCustomColumn$.next(list); } constructor() {} diff --git a/components/table/src/table.types.ts b/components/table/src/table.types.ts index f8c68f2c218..855d5bb430f 100644 --- a/components/table/src/table.types.ts +++ b/components/table/src/table.types.ts @@ -29,4 +29,9 @@ export interface NzCustomColumn { fixWidth?: boolean; } +export interface NzHiddenColumn { + value: string; + hidden: boolean; +} + export type NzTableSummaryFixedType = 'top' | 'bottom'; diff --git a/components/table/src/table/table.component.ts b/components/table/src/table/table.component.ts index c1585460c1d..0b73044ceb6 100644 --- a/components/table/src/table/table.component.ts +++ b/components/table/src/table/table.component.ts @@ -40,6 +40,7 @@ import { NzTableDataService } from '../table-data.service'; import { NzTableStyleService } from '../table-style.service'; import { NzCustomColumn, + NzHiddenColumn, NzTableLayout, NzTablePaginationPosition, NzTablePaginationType, @@ -146,7 +147,7 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'table'; host: { class: 'ant-table-wrapper', '[class.ant-table-wrapper-rtl]': 'dir === "rtl"', - '[class.ant-table-custom-column]': `nzCustomColumn.length` + '[class.ant-table-custom-column]': `nzCustomColumn.length && nzCustomColumn[0].hidden === undefined` }, imports: [ NzSpinComponent, @@ -178,7 +179,7 @@ export class NzTableComponent implements OnInit, OnDestroy, OnChanges, AfterV @Input() nzTotal = 0; @Input() nzWidthConfig: ReadonlyArray = []; @Input() nzData: readonly T[] = []; - @Input() nzCustomColumn: NzCustomColumn[] = []; + @Input() nzCustomColumn: NzCustomColumn[] | NzHiddenColumn[] = []; @Input() nzPaginationPosition: NzTablePaginationPosition = 'bottom'; @Input() nzScroll: { x?: string | null; y?: string | null } = { x: null, y: null }; @@ -200,7 +201,7 @@ export class NzTableComponent implements OnInit, OnDestroy, OnChanges, AfterV @Output() readonly nzPageIndexChange = new EventEmitter(); @Output() readonly nzQueryParams = new EventEmitter(); @Output() readonly nzCurrentPageDataChange = new EventEmitter(); - @Output() readonly nzCustomColumnChange = new EventEmitter(); + @Output() readonly nzCustomColumnChange = new EventEmitter(); /** public data for ngFor tr */ public data: readonly T[] = []; diff --git a/components/table/src/testing/custom-column.spec.ts b/components/table/src/testing/custom-column.spec.ts index 565ea1e68a2..60892628e7b 100644 --- a/components/table/src/testing/custom-column.spec.ts +++ b/components/table/src/testing/custom-column.spec.ts @@ -3,59 +3,96 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { NzDividerModule } from 'ng-zorro-antd/divider'; -import { NzCustomColumn, NzTableComponent, NzTableModule } from 'ng-zorro-antd/table'; +import { NzCustomColumn, NzHiddenColumn, NzTableComponent, NzTableModule } from 'ng-zorro-antd/table'; describe('nz-table-custom-column', () => { - let fixture: ComponentFixture; - let testComponent: NzCustomColumnTestTableComponent; - let resultEl: DebugElement; + describe('default nz-table-custom-column', () => { + let fixture: ComponentFixture; + let testComponent: NzCustomColumnTestTableComponent; + let resultEl: DebugElement; - beforeEach(() => { - fixture = TestBed.createComponent(NzCustomColumnTestTableComponent); - fixture.detectChanges(); - testComponent = fixture.componentInstance; - resultEl = fixture.debugElement.query(By.directive(NzTableComponent)); + beforeEach(() => { + fixture = TestBed.createComponent(NzCustomColumnTestTableComponent); + fixture.detectChanges(); + testComponent = fixture.componentInstance; + resultEl = fixture.debugElement.query(By.directive(NzTableComponent)); + }); + + it('custom-column basic', () => { + fixture.detectChanges(); + // age: order = 3 + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].getAttribute('nzcellcontrol')).toBe('age'); + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].style.order).toBe('3'); + testComponent.customColumn = [ + { + value: 'name', + default: true, + width: 200 + }, + { + value: 'age', + default: true, + width: 200 + }, + { + value: 'gender', + default: false, + width: 200 + }, + { + value: 'address', + default: true, + width: 200 + }, + { + value: 'action', + default: true, + width: 200 + } + ]; + fixture.detectChanges(); + // age: order = 1 + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].getAttribute('nzcellcontrol')).toBe('age'); + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].style.order).toBe('1'); + + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[1].getAttribute('nzcellcontrol')).toBe( + 'gender' + ); + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[1].style.display).toBe('none'); + }); }); - it('custom-column basic', () => { - fixture.detectChanges(); - // age: order = 3 - expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].getAttribute('nzcellcontrol')).toBe('age'); - expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].style.order).toBe('3'); - testComponent.customColumn = [ - { - value: 'name', - default: true, - width: 200 - }, - { - value: 'age', - default: true, - width: 200 - }, - { - value: 'gender', - default: false, - width: 200 - }, - { - value: 'address', - default: true, - width: 200 - }, - { - value: 'action', - default: true, - width: 200 - } - ]; - fixture.detectChanges(); - // age: order = 1 - expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].getAttribute('nzcellcontrol')).toBe('age'); - expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].style.order).toBe('1'); + describe('hidden nz-table-custom-column', () => { + let fixture: ComponentFixture; + let testComponent: NzHiddenColumnTestTableComponent; + let resultEl: DebugElement; - expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[1].getAttribute('nzcellcontrol')).toBe('gender'); - expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[1].style.display).toBe('none'); + beforeEach(() => { + fixture = TestBed.createComponent(NzHiddenColumnTestTableComponent); + fixture.detectChanges(); + testComponent = fixture.componentInstance; + resultEl = fixture.debugElement.query(By.directive(NzTableComponent)); + }); + + it('custom-column hidden', () => { + fixture.detectChanges(); + // age: display = none + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].getAttribute('nzcellcontrol')).toBe('age'); + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].style.display).toBe('none'); + testComponent.customColumn = [ + { + value: 'name', + hidden: true + } + ]; + fixture.detectChanges(); + // name: display = none + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[0].getAttribute('nzcellcontrol')).toBe('name'); + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[0].style.display).toBe('none'); + // age: display = '' + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].getAttribute('nzcellcontrol')).toBe('age'); + expect(resultEl.nativeElement.querySelectorAll('.ant-table-cell')[2].style.display).toBe(''); + }); }); }); @@ -152,3 +189,68 @@ export class NzCustomColumnTestTableComponent { } ]; } + +@Component({ + standalone: true, + imports: [NzDividerModule, NzTableModule], + template: ` + + + + Name + Gender + Age + Address + Action + + + + @for (data of basicTable.data; track data) { + + {{ data.name }} + {{ data.gender }} + {{ data.age }} + {{ data.address }} + + Action + + Delete + + + } + + + ` +}) +export class NzHiddenColumnTestTableComponent { + listOfData: Person[] = [ + { + key: '1', + name: 'John Brown', + gender: 'female', + age: 32, + address: 'New York No. 1 Lake Park' + }, + { + key: '2', + name: 'Jim Green', + gender: 'female', + age: 42, + address: 'London No. 1 Lake Park' + }, + { + key: '3', + name: 'Joe Black', + gender: 'male', + age: 32, + address: 'Sidney No. 1 Lake Park' + } + ]; + + customColumn: NzHiddenColumn[] = [ + { + value: 'age', + hidden: true + } + ]; +} From 61a8003d8c0915bd689c9a93fb14b389d174a10c Mon Sep 17 00:00:00 2001 From: Nicolas Boix Date: Fri, 22 Nov 2024 16:51:40 +0100 Subject: [PATCH 2/3] docs(module:table): doc for hide column only for nzCustomColumn --- components/table/demo/hidden-column.md | 14 +++++ components/table/demo/hidden-column.ts | 87 ++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 components/table/demo/hidden-column.md create mode 100644 components/table/demo/hidden-column.ts diff --git a/components/table/demo/hidden-column.md b/components/table/demo/hidden-column.md new file mode 100644 index 00000000000..d030ed5d4a5 --- /dev/null +++ b/components/table/demo/hidden-column.md @@ -0,0 +1,14 @@ +--- +order: 32 +title: + en-US: Hidden Column + zh-CN: 隐藏栏 +--- + +## zh-CN + +仅控制表中列的可见性 + +## en-US + +Control only the visibility of columns in a table without using flex css property. diff --git a/components/table/demo/hidden-column.ts b/components/table/demo/hidden-column.ts new file mode 100644 index 00000000000..2409872a0d6 --- /dev/null +++ b/components/table/demo/hidden-column.ts @@ -0,0 +1,87 @@ +import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { NzCheckboxModule } from 'ng-zorro-antd/checkbox'; +import { NzHiddenColumn, NzTableModule } from 'ng-zorro-antd/table'; + +interface Person { + key: string; + name: string; + gender: 'male' | 'female'; + age: number; + address: string; +} + +@Component({ + selector: 'nz-demo-table-custom-column', + standalone: true, + imports: [NzCheckboxModule, NzTableModule, FormsModule], + template: ` + + + + Name + Gender + Age + Address + + + + @for (data of basicTable.data; track data) { + + {{ data.name }} + {{ data.gender }} + {{ data.age }} + {{ data.address }} + + } + + + + + + ` +}) +export class NzDemoTableCustomColumnComponent { + listOfData: Person[] = [ + { + key: '1', + name: 'John Brown', + gender: 'female', + age: 32, + address: 'New York No. 1 Lake Park' + }, + { + key: '2', + name: 'Jim Green', + gender: 'female', + age: 42, + address: 'London No. 1 Lake Park' + }, + { + key: '3', + name: 'Joe Black', + gender: 'male', + age: 32, + address: 'Sidney No. 1 Lake Park' + } + ]; + + checked = false; + customColumn: NzHiddenColumn[] = []; + + constructor() {} + + onCheckedChange(): void { + if (this.checked) { + this.customColumn = [ + { + value: 'age', + hidden: true + } + ]; + } else { + this.customColumn = []; + } + } +} From be5694b5676db80d67d2361f6535555d92d1ec44 Mon Sep 17 00:00:00 2001 From: Nicolas Boix Date: Thu, 16 Jan 2025 10:39:31 +0100 Subject: [PATCH 3/3] docs(module:table): changed component and selector name --- components/table/demo/hidden-column.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/components/table/demo/hidden-column.ts b/components/table/demo/hidden-column.ts index 2409872a0d6..8975750421a 100644 --- a/components/table/demo/hidden-column.ts +++ b/components/table/demo/hidden-column.ts @@ -13,7 +13,7 @@ interface Person { } @Component({ - selector: 'nz-demo-table-custom-column', + selector: 'nz-demo-table-hidden-column', standalone: true, imports: [NzCheckboxModule, NzTableModule, FormsModule], template: ` @@ -42,7 +42,7 @@ interface Person { ` }) -export class NzDemoTableCustomColumnComponent { +export class NzDemoTableHiddenColumnComponent { listOfData: Person[] = [ { key: '1', @@ -81,7 +81,12 @@ export class NzDemoTableCustomColumnComponent { } ]; } else { - this.customColumn = []; + this.customColumn = [ + { + value: 'age', + hidden: false + } + ]; } } }