Frozen Columns for DataTable
parent
b50286bca6
commit
2889aeae5b
|
@ -23,4 +23,5 @@ export declare class Column extends Vue {
|
||||||
rowReorderIcon?: string;
|
rowReorderIcon?: string;
|
||||||
reorderableColumn?: boolean;
|
reorderableColumn?: boolean;
|
||||||
rowEditor?: boolean;
|
rowEditor?: boolean;
|
||||||
|
frozen?: boolean;
|
||||||
}
|
}
|
|
@ -89,6 +89,10 @@ export default {
|
||||||
rowEditor: {
|
rowEditor: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
frozen: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -40,9 +40,9 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-datatable-scrollable-wrapper" v-else>
|
<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>
|
<template #header>
|
||||||
<DTTableHeader :columnGroup="headerColumnGroup" :columns="columns" :rowGroupMode="rowGroupMode"
|
<DTTableHeader :columnGroup="frozenHeaderColumnGroup" :columns="frozenColumns" :rowGroupMode="rowGroupMode"
|
||||||
:groupRowsBy="groupRowsBy" :resizableColumns="resizableColumns" :allRowsSelected="allRowsSelected" :empty="empty"
|
:groupRowsBy="groupRowsBy" :resizableColumns="resizableColumns" :allRowsSelected="allRowsSelected" :empty="empty"
|
||||||
:sortMode="sortMode" :sortField="d_sortField" :sortOrder="d_sortOrder" :multiSortMeta="d_multiSortMeta"
|
:sortMode="sortMode" :sortField="d_sortField" :sortOrder="d_sortOrder" :multiSortMeta="d_multiSortMeta"
|
||||||
@column-click="onColumnHeaderClick($event)" @column-mousedown="onColumnHeaderMouseDown($event)"
|
@column-click="onColumnHeaderClick($event)" @column-mousedown="onColumnHeaderMouseDown($event)"
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
@column-resizestart="onColumnResizeStart($event)" @checkbox-change="toggleRowsWithCheckbox($event)" />
|
@column-resizestart="onColumnResizeStart($event)" @checkbox-change="toggleRowsWithCheckbox($event)" />
|
||||||
</template>
|
</template>
|
||||||
<template #body>
|
<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"
|
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :expandableRowGroups="expandableRowGroups" :rowClass="rowClass" :editMode="editMode" :compareSelectionBy="compareSelectionBy"
|
||||||
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
|
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
|
||||||
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$scopedSlots"
|
: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)"/>
|
@row-edit-init="onRowEditInit($event)" @row-edit-save="onRowEditSave($event)" @row-edit-cancel="onRowEditCancel($event)"/>
|
||||||
</template>
|
</template>
|
||||||
<template #frozenbody>
|
<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"
|
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :expandableRowGroups="expandableRowGroups" :rowClass="rowClass" :editMode="editMode" :compareSelectionBy="compareSelectionBy"
|
||||||
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
|
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
|
||||||
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$scopedSlots"
|
: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)"/>
|
@row-edit-init="onRowEditInit($event)" @row-edit-save="onRowEditSave($event)" @row-edit-cancel="onRowEditCancel($event)"/>
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<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>
|
</template>
|
||||||
</DTScrollableView>
|
</DTScrollableView>
|
||||||
</div>
|
</div>
|
||||||
|
@ -294,6 +329,10 @@ export default {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
|
frozenWidth: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -1485,6 +1524,33 @@ export default {
|
||||||
}
|
}
|
||||||
return columns;
|
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() {
|
headerColumnGroup() {
|
||||||
if (this.allChildren) {
|
if (this.allChildren) {
|
||||||
for (let child of this.allChildren) {
|
for (let child of this.allChildren) {
|
||||||
|
@ -1496,6 +1562,17 @@ export default {
|
||||||
|
|
||||||
return null;
|
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() {
|
footerColumnGroup() {
|
||||||
if (this.allChildren) {
|
if (this.allChildren) {
|
||||||
for (let child of this.allChildren) {
|
for (let child of this.allChildren) {
|
||||||
|
@ -1507,6 +1584,17 @@ export default {
|
||||||
|
|
||||||
return null;
|
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() {
|
processedData() {
|
||||||
if (this.lazy) {
|
if (this.lazy) {
|
||||||
return this.value;
|
return this.value;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<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" ref="scrollHeader" @scroll="onHeaderScroll">
|
||||||
<div class="p-datatable-scrollable-header-box" ref="scrollHeaderBox">
|
<div class="p-datatable-scrollable-header-box" ref="scrollHeaderBox">
|
||||||
<table class="p-datatable-scrollable-header-table'">
|
<table class="p-datatable-scrollable-header-table'">
|
||||||
|
@ -72,18 +72,18 @@ export default {
|
||||||
this.$refs.scrollHeader.scrollLeft = 0;
|
this.$refs.scrollHeader.scrollLeft = 0;
|
||||||
},
|
},
|
||||||
onBodyScroll() {
|
onBodyScroll() {
|
||||||
let frozenView = this.$refs.previousElementSibling;
|
let frozenView = this.$el.previousElementSibling;
|
||||||
let frozenScrollBody;
|
let frozenScrollBody;
|
||||||
if (frozenView) {
|
if (frozenView) {
|
||||||
frozenScrollBody = DomHandler.findSingle(frozenView, '.p-datatable-scrollable-body');
|
frozenScrollBody = DomHandler.findSingle(frozenView, '.p-datatable-scrollable-body');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$refs.scrollHeaderBox.style.marginLeft = -1 * this.$refs.scrollBody.scrollLeft + 'px';
|
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';
|
this.$refs.scrollFooterBox.style.marginLeft = -1 * this.$refs.scrollBody.scrollLeft + 'px';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(frozenScrollBody) {
|
if (frozenScrollBody) {
|
||||||
frozenScrollBody.scrollTop = this.$refs.scrollBody.scrollTop;
|
frozenScrollBody.scrollTop = this.$refs.scrollBody.scrollTop;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -166,6 +166,24 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
containerClass() {
|
containerClass() {
|
||||||
return ['p-datatable-scrollable-view', {'p-datatable-frozen-view': this.frozen, 'p-datatable-unfrozen-view': !this.frozen && this.frozenWidth}];
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,24 @@
|
||||||
<Column field="brand" header="Brand"></Column>
|
<Column field="brand" header="Brand"></Column>
|
||||||
<Column field="color" header="Color"></Column>
|
<Column field="color" header="Color"></Column>
|
||||||
</DataTable>
|
</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>
|
||||||
|
|
||||||
<div class="content-section documentation">
|
<div class="content-section documentation">
|
||||||
|
|
Loading…
Reference in New Issue