Frozen Columns for DataTable

pull/104/head
cagataycivici 2019-11-19 10:51:23 +03:00
parent b50286bca6
commit 2889aeae5b
5 changed files with 138 additions and 9 deletions

View File

@ -23,4 +23,5 @@ export declare class Column extends Vue {
rowReorderIcon?: string;
reorderableColumn?: boolean;
rowEditor?: boolean;
frozen?: boolean;
}

View File

@ -89,6 +89,10 @@ export default {
rowEditor: {
type: Boolean,
default: false
},
frozen: {
type: Boolean,
default: false
}
},
render() {

View File

@ -40,9 +40,9 @@
</table>
</div>
<div class="p-datatable-scrollable-wrapper" v-else>
<DTScrollableView :scrollHeight="scrollHeight" :columns="columns">
<DTScrollableView v-if="hasFrozenColumns" :scrollHeight="scrollHeight" :columns="frozenColumns" :frozenWidth="frozenWidth" :frozen="true">
<template #header>
<DTTableHeader :columnGroup="headerColumnGroup" :columns="columns" :rowGroupMode="rowGroupMode"
<DTTableHeader :columnGroup="frozenHeaderColumnGroup" :columns="frozenColumns" :rowGroupMode="rowGroupMode"
:groupRowsBy="groupRowsBy" :resizableColumns="resizableColumns" :allRowsSelected="allRowsSelected" :empty="empty"
:sortMode="sortMode" :sortField="d_sortField" :sortOrder="d_sortOrder" :multiSortMeta="d_multiSortMeta"
@column-click="onColumnHeaderClick($event)" @column-mousedown="onColumnHeaderMouseDown($event)"
@ -50,7 +50,7 @@
@column-resizestart="onColumnResizeStart($event)" @checkbox-change="toggleRowsWithCheckbox($event)" />
</template>
<template #body>
<DTTableBody :value="dataToRender" :columns="columns" :empty="empty" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode"
<DTTableBody :value="dataToRender" :columns="frozenColumns" :empty="empty" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode"
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :expandableRowGroups="expandableRowGroups" :rowClass="rowClass" :editMode="editMode" :compareSelectionBy="compareSelectionBy"
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$scopedSlots"
@ -61,7 +61,7 @@
@row-edit-init="onRowEditInit($event)" @row-edit-save="onRowEditSave($event)" @row-edit-cancel="onRowEditCancel($event)"/>
</template>
<template #frozenbody>
<DTTableBody :value="frozenValue" :columns="columns" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode"
<DTTableBody :value="frozenValue" :columns="frozenColumns" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode"
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :expandableRowGroups="expandableRowGroups" :rowClass="rowClass" :editMode="editMode" :compareSelectionBy="compareSelectionBy"
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$scopedSlots"
@ -72,7 +72,42 @@
@row-edit-init="onRowEditInit($event)" @row-edit-save="onRowEditSave($event)" @row-edit-cancel="onRowEditCancel($event)"/>
</template>
<template #footer>
<DTTableFooter :columnGroup="footerColumnGroup" :columns="columns" />
<DTTableFooter :columnGroup="frozenFooterColumnGroup" :columns="frozenColumns" />
</template>
</DTScrollableView>
<DTScrollableView :scrollHeight="scrollHeight" :columns="scrollableColumns" :frozenWidth="frozenWidth">
<template #header>
<DTTableHeader :columnGroup="headerColumnGroup" :columns="scrollableColumns" :rowGroupMode="rowGroupMode"
:groupRowsBy="groupRowsBy" :resizableColumns="resizableColumns" :allRowsSelected="allRowsSelected" :empty="empty"
:sortMode="sortMode" :sortField="d_sortField" :sortOrder="d_sortOrder" :multiSortMeta="d_multiSortMeta"
@column-click="onColumnHeaderClick($event)" @column-mousedown="onColumnHeaderMouseDown($event)"
@column-dragstart="onColumnHeaderDragStart($event)" @column-dragover="onColumnHeaderDragOver($event)" @column-dragleave="onColumnHeaderDragLeave($event)" @column-drop="onColumnHeaderDrop($event)"
@column-resizestart="onColumnResizeStart($event)" @checkbox-change="toggleRowsWithCheckbox($event)" />
</template>
<template #body>
<DTTableBody :value="dataToRender" :columns="scrollableColumns" :empty="empty" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode"
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :expandableRowGroups="expandableRowGroups" :rowClass="rowClass" :editMode="editMode" :compareSelectionBy="compareSelectionBy"
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$scopedSlots"
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-touchend="onRowTouchEnd" @row-keydown="onRowKeyDown"
@row-mousedown="onRowMouseDown" @row-dragstart="onRowDragStart($event)" @row-dragover="onRowDragOver($event)" @row-dragleave="onRowDragLeave($event)" @row-dragend="onRowDragEnd($event)" @row-drop="onRowDrop($event)"
@row-toggle="toggleRow($event)" @radio-change="toggleRowWithRadio($event)" @checkbox-change="toggleRowWithCheckbox($event)"
@cell-edit-init="onCellEditInit($event)" @cell-edit-complete="onCellEditComplete($event)" @cell-edit-cancel="onCellEditCancel($event)"
@row-edit-init="onRowEditInit($event)" @row-edit-save="onRowEditSave($event)" @row-edit-cancel="onRowEditCancel($event)"/>
</template>
<template #frozenbody>
<DTTableBody :value="frozenValue" :columns="scrollableColumns" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode"
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :expandableRowGroups="expandableRowGroups" :rowClass="rowClass" :editMode="editMode" :compareSelectionBy="compareSelectionBy"
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$scopedSlots"
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-touchend="onRowTouchEnd" @row-keydown="onRowKeyDown"
@row-mousedown="onRowMouseDown" @row-dragstart="onRowDragStart($event)" @row-dragover="onRowDragOver($event)" @row-dragleave="onRowDragLeave($event)" @row-dragend="onRowDragEnd($event)" @row-drop="onRowDrop($event)"
@row-toggle="toggleRow($event)" @radio-change="toggleRowWithRadio($event)" @checkbox-change="toggleRowWithCheckbox($event)"
@cell-edit-init="onCellEditInit($event)" @cell-edit-complete="onCellEditComplete($event)" @cell-edit-cancel="onCellEditCancel($event)"
@row-edit-init="onRowEditInit($event)" @row-edit-save="onRowEditSave($event)" @row-edit-cancel="onRowEditCancel($event)"/>
</template>
<template #footer>
<DTTableFooter :columnGroup="footerColumnGroup" :columns="scrollableColumns" />
</template>
</DTScrollableView>
</div>
@ -294,6 +329,10 @@ export default {
type: Array,
default: null
},
frozenWidth: {
type: String,
default: null
}
},
data() {
return {
@ -1485,6 +1524,33 @@ export default {
}
return columns;
},
frozenColumns() {
let frozenColumns = [];
for(let col of this.columns) {
if(col.frozen) {
frozenColumns = frozenColumns||[];
frozenColumns.push(col);
}
}
return frozenColumns;
},
scrollableColumns() {
let scrollableColumns = [];
for(let col of this.columns) {
if(!col.frozen) {
scrollableColumns = scrollableColumns||[];
scrollableColumns.push(col);
}
}
return scrollableColumns;
},
hasFrozenColumns() {
return this.frozenColumns.length > 0;
},
headerColumnGroup() {
if (this.allChildren) {
for (let child of this.allChildren) {
@ -1496,6 +1562,17 @@ export default {
return null;
},
frozenHeaderColumnGroup() {
if (this.allChildren) {
for (let child of this.allChildren) {
if (child.$vnode.tag.indexOf('columngroup') !== -1 && child.type === 'frozenheader') {
return child;
}
}
}
return null;
},
footerColumnGroup() {
if (this.allChildren) {
for (let child of this.allChildren) {
@ -1507,6 +1584,17 @@ export default {
return null;
},
frozenFooterColumnGroup() {
if (this.allChildren) {
for (let child of this.allChildren) {
if (child.$vnode.tag.indexOf('columngroup') !== -1 && child.type === 'frozenfooter') {
return child;
}
}
}
return null;
},
processedData() {
if (this.lazy) {
return this.value;

View File

@ -1,5 +1,5 @@
<template>
<div :class="containerClass">
<div :class="containerClass" :style="containerStyle">
<div class="p-datatable-scrollable-header" ref="scrollHeader" @scroll="onHeaderScroll">
<div class="p-datatable-scrollable-header-box" ref="scrollHeaderBox">
<table class="p-datatable-scrollable-header-table'">
@ -72,18 +72,18 @@ export default {
this.$refs.scrollHeader.scrollLeft = 0;
},
onBodyScroll() {
let frozenView = this.$refs.previousElementSibling;
let frozenView = this.$el.previousElementSibling;
let frozenScrollBody;
if (frozenView) {
frozenScrollBody = DomHandler.findSingle(frozenView, '.p-datatable-scrollable-body');
}
this.$refs.scrollHeaderBox.style.marginLeft = -1 * this.$refs.scrollBody.scrollLeft + 'px';
if( this.$refs.scrollFooterBox) {
if (this.$refs.scrollFooterBox) {
this.$refs.scrollFooterBox.style.marginLeft = -1 * this.$refs.scrollBody.scrollLeft + 'px';
}
if(frozenScrollBody) {
if (frozenScrollBody) {
frozenScrollBody.scrollTop = this.$refs.scrollBody.scrollTop;
}
/*
@ -166,6 +166,24 @@ export default {
computed: {
containerClass() {
return ['p-datatable-scrollable-view', {'p-datatable-frozen-view': this.frozen, 'p-datatable-unfrozen-view': !this.frozen && this.frozenWidth}];
},
containerStyle() {
if (this.frozenWidth) {
if (this.frozen) {
return {
width: this.frozenWidth
};
}
else {
return {
width: 'calc(100% - ' + this.frozenWidth + ')',
left: this.frozenWidth
}
}
}
else {
return null;
}
}
}
}

View File

@ -37,6 +37,24 @@
<Column field="brand" header="Brand"></Column>
<Column field="color" header="Color"></Column>
</DataTable>
<h3>Frozen Columns</h3>
<DataTable :value="cars" :scrollable="true" scrollHeight="200px" frozenWidth="300px">
<Column field="vin" header="Vin" headerStyle="width: 300px" columnKey="vin_1" :frozen="true">
<template #body="slotProps">
<span style="font-weight: bold">{{slotProps.data.vin}}</span>
</template>
</Column>
<Column field="year" header="Year" headerStyle="width: 300px" columnKey="year_1"></Column>
<Column field="brand" header="Brand" headerStyle="width: 300px" columnKey="brand_1"></Column>
<Column field="color" header="Color" headerStyle="width: 300px" columnKey="color_1"></Column>
<Column field="year" header="Year" headerStyle="width: 300px" columnKey="year_2"></Column>
<Column field="brand" header="Brand" headerStyle="width: 300px" columnKey="brand_2"></Column>
<Column field="color" header="Color" headerStyle="width: 300px" columnKey="color_2"></Column>
<Column field="year" header="Year" headerStyle="width: 300px" columnKey="year_3"></Column>
<Column field="brand" header="Brand" headerStyle="width: 300px" columnKey="brand_3"></Column>
<Column field="color" header="Color" headerStyle="width: 300px" columnKey="color_3"></Column>
</DataTable>
</div>
<div class="content-section documentation">