From 7fea43330c923e882c2cae48ac17946489c775fe Mon Sep 17 00:00:00 2001 From: cagataycivici Date: Tue, 19 Nov 2019 17:02:36 +0300 Subject: [PATCH] Docs for Scrolling Table --- src/components/datatable/DataTable.d.ts | 7 + src/components/datatable/DataTable.vue | 4 +- src/views/datatable/DataTableDoc.vue | 203 ++++++++++++++++++++ src/views/datatable/DataTableScrollDemo.vue | 184 ++++++++++++++++++ 4 files changed, 396 insertions(+), 2 deletions(-) diff --git a/src/components/datatable/DataTable.d.ts b/src/components/datatable/DataTable.d.ts index e5d1579ee..345059340 100644 --- a/src/components/datatable/DataTable.d.ts +++ b/src/components/datatable/DataTable.d.ts @@ -47,6 +47,13 @@ export declare class DataTable extends Vue { editMode?: string; editingRows?: any[]; rowClass?: any; + scrollable?: boolean; + scrollHeight?: string; + frozenValue?: any[]; + frozenWidth?: string; + virtualScroll?: boolean; + virtualRowHeight?: string; + virtualScrollDelay?: number; $emit(eventName: 'page', event: Event): this; $emit(eventName: 'sort', event: Event): this; $emit(eventName: 'filter', event: Event): this; diff --git a/src/components/datatable/DataTable.vue b/src/components/datatable/DataTable.vue index a769f8bbe..43163da22 100644 --- a/src/components/datatable/DataTable.vue +++ b/src/components/datatable/DataTable.vue @@ -340,11 +340,11 @@ export default { }, virtualRowHeight: { type: Number, - default: null + default: 28 }, virtualScrollDelay: { type: Number, - default: 159 + default: 150 } }, data() { diff --git a/src/views/datatable/DataTableDoc.vue b/src/views/datatable/DataTableDoc.vue index 682d624ec..9bf055c1b 100644 --- a/src/views/datatable/DataTableDoc.vue +++ b/src/views/datatable/DataTableDoc.vue @@ -262,6 +262,18 @@ export default { false When enabled, column displays row editor controls. + + rowEditor + boolean + false + When enabled, column displays row editor controls. + + + frozen + boolean + false + Whether the column is fixed in horizontal scrolling. + @@ -550,6 +562,149 @@ data() { <Column field="color" header="Color"></Column> </DataTable> + + +

Scrolling

+

DataTable supports both horizontal and vertical scrolling as well as frozen columns and rows. Scrollable DataTable is enabled using scrollable property and scrollHeight to define the viewport height.

+ + + + +

Horizontal Scrolling requires a width of DataTable to be defined and explicit widths on columns.

+ + + + +

Certain columns can be frozen by using the frozen property of the column component. Widths of the frozen section is specified by the frozenWidth property.

+ + + + +

Note that frozen columns are enabled, frozen and scrollable cells may have content with varying height which leads to misalignment. Provide fixed height to cells to avoid alignment issues.

+ + + + +

One or more rows can be displayed as fixed using the frozenValue property.

+ + + + +

When using frozen columns with column grouping, use frozenheadergroup and frozenfootergroup types to define grouping for the frozen section.

+ +

Virtual scrolling is enabled using virtualScroll and onVirtualScroll properties combined with lazy loading so that data is loaded on the fly during scrolling. + For smooth scrolling twice the amount of rows property is loaded on a lazy load event. In addition, to avoid performance problems row height is not calculated automatically and + should be provided using virtualRowHeight property which defaults to 28px. View the scrolling demo for a sample in-memory implementation.

+ + + + + + +import CarService from '../../service/CarService'; + +export default { + data() { + return { + lazyCars: null, + lazyTotalRecords: 0 + } + }, + carService: null, + mounted() { + this.lazyCars = this.loadChunk(0, 40); + this.lazyTotalRecords = //retrieve logical number of rows from a datasource; + }, + methods: { + loadChunk(index, length) { + //return data from a datasource between [index, index + length]; + }, + onVirtualScroll(event) { + //last chunk + if (event.first === (this.lazyTotalRecords - 20)) + this.lazyCars = this.loadChunk(event.first, 20) + else + this.lazyCars = this.loadChunk(event.first, event.rows) + } + } +}

Lazy Loading

@@ -1697,6 +1852,48 @@ export default { null A function that takes the row data and returns a string to apply a particular class for the row. + + scrollable + boolean + false + When specified, enables horizontal and/or vertical scrolling. + + + scrollHeight + string + null + Height of the scroll viewport. + + + virtualScroll + boolean + false + Whether the data should be loaded on demand during scroll. + + + virtualScrollDelay + number + 150 + Delay in virtual scroll before doing a call to lazy load. + + + virtualRowHeight + number + 28 + Height of a row to use in calculations of virtual scrolling. + + + frozenWidth + string + null + Width of the frozen part in scrollable DataTable. + + + frozenValue + array + null + Items of the frozen part in scrollable DataTable. + @@ -1849,6 +2046,12 @@ export default { event.index: Index of the row data to edit.
Callback to invoke when row edit is cancelled. + + virtual-scroll + event.first: Index of the first row.
+ event.rows: Rows per page. + Callback to invoke during virtual scrolling. + diff --git a/src/views/datatable/DataTableScrollDemo.vue b/src/views/datatable/DataTableScrollDemo.vue index fee25940b..5038acd34 100644 --- a/src/views/datatable/DataTableScrollDemo.vue +++ b/src/views/datatable/DataTableScrollDemo.vue @@ -87,11 +87,195 @@ +import CarService from '../../service/CarService'; +export default { + data() { + return { + cars: null, + frozenCars: null, + lazyCars: null, + lazyTotalRecords: 0, + loading: false + } + }, + carService: null, + inmemoryData: null, + created() { + this.carService = new CarService(); + + this.inmemoryData = [ + {"brand": "VW", "year": 2012, "color": "Orange"}, + {"brand": "Audi", "year": 2011, "color": "Black"}, + {"brand": "Renault", "year": 2005, "color": "Gray"}, + {"brand": "BMW", "year": 2003, "color": "Blue"}, + {"brand": "Mercedes", "year": 1995, "color": "Orange"}, + {"brand": "Volvo", "year": 2005, "color": "Black"}, + {"brand": "Honda", "year": 2012, "color": "Yellow"}, + {"brand": "Jaguar", "year": 2013, "color": "Orange"}, + {"brand": "Ford", "year": 2000, "color": "Black"}, + {"brand": "Fiat", "year": 2013, "color": "Red"}, + {"brand": "VW", "year": 2012, "color": "Orange"}, + {"brand": "Audi", "year": 2011, "color": "Black"}, + {"brand": "Renault", "year": 2005, "color": "Gray"}, + {"brand": "BMW", "year": 2003, "color": "Blue"}, + {"brand": "Mercedes", "year": 1995, "color": "Orange"}, + {"brand": "Volvo", "year": 2005, "color": "Black"}, + {"brand": "Honda", "year": 2012, "color": "Yellow"}, + {"brand": "Jaguar", "year": 2013, "color": "Orange"}, + {"brand": "Ford", "year": 2000, "color": "Black"}, + {"brand": "Fiat", "year": 2013, "color": "Red"}, + {"brand": "VW", "year": 2012, "color": "Orange"}, + {"brand": "Audi", "year": 2011, "color": "Black"}, + {"brand": "Renault", "year": 2005, "color": "Gray"}, + {"brand": "BMW", "year": 2003, "color": "Blue"}, + {"brand": "Mercedes", "year": 1995, "color": "Orange"}, + {"brand": "Volvo", "year": 2005, "color": "Black"}, + {"brand": "Honda", "year": 2012, "color": "Yellow"}, + {"brand": "Jaguar", "year": 2013, "color": "Orange"}, + {"brand": "Ford", "year": 2000, "color": "Black"}, + {"brand": "Fiat", "year": 2013, "color": "Red"}, + {"brand": "VW", "year": 2012, "color": "Orange"}, + {"brand": "Audi", "year": 2011, "color": "Black"}, + {"brand": "Renault", "year": 2005, "color": "Gray"}, + {"brand": "BMW", "year": 2003, "color": "Blue"}, + {"brand": "Mercedes", "year": 1995, "color": "Orange"}, + {"brand": "Volvo", "year": 2005, "color": "Black"}, + {"brand": "Honda", "year": 2012, "color": "Yellow"}, + {"brand": "Jaguar", "year": 2013, "color": "Orange"}, + {"brand": "Ford", "year": 2000, "color": "Black"}, + {"brand": "Fiat", "year": 2013, "color": "Red"} + ]; + }, + mounted() { + this.loading = true; + + setTimeout(() => { + this.carService.getCarsLarge().then(data => { + this.cars = data + this.loading = false; + }); + }, 150); + + this.frozenCars = [ + {brand: "BMW", year: 2013, color: "Grey", vin: "fh2uf23"}, + {brand: "Chevrolet", year: 2011, color: "Black", vin: "4525g23"} + ]; + + setTimeout(() => { + this.lazyCars = this.loadChunk(0, 40); + this.lazyTotalRecords = 250000; + }, 250); + }, + methods: { + loadChunk(index, length) { + let chunk = []; + for (let i = 0; i < length; i++) { + chunk[i] = {...this.inmemoryData[i], ...{vin: (index + i)}}; + } + + return chunk; + }, + onVirtualScroll(event) { + /* + For demo purposes keep loading the same dataset, + in a real production application, this data should come from server by building the query with LazyLoadEvent options + */ + setTimeout(() => { + //last chunk + if (event.first === 249980) + this.lazyCars = this.loadChunk(event.first, 20) + else + this.lazyCars = this.loadChunk(event.first, event.rows) + }, 250); + } + } +} + + + +.loading-text { + display: block; + background-color: #f1f1f1; + min-height: 19px; + animation: pulse 1s infinite ease-in-out; + text-indent: -99999px; + overflow: hidden; +}