Fixed #328 - Flex Scroll height for DataTable

pull/345/head
cagataycivici 2020-05-27 15:12:12 +03:00
parent e072068c7f
commit 3ae6ee1272
7 changed files with 151 additions and 38 deletions

View File

@ -78,6 +78,7 @@
<li><router-link to="/datatable/selection">Selection</router-link></li>
<li><router-link to="/datatable/lazy">Lazy</router-link></li>
<li><router-link to="/datatable/scroll">Scroll</router-link></li>
<li><router-link to="/datatable/flexscroll">FlexScroll</router-link></li>
<li><router-link to="/datatable/rowexpand">Expand</router-link></li>
<li><router-link to="/datatable/edit">Edit</router-link></li>
<li><router-link to="/datatable/coltoggle">ColToggle</router-link></li>

View File

@ -1645,7 +1645,8 @@ export default {
'p-datatable-resizable': this.resizableColumns,
'p-datatable-resizable-fit': this.resizableColumns && this.columnResizeMode === 'fit',
'p-datatable-scrollable': this.scrollable,
'p-datatable-virtual-scrollable': this.virtualScroll
'p-datatable-virtual-scrollable': this.virtualScroll,
'p-datatable-flex-scrollable': (this.scrollable && this.scrollHeight === 'flex')
}
];
},
@ -1900,6 +1901,26 @@ export default {
top: 0;
}
/* Flex Scrollable */
.p-datatable-flex-scrollable {
display: flex;
flex-direction: column;
flex: 1;
height: 100%;
}
.p-datatable-flex-scrollable .p-datatable-scrollable-wrapper,
.p-datatable-flex-scrollable .p-datatable-scrollable-view {
display: flex;
flex-direction: column;
flex: 1;
height: 100%;
}
.p-datatable-flex-scrollable .p-datatable-scrollable-body {
flex: 1;
}
/* Resizable */
.p-datatable-resizable > .p-datatable-wrapper {
overflow-x: auto;

View File

@ -11,7 +11,7 @@
</table>
</div>
</div>
<div class="p-datatable-scrollable-body" ref="scrollBody" @scroll="onBodyScroll">
<div class="p-datatable-scrollable-body" ref="scrollBody" @scroll="onBodyScroll" :style="{maxHeight: scrollHeight !== 'flex' ? scrollHeight: null}">
<table ref="scrollTable" :class="bodyTableClass" :style="bodyTableStyle">
<colgroup class="p-datatable-scrollable-colgroup">
<col v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.headerStyle" />
@ -80,8 +80,6 @@ export default {
},
virtualScrollCallback: null,
mounted() {
this.setScrollHeight();
if (!this.frozen)
this.alignScrollBar();
else
@ -100,8 +98,6 @@ export default {
this.virtualScrollCallback();
this.virtualScrollCallback = null;
}
this.setScrollHeight();
},
watch: {
totalRecords(newValue) {
@ -159,33 +155,6 @@ export default {
}
}
},
setScrollHeight() {
if (this.scrollHeight) {
let frozenView = this.$el.previousElementSibling;
if (frozenView) {
let frozenScrollBody = DomHandler.findSingle(frozenView, '.p-datatable-scrollable-body');
this.$refs.scrollBody.style.maxHeight = frozenScrollBody.style.maxHeight;
}
else {
if(this.scrollHeight.indexOf('%') !== -1) {
let datatableContainer = this.findDataTableContainer(this.$el);
this.$refs.scrollBody.style.visibility = 'hidden';
this.$refs.scrollBody.style.height = '100px'; //temporary height to calculate static height
let containerHeight = DomHandler.getOuterHeight(datatableContainer);
let relativeHeight = DomHandler.getOuterHeight(datatableContainer.parentElement) * parseInt(this.scrollHeight, 10) / 100;
let staticHeight = containerHeight - 100; //total height of headers, footers, paginators
let scrollBodyHeight = (relativeHeight - staticHeight);
this.$refs.scrollBody.style.height = 'auto';
this.$refs.scrollBody.style.maxHeight = scrollBodyHeight + 'px';
this.$refs.scrollBody.style.visibility = 'visible';
}
else {
this.$refs.scrollBody.style.maxHeight = this.scrollHeight;
}
}
}
},
hasVerticalOverflow() {
return DomHandler.getOuterHeight(this.$refs.scrollTable) > DomHandler.getOuterHeight(this.$refs.scrollBody);
},

View File

@ -251,6 +251,11 @@ export default new Router({
name: 'datatablescroll',
component: () => import('./views/datatable/DataTableScrollDemo.vue')
},
{
path: '/datatable/flexscroll',
name: 'datatableflexscroll',
component: () => import('./views/datatable/DataTableFlexScrollDemo.vue')
},
{
path: '/datatable/style',
name: 'datatablestyle',

View File

@ -662,7 +662,43 @@ methods: {
</template>
</CodeHighlight>
<p>Horizontal Scrolling requires a width of DataTable to be defined and explicit widths on columns.</p>
<h3>Flex Scroll</h3>
<p>In cases where viewport should adjust itself according to the table parent's height instead of a fixed viewport height, set scrollHeight option as flex. In example below, table is inside a Dialog where viewport size dynamically responds to the dialog size changes such as maximizing.</p>
<CodeHighlight>
<template v-pre>
&lt;Button label="Show" icon="pi pi-external-link" @click="openDialog" /&gt;
&lt;Dialog header="Flex Scroll" :visible.sync="dialogVisible" :style="{width: '50vw'}" :maximizable="true" :modal="true" :contentStyle="{height: '300px'}"&gt;
&lt;DataTable :value="cars" :scrollable="true" scrollHeight="flex"&gt;
&lt;Column field="vin" header="Vin"&gt;&lt;/Column&gt;
&lt;Column field="year" header="Year"&gt;&lt;/Column&gt;
&lt;Column field="brand" header="Brand"&gt;&lt;/Column&gt;
&lt;Column field="color" header="Color"&gt;&lt;/Column&gt;
&lt;/DataTable&gt;
&lt;template #footer&gt;
&lt;Button label="Yes" icon="pi pi-check" @click="closeDialog" /&gt;
&lt;Button label="No" icon="pi pi-times" @click="closeDialog" class="p-button-secondary"/&gt;
&lt;/template&gt;
&lt;/Dialog&gt;
</template>
</CodeHighlight>
<h3>Full Page Scroll</h3>
<p>FlexScroll can also be used for cases where scrollable viewport should be responsive with respect to the window size. See the Full Page demo for an example.</p>
<CodeHighlight>
<template v-pre>
&lt;div style="height: calc(100vh - 143px)"&gt;
&lt;DataTable :value="cars" :scrollable="true" scrollHeight="flex"&gt;
&lt;Column field="vin" header="Vin"&gt;&lt;/Column&gt;
&lt;Column field="year" header="Year"&gt;&lt;/Column&gt;
&lt;Column field="brand" header="Brand"&gt;&lt;/Column&gt;
&lt;Column field="color" header="Color"&gt;&lt;/Column&gt;
&lt;/DataTable&gt;
&lt;/div&gt;
</template>
</CodeHighlight>
<h3>Horizontal Scrolling</h3>
<p>In horizontal scrolling, it is required to give fixed widths to columns. In general when customizing the column widths of scrollable tables, use colgroup as below to avoid misalignment issues as it will apply both the header, body and footer sections which are different separate elements internally.</p>
<CodeHighlight>
<template v-pre>
&lt;DataTable :value="cars" :scrollable="true" scrollHeight="200px" style="width: 600px"&gt;
@ -678,7 +714,8 @@ methods: {
</template>
</CodeHighlight>
<p>Certain columns can be frozen by using the <i>frozen</i> property of the column component. Widths of the frozen section is specified by the <i>frozenWidth</i> property.</p>
<h3>Frozen Rows and Columns</h3>
<p>Certain columns can be frozen by using the <i>frozen</i> property of the column component. Widths of the frozen section is specified by the <i>frozenWidth</i> property.</p>
<CodeHighlight>
<template v-pre>
&lt;DataTable :value="cars" :scrollable="true" scrollHeight="200px" frozenWidth="300px" :loading="loading"&gt;
@ -730,6 +767,7 @@ methods: {
<p>When using frozen columns with column grouping, use <i>frozenheadergroup</i> and <i>frozenfootergroup</i> types to define grouping for the frozen section.</p>
<h3>Virtual Scrolling</h3>
<p>Virtual scrolling is enabled using <i>virtualScroll</i> and <i>onVirtualScroll</i> 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 <i>virtualRowHeight</i> property which defaults to 28px. View the <router-link to="/datatable/scroll">scrolling demo</router-link> for a sample in-memory implementation.</p>
@ -2038,7 +2076,7 @@ export default {
<td>scrollHeight</td>
<td>string</td>
<td>null</td>
<td>Height of the scroll viewport.</td>
<td>Height of the scroll viewport in fixed pixels or the "flex" keyword for a dynamic size.</td>
</tr>
<tr>
<td>virtualScroll</td>

View File

@ -0,0 +1,29 @@
<template>
<div class="content-section implementation" style="height: calc(100vh - 143px)">
<DataTable :value="cars" :scrollable="true" scrollHeight="flex">
<Column field="vin" header="Vin"></Column>
<Column field="year" header="Year"></Column>
<Column field="brand" header="Brand"></Column>
<Column field="color" header="Color"></Column>
</DataTable>
</div>
</template>
<script>
import CarService from '../../service/CarService';
export default {
data() {
return {
cars: null
}
},
carService: null,
created() {
this.carService = new CarService();
},
mounted() {
this.carService.getCarsLarge().then(data => this.cars = data);
}
}
</script>

View File

@ -16,6 +16,24 @@
<Column field="color" header="Color"></Column>
</DataTable>
<h3>Flexible Scroll</h3>
<p>Flex scroll feature makes the scrollable viewport section dynamic so that it can grow or shrink relative to the parent size of the table.
Click the button below to display a maximizable Dialog where data viewport adjusts itself according to the size changes.</p>
<Button label="Show" icon="pi pi-external-link" @click="openDialog" />
<Dialog header="Flex Scroll" :visible.sync="dialogVisible" :style="{width: '50vw'}" :maximizable="true" :modal="true" :contentStyle="{height: '300px'}">
<DataTable :value="cars" :scrollable="true" scrollHeight="flex">
<Column field="vin" header="Vin"></Column>
<Column field="year" header="Year"></Column>
<Column field="brand" header="Brand"></Column>
<Column field="color" header="Color"></Column>
</DataTable>
<template #footer>
<Button label="Yes" icon="pi pi-check" @click="closeDialog" />
<Button label="No" icon="pi pi-times" @click="closeDialog" class="p-button-secondary"/>
</template>
</Dialog>
<h3>Virtual Scroll</h3>
<DataTable :value="lazyCars" :scrollable="true" scrollHeight="200px" :lazy="true" :rows="20" :loading="loading"
:virtualScroll="true" :virtualRowHeight="30" @virtual-scroll="onVirtualScroll" :totalRecords="lazyTotalRecords">
@ -93,6 +111,24 @@
&lt;Column field="color" header="Color"&gt;&lt;/Column&gt;
&lt;/DataTable&gt;
&lt;h3&gt;Flexible Scroll&lt;/h3&gt;
&lt;p&gt;Flex scroll feature makes the scrollable viewport section dynamic so that it can grow or shrink relative to the parent size of the table.
Click the button below to display a maximizable Dialog where data viewport adjusts itself according to the size changes.&lt;/p&gt;
&lt;Button label="Show" icon="pi pi-external-link" @click="openDialog" /&gt;
&lt;Dialog header="Flex Scroll" :visible.sync="dialogVisible" :style="{width: '50vw'}" :maximizable="true" :modal="true" :contentStyle="{height: '300px'}"&gt;
&lt;DataTable :value="cars" :scrollable="true" scrollHeight="flex"&gt;
&lt;Column field="vin" header="Vin"&gt;&lt;/Column&gt;
&lt;Column field="year" header="Year"&gt;&lt;/Column&gt;
&lt;Column field="brand" header="Brand"&gt;&lt;/Column&gt;
&lt;Column field="color" header="Color"&gt;&lt;/Column&gt;
&lt;/DataTable&gt;
&lt;template #footer&gt;
&lt;Button label="Yes" icon="pi pi-check" @click="closeDialog" /&gt;
&lt;Button label="No" icon="pi pi-times" @click="closeDialog" class="p-button-secondary"/&gt;
&lt;/template&gt;
&lt;/Dialog&gt;
&lt;h3&gt;Virtual Scroll&lt;/h3&gt;
&lt;DataTable :value="lazyCars" :scrollable="true" scrollHeight="200px" :lazy="true" :rows="20" :loading="loading"
:virtualScroll="true" :virtualRowHeight="30" @virtual-scroll="onVirtualScroll" :totalRecords="lazyTotalRecords"&gt;
@ -168,7 +204,8 @@ export default {
frozenCars: null,
lazyCars: null,
lazyTotalRecords: 0,
loading: false
loading: false,
dialogVisible: false
}
},
carService: null,
@ -260,6 +297,12 @@ export default {
else
this.lazyCars = this.loadChunk(event.first, event.rows)
}, 250);
},
openDialog() {
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
}
}
}
@ -291,7 +334,8 @@ export default {
frozenCars: null,
lazyCars: null,
lazyTotalRecords: 0,
loading: false
loading: false,
dialogVisible: false
}
},
carService: null,
@ -383,6 +427,12 @@ export default {
else
this.lazyCars = this.loadChunk(event.first, event.rows)
}, 250);
},
openDialog() {
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
}
}
}