Skip to content

Commit

Permalink
Fixed #328 - Flex Scroll height for DataTable
Browse files Browse the repository at this point in the history
  • Loading branch information
cagataycivici committed May 27, 2020
1 parent e072068 commit 3ae6ee1
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 38 deletions.
1 change: 1 addition & 0 deletions src/AppMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
23 changes: 22 additions & 1 deletion src/components/datatable/DataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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')
}
];
},
Expand Down Expand Up @@ -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;
Expand Down
33 changes: 1 addition & 32 deletions src/components/datatable/ScrollableView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down Expand Up @@ -80,8 +80,6 @@ export default {
},
virtualScrollCallback: null,
mounted() {
this.setScrollHeight();
if (!this.frozen)
this.alignScrollBar();
else
Expand All @@ -100,8 +98,6 @@ export default {
this.virtualScrollCallback();
this.virtualScrollCallback = null;
}
this.setScrollHeight();
},
watch: {
totalRecords(newValue) {
Expand Down Expand Up @@ -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);
},
Expand Down
5 changes: 5 additions & 0 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
44 changes: 41 additions & 3 deletions src/views/datatable/DataTableDoc.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
29 changes: 29 additions & 0 deletions src/views/datatable/DataTableFlexScrollDemo.vue
Original file line number Diff line number Diff line change
@@ -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>
54 changes: 52 additions & 2 deletions src/views/datatable/DataTableScrollDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -168,7 +204,8 @@ export default {
frozenCars: null,
lazyCars: null,
lazyTotalRecords: 0,
loading: false
loading: false,
dialogVisible: false
}
},
carService: null,
Expand Down Expand Up @@ -260,6 +297,12 @@ export default {
else
this.lazyCars = this.loadChunk(event.first, event.rows)
}, 250);
},
openDialog() {
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
}
}
}
Expand Down Expand Up @@ -291,7 +334,8 @@ export default {
frozenCars: null,
lazyCars: null,
lazyTotalRecords: 0,
loading: false
loading: false,
dialogVisible: false
}
},
carService: null,
Expand Down Expand Up @@ -383,6 +427,12 @@ export default {
else
this.lazyCars = this.loadChunk(event.first, event.rows)
}, 250);
},
openDialog() {
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
}
}
}
Expand Down

0 comments on commit 3ae6ee1

Please sign in to comment.