From 998dcce225990ef3efdd0ea7003b69841fb185a0 Mon Sep 17 00:00:00 2001 From: Hashem Qolami Date: Tue, 13 Dec 2016 11:51:59 +0330 Subject: [PATCH] Feature table maxHeight (#1560) (#1674) * :sparkles: [Table] Added fluid height table with maxHeight prop (#1560) * :rotating_light: [Table] Added test for maxHeight prop (#1560) * :books: [Table] Added the documentation of fluid-height table (#1560) --- examples/docs/en-US/table.md | 177 ++++++++++++++++++++++++++- packages/table/src/table-layout.js | 23 ++-- packages/table/src/table.vue | 96 ++++++++++++--- packages/theme-default/src/table.css | 8 ++ test/unit/specs/table.spec.js | 9 ++ 5 files changed, 282 insertions(+), 31 deletions(-) diff --git a/examples/docs/en-US/table.md b/examples/docs/en-US/table.md index 80c668b5d..1ae77b9ef 100644 --- a/examples/docs/en-US/table.md +++ b/examples/docs/en-US/table.md @@ -104,6 +104,49 @@ address: 'No. 189, Grove St, Los Angeles', zip: 'CA 90036' }], + tableData4: [{ + date: '2016-05-03', + name: 'Tom', + state: 'California', + city: 'Los Angeles', + address: 'No. 189, Grove St, Los Angeles', + zip: 'CA 90036' + }, { + date: '2016-05-02', + name: 'Tom', + state: 'California', + city: 'Los Angeles', + address: 'No. 189, Grove St, Los Angeles', + zip: 'CA 90036' + }, { + date: '2016-05-04', + name: 'Tom', + state: 'California', + city: 'Los Angeles', + address: 'No. 189, Grove St, Los Angeles', + zip: 'CA 90036' + }, { + date: '2016-05-01', + name: 'Tom', + state: 'California', + city: 'Los Angeles', + address: 'No. 189, Grove St, Los Angeles', + zip: 'CA 90036' + }, { + date: '2016-05-08', + name: 'Tom', + state: 'California', + city: 'Los Angeles', + address: 'No. 189, Grove St, Los Angeles', + zip: 'CA 90036' + }, { + date: '2016-05-06', + name: 'Tom', + state: 'California', + city: 'Los Angeles', + address: 'No. 189, Grove St, Los Angeles', + zip: 'CA 90036' + }], currentRow: null, multipleSelection: [] }; @@ -144,6 +187,10 @@ return 'positive-row'; } return ''; + }, + + deleteRow(index, rows) { + rows.splice(index, 1); } }, @@ -683,6 +730,133 @@ When you have huge chunks of data to put in a table, you can fix the header and ``` ::: +### Fluid-height Table with fixed header (and columns) + +When the the data is dynamically changed, you might want the table to have a maximum height rather than a fixed height and to show the scroll bar if needed. + +:::demo By setting the attribute `maxHeight` of `el-table`, you can fix the table header. The table body scrolls only if the height of the rows exceeds the maxHeight value. +```html + + + +``` +::: + ### Grouping table head When the data structure is complex, you can use group header to show the data hierarchy. @@ -1177,7 +1351,8 @@ Customize table column so it can be integrated with other components. | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | data | table data | array | — | — | -| height | Table's height. By default it has an auto height. If its value is a number, the height is measured in pixels; if its value is a string, the height is affected by external styles | string/number | — | — | +| height | Table's height. By default it has an `auto` height. If its value is a number, the height is measured in pixels; if its value is a string, the height is affected by external styles | string/number | — | — | +| maxHeight | Table's max-height. The height of the table starts from `auto` until it reaches the maxHeight limit. The `maxHeight` is measured in pixels, same as `height` | string/number | — | — | | stripe | whether table is striped | boolean | — | false | | border | whether table has vertical border | boolean | — | false | | fit | whether width of column automatically fits its container | boolean | — | true | diff --git a/packages/table/src/table-layout.js b/packages/table/src/table-layout.js index 0542e7b54..73fefd1b5 100644 --- a/packages/table/src/table-layout.js +++ b/packages/table/src/table-layout.js @@ -51,26 +51,28 @@ class TableLayout { } } - setHeight(height) { + setHeight(value, prop = 'height') { const el = this.table.$el; - if (typeof height === 'string') { - if (/^\d+$/.test(height)) { - height = Number(height); - } + if (typeof value === 'string' && /^\d+$/.test(value)) { + value = Number(value); } - this.height = height; + this.height = value; if (!el) return; - if (!isNaN(height)) { - el.style.height = height + 'px'; + if (typeof value === 'number') { + el.style[prop] = value + 'px'; this.updateHeight(); - } else if (typeof height === 'string') { + } else if (typeof value === 'string') { this.updateHeight(); } } + setMaxHeight(value) { + return this.setHeight(value, 'max-height'); + } + updateHeight() { const height = this.tableHeight = this.table.$el.clientHeight; const { headerWrapper } = this.table.$refs; @@ -81,7 +83,6 @@ class TableLayout { this.bodyHeight = height; } this.fixedBodyHeight = this.scrollX ? height - this.gutterWidth : height; - this.viewportHeight = this.scrollX ? height - this.gutterWidth : height; } else { const headerHeight = this.headerHeight = headerWrapper.offsetHeight; const bodyHeight = height - headerHeight; @@ -89,8 +90,8 @@ class TableLayout { this.bodyHeight = bodyHeight; } this.fixedBodyHeight = this.scrollX ? bodyHeight - this.gutterWidth : bodyHeight; - this.viewportHeight = this.scrollX ? height - this.gutterWidth : height; } + this.viewportHeight = this.scrollX ? height - this.gutterWidth : height; } update() { diff --git a/packages/table/src/table.vue b/packages/table/src/table.vue index 499ac68dc..43dab3663 100644 --- a/packages/table/src/table.vue +++ b/packages/table/src/table.vue @@ -4,6 +4,7 @@ 'el-table--fit': fit, 'el-table--striped': stripe, 'el-table--border': border, + 'el-table--fluid-height': maxHeight, 'el-table--enable-row-hover': !store.states.isComplex, 'el-table--enable-row-transition': true || (store.states.data || []).length !== 0 && (store.states.data || []).length < 100 }" @@ -17,8 +18,7 @@ :style="{ width: layout.bodyWidth ? layout.bodyWidth + 'px' : '' }"> -
+
+ :style="[ + { width: layout.fixedWidth ? layout.fixedWidth + 'px' : '' }, + fixedHeight + ]">
+ :style="[ + { top: layout.headerHeight + 'px' }, + fixedBodyHeight + ]">
+ :style="[ + { width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '' }, + { right: layout.scrollY ? (border ? layout.gutterWidth : (layout.gutterWidth || 1)) + 'px' : '' }, + fixedHeight + ]">
+ :style="[ + { top: layout.headerHeight + 'px' }, + fixedBodyHeight + ]"> { if (this.height) { this.layout.setHeight(this.height); + } else if (this.maxHeight) { + this.layout.setMaxHeight(this.maxHeight); } else if (this.shouldUpdateHeight) { this.layout.updateHeight(); } @@ -275,6 +279,60 @@ rightFixedColumns() { return this.store.states.rightFixedColumns; + }, + + bodyHeight() { + let style = {}; + + if (this.height) { + style = { + height: this.layout.bodyHeight ? this.layout.bodyHeight + 'px' : '' + }; + } else if (this.maxHeight) { + style = { + 'max-height': (this.showHeader ? this.maxHeight - this.layout.headerHeight : this.maxHeight) + 'px' + }; + } + + return style; + }, + + fixedBodyHeight() { + let style = {}; + + if (this.height) { + style = { + height: this.layout.fixedBodyHeight ? this.layout.fixedBodyHeight + 'px' : '' + }; + } else if (this.maxHeight) { + let maxHeight = this.layout.scrollX ? this.maxHeight - this.layout.gutterWidth : this.maxHeight; + + if (this.showHeader) { + maxHeight -= this.layout.headerHeight; + } + + style = { + 'max-height': maxHeight + 'px' + }; + } + + return style; + }, + + fixedHeight() { + let style = {}; + + if (this.maxHeight) { + style = { + bottom: (this.layout.scrollX && this.data.length) ? this.layout.gutterWidth + 'px' : '' + }; + } else { + style = { + height: this.layout.viewportHeight ? this.layout.viewportHeight + 'px' : '' + }; + } + + return style; } }, diff --git a/packages/theme-default/src/table.css b/packages/theme-default/src/table.css index df4bb18ff..4f891e3de 100644 --- a/packages/theme-default/src/table.css +++ b/packages/theme-default/src/table.css @@ -388,5 +388,13 @@ background-color: #eff2f7; } } + + @modifier fluid-height { + .el-table__fixed, + .el-table__fixed-right { + bottom: 0; + overflow: hidden; + } + } } } diff --git a/test/unit/specs/table.spec.js b/test/unit/specs/table.spec.js index 39a4c64ff..17818011d 100644 --- a/test/unit/specs/table.spec.js +++ b/test/unit/specs/table.spec.js @@ -89,6 +89,15 @@ describe('Table', () => { }, DELAY); }); + it('maxHeight', done => { + const vm = createTable('max-height="134"'); + setTimeout(_ => { + expect(vm.$el.style.maxHeight).to.equal('134px'); + destroyVM(vm); + done(); + }, DELAY); + }); + it('stripe', done => { const vm = createTable('stripe'); setTimeout(_ => {