Initiated new DataTable Scrolling Implementation

pull/973/head
Cagatay Civici 2021-02-10 13:28:47 +03:00
parent 7edffc6b4d
commit 3bd70d34c1
11 changed files with 551 additions and 605 deletions

View File

@ -34,6 +34,14 @@ export default {
type: null, type: null,
default: null default: null
}, },
style: {
type: null,
default: null
},
class: {
type: String,
default: null
},
headerStyle: { headerStyle: {
type: null, type: null,
default: null default: null

View File

@ -1,5 +1,5 @@
<template> <template>
<td :style="columnProp('bodyStyle')" :class="containerClass" @click="onClick" @keydown="onKeyDown"> <td :style="containerStyle" :class="containerClass" @click="onClick" @keydown="onKeyDown" role="cell">
<component :is="column.children.body" :data="rowData" :column="column" :index="index" v-if="column.children && column.children.body && !d_editing" /> <component :is="column.children.body" :data="rowData" :column="column" :index="index" v-if="column.children && column.children.body && !d_editing" />
<component :is="column.children.editor" :data="rowData" :column="column" :index="index" v-else-if="column.children && column.children.editor && d_editing" /> <component :is="column.children.editor" :data="rowData" :column="column" :index="index" v-else-if="column.children && column.children.editor && d_editing" />
<template v-else-if="columnProp('selectionMode')"> <template v-else-if="columnProp('selectionMode')">
@ -73,7 +73,10 @@ export default {
selfClick: false, selfClick: false,
data() { data() {
return { return {
d_editing: this.editing d_editing: this.editing,
styleObject: {
left: '0px'
}
} }
}, },
watch: { watch: {
@ -82,13 +85,13 @@ export default {
} }
}, },
mounted() { mounted() {
this.children = this.$children; if (this.columnProp('frozen')) {
this.updateStickyPosition();
}
}, },
updated() { updated() {
let query = this.editMode === 'row' ? '[autofocus]' : 'input'; if (this.columnProp('frozen')) {
let focusable = DomHandler.findSingle(this.$el, query); this.updateStickyPosition();
if (focusable && document.activeElement != focusable) {
focusable.focus();
} }
}, },
methods: { methods: {
@ -274,15 +277,33 @@ export default {
}, },
onRowEditCancel(event) { onRowEditCancel(event) {
this.$emit('row-edit-cancel', {originalEvent: event, data: this.rowData, field: this.columnProp('field'), index: this.index}); this.$emit('row-edit-cancel', {originalEvent: event, data: this.rowData, field: this.columnProp('field'), index: this.index});
},
updateStickyPosition() {
if (this.columnProp('frozen')) {
let left = 0;
let prev = this.$el.previousElementSibling;
if (prev) {
left = DomHandler.getOuterWidth(prev) + parseFloat(prev.style.left);
}
this.styleObject.left = left + 'px';
}
} }
}, },
computed: { computed: {
containerClass() { containerClass() {
return [this.columnProp('bodyClass'), { return [this.columnProp('bodyClass'), this.columnProp('class'), {
'p-selection-column': this.columnProp('selectionMode') != null, 'p-selection-column': this.columnProp('selectionMode') != null,
'p-editable-column': this.isEditable(), 'p-editable-column': this.isEditable(),
'p-cell-editing': this.d_editing 'p-cell-editing': this.d_editing,
'p-frozen-column': this.columnProp('frozen')
}]; }];
},
containerStyle() {
let bodyStyle = this.columnProp('bodyStyle');
let columnStyle = this.columnProp('style');
return this.columnProp('frozen') ? [columnStyle, bodyStyle, this.styleObject]: [columnStyle, bodyStyle];
} }
}, },
components: { components: {

View File

@ -340,14 +340,12 @@ export default {
this.selfClick = true; this.selfClick = true;
}, },
onOverlayEnter() { onOverlayEnter() {
if (this.filterMenuStyle) {
DomHandler.applyStyle(this.overlay, this.filterMenuStyle);
}
document.body.appendChild(this.overlay); document.body.appendChild(this.overlay);
this.overlay.style.zIndex = String(DomHandler.generateZIndex()); this.overlay.style.zIndex = String(DomHandler.generateZIndex());
DomHandler.absolutePosition(this.overlay, this.$refs.icon); DomHandler.absolutePosition(this.overlay, this.$refs.icon);
if (this.filterMenuStyle) {
for (let prop in this.filterMenuStyle) {
this.overlay.style[prop] = this.filterMenuStyle[prop];
}
}
this.bindOutsideClickListener(); this.bindOutsideClickListener();
this.bindScrollListener(); this.bindScrollListener();
this.bindResizeListener(); this.bindResizeListener();

View File

@ -16,14 +16,23 @@
<slot name="paginatorRight"></slot> <slot name="paginatorRight"></slot>
</template> </template>
</DTPaginator> </DTPaginator>
<div class="p-datatable-wrapper" v-if="!scrollable"> <div class="p-datatable-wrapper" :style="{maxHeight: scrollHeight}">
<table ref="table" role="grid"> <table ref="table" role="table" class="p-datatable-table">
<DTTableHeader :columnGroup="headerColumnGroup" :columns="columns" :rowGroupMode="rowGroupMode" <DTTableHeader :columnGroup="headerColumnGroup" :columns="columns" :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" :filters="d_filters" :filtersStore="filters" :filterDisplay="filterDisplay" :sortMode="sortMode" :sortField="d_sortField" :sortOrder="d_sortOrder" :multiSortMeta="d_multiSortMeta" :filters="d_filters" :filtersStore="filters" :filterDisplay="filterDisplay"
@column-click="onColumnHeaderClick($event)" @column-mousedown="onColumnHeaderMouseDown($event)" @filter-change="onFilterChange" @filter-apply="onFilterApply" @column-click="onColumnHeaderClick($event)" @column-mousedown="onColumnHeaderMouseDown($event)" @filter-change="onFilterChange" @filter-apply="onFilterApply"
@column-dragstart="onColumnHeaderDragStart($event)" @column-dragover="onColumnHeaderDragOver($event)" @column-dragleave="onColumnHeaderDragLeave($event)" @column-drop="onColumnHeaderDrop($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)" /> @column-resizestart="onColumnResizeStart($event)" @checkbox-change="toggleRowsWithCheckbox($event)" />
<DTTableBody :value="frozenValue" :frozenRow="true" class="p-datatable-frozen-tbody" :columns="columns" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode" :contextMenu="contextMenu" :contextMenuSelection="contextMenuSelection"
: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="$slots" :loading="loading"
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-rightclick="onRowRightClick($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)"/>
<DTTableBody :value="dataToRender" :columns="columns" :empty="empty" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode" :contextMenu="contextMenu" :contextMenuSelection="contextMenuSelection" <DTTableBody :value="dataToRender" :columns="columns" :empty="empty" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode" :contextMenu="contextMenu" :contextMenuSelection="contextMenuSelection"
: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"
@ -36,83 +45,6 @@
<DTTableFooter :columnGroup="footerColumnGroup" :columns="columns" /> <DTTableFooter :columnGroup="footerColumnGroup" :columns="columns" />
</table> </table>
</div> </div>
<div class="p-datatable-scrollable-wrapper" v-else>
<DTScrollableView v-if="hasFrozenColumns" :scrollHeight="scrollHeight" :columns="frozenColumns" :frozenWidth="frozenWidth" :frozen="true"
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :headerColumnGroup="frozenHeaderColumnGroup" :footerColumnGroup="frozenFooterColumnGroup">
<template #header="slotProps">
<DTTableHeader :columnGroup="slotProps.columnGroup" :columns="slotProps.columns" :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="slotProps">
<DTTableBody :value="dataToRender" :columns="slotProps.columns" :empty="empty" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode" :contextMenu="contextMenu" :contextMenuSelection="contextMenuSelection"
: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="$slots" :loading="loading"
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-rightclick="onRowRightClick($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="slotProps">
<DTTableBody v-if="frozenValue" :value="frozenValue" :columns="slotProps.columns" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode" :contextMenu="contextMenu" :contextMenuSelection="contextMenuSelection"
: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="$slots" :loading="loading"
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-rightclick="onRowRightClick($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="slotProps">
<DTTableFooter :columnGroup="slotProps.columnGroup" :columns="slotProps.columns" />
</template>
</DTScrollableView>
<DTScrollableView :scrollHeight="scrollHeight" :columns="scrollableColumns" :frozenWidth="frozenWidth" :rows="rows"
:virtualScroll="virtualScroll" :virtualRowHeight="virtualRowHeight" :totalRecords="totalRecordsLength" @virtual-scroll="onVirtualScroll"
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :headerColumnGroup="headerColumnGroup" :footerColumnGroup="footerColumnGroup">
<template #header="slotProps">
<DTTableHeader :columnGroup="slotProps.columnGroup" :columns="slotProps.columns" :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)"
@operator-change="$emit('operator-change',$event)" @matchmode-change="$emit('matchmode-change',$event)"
@constraint-add="$emit('constraint-add',$event)" @constraint-remove="$emit('constraint-remove',$event)" @apply-click="$emit('apply-click',$event)" />
</template>
<template #body="slotProps">
<DTTableBody :value="dataToRender" :columns="slotProps.columns" :empty="empty" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode" :contextMenu="contextMenu" :contextMenuSelection="contextMenuSelection"
: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="$slots" :loading="loading"
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-rightclick="onRowRightClick($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="slotProps">
<DTTableBody v-if="frozenValue" :value="frozenValue" :columns="slotProps.columns" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode" :contextMenu="contextMenu" :contextMenuSelection="contextMenuSelection"
: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="$slots" :loading="loading"
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-rightclick="onRowRightClick($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="slotProps">
<DTTableFooter :columnGroup="slotProps.columnGroup" :columns="slotProps.columns" />
</template>
</DTScrollableView>
</div>
<DTPaginator v-if="paginatorBottom" :rows="d_rows" :first="d_first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions" <DTPaginator v-if="paginatorBottom" :rows="d_rows" :first="d_first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
:currentPageReportTemplate="currentPageReportTemplate" class="p-paginator-bottom" @page="onPage($event)" :alwaysShow="alwaysShowPaginator"> :currentPageReportTemplate="currentPageReportTemplate" class="p-paginator-bottom" @page="onPage($event)" :alwaysShow="alwaysShowPaginator">
<template #left v-if="$slots.paginatorLeft"> <template #left v-if="$slots.paginatorLeft">
@ -135,7 +67,6 @@
import {ObjectUtils,DomHandler} from 'primevue/utils'; import {ObjectUtils,DomHandler} from 'primevue/utils';
import {FilterMatchMode,FilterOperator,FilterService} from 'primevue/api'; import {FilterMatchMode,FilterOperator,FilterService} from 'primevue/api';
import Paginator from 'primevue/paginator'; import Paginator from 'primevue/paginator';
import ScrollableView from './ScrollableView.vue';
import TableHeader from './TableHeader.vue'; import TableHeader from './TableHeader.vue';
import TableBody from './TableBody.vue'; import TableBody from './TableBody.vue';
import TableFooter from './TableFooter.vue'; import TableFooter from './TableFooter.vue';
@ -352,6 +283,10 @@ export default {
type: Boolean, type: Boolean,
default: false default: false
}, },
scrollDirection: {
type: String,
default: "vertical"
},
scrollHeight: { scrollHeight: {
type: String, type: String,
default: null default: null
@ -1097,33 +1032,15 @@ export default {
let nextColumnWidth = nextColumn.offsetWidth - delta; let nextColumnWidth = nextColumn.offsetWidth - delta;
if (newColumnWidth > 15 && nextColumnWidth > 15) { if (newColumnWidth > 15 && nextColumnWidth > 15) {
if(this.scrollable) { this.resizeColumnElement.style.width = newColumnWidth + 'px';
const scrollableView = this.findParentScrollableView(this.resizeColumnElement); if(nextColumn) {
const scrollableBodyTable = DomHandler.findSingle(scrollableView, 'table.p-datatable-scrollable-body-table'); nextColumn.style.width = nextColumnWidth + 'px';
const scrollableHeaderTable = DomHandler.findSingle(scrollableView, 'table.p-datatable-scrollable-header-table');
const scrollableFooterTable = DomHandler.findSingle(scrollableView, 'table.p-datatable-scrollable-footer-table');
const resizeColumnIndex = DomHandler.index(this.resizeColumnElement);
this.resizeColGroup(scrollableHeaderTable, resizeColumnIndex, newColumnWidth, nextColumnWidth);
this.resizeColGroup(scrollableBodyTable, resizeColumnIndex, newColumnWidth, nextColumnWidth);
this.resizeColGroup(scrollableFooterTable, resizeColumnIndex, newColumnWidth, nextColumnWidth);
}
else {
this.resizeColumnElement.style.width = newColumnWidth + 'px';
if(nextColumn) {
nextColumn.style.width = nextColumnWidth + 'px';
}
} }
} }
} }
else if (this.columnResizeMode === 'expand') { else if (this.columnResizeMode === 'expand') {
if (this.scrollable) { this.$refs.table.style.width = this.$refs.table.offsetWidth + delta + 'px';
this.resizeScrollableTable(this.resizeColumnElement, newColumnWidth, delta); this.resizeColumnElement.style.width = newColumnWidth + 'px';
}
else {
this.$refs.table.style.width = this.$refs.table.offsetWidth + delta + 'px';
this.resizeColumnElement.style.width = newColumnWidth + 'px';
}
} }
this.$emit('column-resize-end', { this.$emit('column-resize-end', {
@ -1290,19 +1207,6 @@ export default {
return parent; return parent;
} }
}, },
findParentScrollableView(column) {
if (column) {
let parent = column.parentElement;
while (parent && !DomHandler.hasClass(parent, 'p-datatable-scrollable-view')) {
parent = parent.parentElement;
}
return parent;
}
else {
return null;
}
},
findColumnByKey(columns, key) { findColumnByKey(columns, key) {
if (columns && columns.length) { if (columns && columns.length) {
for (let i = 0; i < columns.length; i++) { for (let i = 0; i < columns.length; i++) {
@ -1315,38 +1219,6 @@ export default {
return null; return null;
}, },
resizeScrollableTable(column, newColumnWidth, delta) {
const scrollableView = column ? this.findParentScrollableView(column) : this.$el;
const scrollableBody = DomHandler.findSingle(scrollableView, '.p-datatable-scrollable-body');
const scrollableHeader = DomHandler.findSingle(scrollableView, '.p-datatable-scrollable-header');
const scrollableFooter = DomHandler.findSingle(scrollableView, '.p-datatable-scrollable-footer');
const scrollableBodyTable = DomHandler.findSingle(scrollableBody, 'table.p-datatable-scrollable-body-table');
const scrollableHeaderTable = DomHandler.findSingle(scrollableHeader, 'table.p-datatable-scrollable-header-table');
const scrollableFooterTable = DomHandler.findSingle(scrollableFooter, 'table.p-datatable-scrollable-footer-table');
const scrollableBodyTableWidth = column ? scrollableBodyTable.offsetWidth + delta : newColumnWidth;
const scrollableHeaderTableWidth = column ? scrollableHeaderTable.offsetWidth + delta : newColumnWidth;
const isContainerInViewport = this.$el.offsetWidth >= parseFloat(scrollableBodyTableWidth);
let setWidth = (container, table, width, isContainerInViewport) => {
if (container && table) {
container.style.width = isContainerInViewport ? width + DomHandler.calculateScrollbarWidth(scrollableBody) + 'px' : 'auto'
table.style.width = width + 'px';
}
};
setWidth(scrollableBody, scrollableBodyTable, scrollableBodyTableWidth, isContainerInViewport);
setWidth(scrollableHeader, scrollableHeaderTable, scrollableHeaderTableWidth, isContainerInViewport);
setWidth(scrollableFooter, scrollableFooterTable, scrollableHeaderTableWidth, isContainerInViewport);
if (column) {
let resizeColumnIndex = DomHandler.index(column);
this.resizeColGroup(scrollableHeaderTable, resizeColumnIndex, newColumnWidth, null);
this.resizeColGroup(scrollableBodyTable, resizeColumnIndex, newColumnWidth, null);
this.resizeColGroup(scrollableFooterTable, resizeColumnIndex, newColumnWidth, null);
}
},
onRowMouseDown(event) { onRowMouseDown(event) {
if (DomHandler.hasClass(event.target, 'p-datatable-reorderablerow-handle')) if (DomHandler.hasClass(event.target, 'p-datatable-reorderablerow-handle'))
event.currentTarget.draggable = true; event.currentTarget.draggable = true;
@ -1603,8 +1475,7 @@ export default {
state.columnWidths = widths.join(','); state.columnWidths = widths.join(',');
if (this.columnResizeMode === 'expand') { if (this.columnResizeMode === 'expand') {
state.tableWidth = this.scrollable ? DomHandler.findSingle(this.$el, '.p-datatable-scrollable-header-table').style.width : state.tableWidth = DomHandler.getOuterWidth(this.$refs.table) + 'px';
DomHandler.getOuterWidth(this.$refs.table) + 'px';
} }
}, },
restoreColumnWidths() { restoreColumnWidths() {
@ -1612,28 +1483,11 @@ export default {
let widths = this.columnWidthsState.split(','); let widths = this.columnWidthsState.split(',');
if (this.columnResizeMode === 'expand' && this.tableWidthState) { if (this.columnResizeMode === 'expand' && this.tableWidthState) {
if (this.scrollable) { this.$refs.table.style.width = this.tableWidthState;
this.resizeScrollableTable(null, this.tableWidthState, 0); this.$el.style.width = this.tableWidthState;
}
else {
this.$refs.table.style.width = this.tableWidthState;
this.$el.style.width = this.tableWidthState;
}
} }
if (this.scrollable) { DomHandler.find(this.$refs.table, '.p-datatable-thead > tr > th').forEach((header, index) => header.style.width = widths[index] + 'px');
let headerCols = DomHandler.find(this.$el, '.p-datatable-scrollable-header-table > colgroup > col');
let bodyCols = DomHandler.find(this.$el, '.p-datatable-scrollable-body-table > colgroup > col');
headerCols.forEach((col, index) => col.style.width = widths[index] + 'px');
bodyCols.forEach((col, index) => col.style.width = widths[index] + 'px');
}
else {
let headers = DomHandler.find(this.$refs.table, '.p-datatable-thead > tr > th');
headers.forEach((header, index) => header.style.width = widths[index] + 'px');
}
} }
}, },
onCellEditInit(event) { onCellEditInit(event) {
@ -1732,6 +1586,9 @@ export default {
'p-datatable-resizable': this.resizableColumns, 'p-datatable-resizable': this.resizableColumns,
'p-datatable-resizable-fit': this.resizableColumns && this.columnResizeMode === 'fit', 'p-datatable-resizable-fit': this.resizableColumns && this.columnResizeMode === 'fit',
'p-datatable-scrollable': this.scrollable, 'p-datatable-scrollable': this.scrollable,
'p-datatable-scrollable-vertical': this.scrollDirection === 'vertical',
'p-datatable-scrollable-horizontal': this.scrollDirection === 'horizontal',
'p-datatable-scrollable-both': this.scrollDirection === 'both',
'p-datatable-virtual-scrollable': this.virtualScroll, 'p-datatable-virtual-scrollable': this.virtualScroll,
'p-datatable-flex-scrollable': (this.scrollable && this.scrollHeight === 'flex') 'p-datatable-flex-scrollable': (this.scrollable && this.scrollHeight === 'flex')
} }
@ -1766,33 +1623,6 @@ export default {
return cols; return cols;
}, },
frozenColumns() {
let frozenColumns = [];
for(let col of this.columns) {
if(this.columnProp(col, 'frozen')) {
frozenColumns = frozenColumns||[];
frozenColumns.push(col);
}
}
return frozenColumns;
},
scrollableColumns() {
let scrollableColumns = [];
for(let col of this.columns) {
if(!this.columnProp(col, 'frozen')) {
scrollableColumns = scrollableColumns||[];
scrollableColumns.push(col);
}
}
return scrollableColumns;
},
hasFrozenColumns() {
return this.frozenColumns.length > 0;
},
headerColumnGroup() { headerColumnGroup() {
const children = this.getChildren(); const children = this.getChildren();
if (children) { if (children) {
@ -1805,18 +1635,6 @@ export default {
return null; return null;
}, },
frozenHeaderColumnGroup() {
const children = this.getChildren();
if (children) {
for (let child of children) {
if (child.type.name === 'columngroup' && this.columnProp(child, 'type') === 'frozenheader') {
return child;
}
}
}
return null;
},
footerColumnGroup() { footerColumnGroup() {
const children = this.getChildren(); const children = this.getChildren();
if (children) { if (children) {
@ -1829,18 +1647,6 @@ export default {
return null; return null;
}, },
frozenFooterColumnGroup() {
const children = this.getChildren();
if (children) {
for (let child of children) {
if (child.type.name === 'columngroup' && this.columnProp(child, 'type') === 'frozenfooter') {
return child;
}
}
}
return null;
},
processedData() { processedData() {
if (this.lazy) { if (this.lazy) {
return this.value; return this.value;
@ -1910,7 +1716,6 @@ export default {
}, },
components: { components: {
'DTPaginator': Paginator, 'DTPaginator': Paginator,
'DTScrollableView': ScrollableView,
'DTTableHeader': TableHeader, 'DTTableHeader': TableHeader,
'DTTableBody': TableBody, 'DTTableBody': TableBody,
'DTTableFooter': TableFooter, 'DTTableFooter': TableFooter,
@ -1946,9 +1751,9 @@ export default {
justify-content: center; justify-content: center;
} }
.p-datatable-auto-layout > .p-datatable-wrapper { /*.p-datatable-auto-layout > .p-datatable-wrapper {
overflow-x: auto; overflow-x: auto;
} }*/
.p-datatable-auto-layout > .p-datatable-wrapper > table { .p-datatable-auto-layout > .p-datatable-wrapper > table {
table-layout: auto; table-layout: auto;
@ -1959,43 +1764,65 @@ export default {
} }
/* Scrollable */ /* Scrollable */
.p-datatable-scrollable-wrapper { .p-datatable-scrollable .p-datatable-wrapper {
position: relative; position: relative;
}
.p-datatable-scrollable-header,
.p-datatable-scrollable-footer {
overflow: hidden;
}
.p-datatable-scrollable-body {
overflow: auto; overflow: auto;
position: relative;
} }
.p-datatable-scrollable-body > table > .p-datatable-tbody > tr:first-child > td { .p-datatable-scrollable .p-datatable-table {
border-top: 0 none; display: block;
} }
.p-datatable-virtual-table { .p-datatable-scrollable .p-datatable-thead,
position: absolute; .p-datatable-scrollable .p-datatable-tbody,
.p-datatable-scrollable .p-datatable-tfoot {
display: block;
} }
/* Frozen Columns */ .p-datatable-scrollable .p-datatable-thead > tr,
.p-datatable-frozen-view .p-datatable-scrollable-body { .p-datatable-scrollable .p-datatable-tbody > tr,
overflow: hidden; .p-datatable-scrollable .p-datatable-tfoot > tr {
display: flex;
flex-wrap: nowrap;
width: 100%;
} }
.p-datatable-frozen-view > .p-datatable-scrollable-body > table > .p-datatable-tbody > tr > td:last-child { .p-datatable-scrollable .p-datatable-thead > tr > th,
border-right: 0 none; .p-datatable-scrollable .p-datatable-tbody > tr > td,
.p-datatable-scrollable .p-datatable-tfoot > tr > td {
flex: 1 1 0;
} }
.p-datatable-unfrozen-view { .p-datatable-scrollable .p-datatable-thead {
position: absolute; position: sticky;
top: 0; top: 0;
z-index: 1;
}
.p-datatable-scrollable .p-datatable-frozen-tbody {
position: sticky;
}
.p-datatable-scrollable .p-datatable-tfoot {
position: sticky;
bottom: 0;
z-index: 1;
}
.p-datatable-scrollable .p-frozen-column {
position: sticky;
background: inherit;
}
.p-datatable-scrollable-both .p-datatable-thead > tr > th,
.p-datatable-scrollable-both .p-datatable-tbody > tr > td,
.p-datatable-scrollable-both .p-datatable-tfoot > tr > td,
.p-datatable-scrollable-horizontal .p-datatable-thead > tr > th
.p-datatable-scrollable-horizontal .p-datatable-tbody > tr > td,
.p-datatable-scrollable-horizontal .p-datatable-tfoot > tr > td {
flex: 0 0 auto;
} }
/* Flex Scrollable */
.p-datatable-flex-scrollable { .p-datatable-flex-scrollable {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -2003,18 +1830,13 @@ export default {
height: 100%; height: 100%;
} }
.p-datatable-flex-scrollable .p-datatable-scrollable-wrapper, .p-datatable-flex-scrollable .p-datatable-wrapper {
.p-datatable-flex-scrollable .p-datatable-scrollable-view {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 1; flex: 1;
height: 100%; height: 100%;
} }
.p-datatable-flex-scrollable .p-datatable-scrollable-body {
flex: 1;
}
/* Resizable */ /* Resizable */
.p-datatable-resizable > .p-datatable-wrapper { .p-datatable-resizable > .p-datatable-wrapper {
overflow-x: auto; overflow-x: auto;

View File

@ -0,0 +1,66 @@
<template>
<td :style="containerStyle" :class="containerClass" role="cell"
:colspan="columnProp('colspan')" :rowspan="columnProp('rowspan')">
<component :is="column.children.footer" :column="column" v-if="column.children && column.children.footer"/>
{{columnProp('footer')}}
</td>
</template>
<script>
import {DomHandler} from 'primevue/utils';
export default {
props: {
column: {
type: null,
default: null
}
},
data() {
return {
styleObject: {
left: '0px'
}
}
},
mounted() {
if (this.columnProp('frozen')) {
this.updateStickyPosition();
}
},
updated() {
if (this.columnProp('frozen')) {
this.updateStickyPosition();
}
},
methods: {
columnProp(prop) {
return this.column.props ? ((this.column.type.props[prop].type === Boolean && this.column.props[prop] === '') ? true : this.column.props[prop]) : null;
},
updateStickyPosition() {
if (this.columnProp('frozen')) {
let left = 0;
let prev = this.$el.previousElementSibling;
if (prev) {
left = DomHandler.getOuterWidth(prev) + parseFloat(prev.style.left);
}
this.styleObject.left = left + 'px';
}
}
},
computed: {
containerClass() {
return [this.columnProp('footerClass'), this.columnProp('class'), {
'p-frozen-column': this.columnProp('frozen')
}];
},
containerStyle() {
let bodyStyle = this.columnProp('footerStyle');
let columnStyle = this.columnProp('style');
return this.columnProp('frozen') ? [columnStyle, bodyStyle, this.styleObject]: [columnStyle, bodyStyle];
}
}
}
</script>

View File

@ -0,0 +1,225 @@
<template>
<th :style="containerStyle" :class="containerClass" :tabindex="columnProp('sortable') ? '0' : null" role="cell"
@click="onClick" @keydown="onKeyDown" @mousedown="onMouseDown"
@dragstart="onDragStart" @dragover="onDragOver" @dragleave="onDragLeave" @drop="onDrop"
:colspan="columnProp('colspan')" :rowspan="columnProp('rowspan')" :aria-sort="ariaSort">
<span class="p-column-resizer" @mousedown="onResizeStart" v-if="resizableColumns"></span>
<div class="p-column-header-content">
<component :is="col.children.header" :column="column" v-if="column.children && column.children.header"/>
<span class="p-column-title" v-if="columnProp('header')">{{columnProp('header')}}</span>
<span v-if="columnProp('sortable')" :class="sortableColumnIcon"></span>
<span v-if="isMultiSorted()" class="p-sortable-column-badge">{{getMultiSortMetaIndex() + 1}}</span>
<DTHeaderCheckbox :checked="allRowsSelected" @change="onHeaderCheckboxChange" :disabled="empty" v-if="columnProp('selectionMode') ==='multiple' && filterDisplay !== 'row'" />
<DTColumnFilter v-if="filterDisplay === 'menu' && column.children && column.children.filter" :field="columnProp('filterField')||columnProp('field')" :type="columnProp('dataType')" display="menu"
:showMenu="columnProp('showFilterMenu')" :filterElement="column.children && column.children.filter"
:filterHeaderTemplate="column.children && column.children.filterheader" :filterFooterTemplate="column.children && column.children.filterfooter"
:filterClearTemplate="column.children && column.children.filterclear" :filterApplyTemplate="column.children && column.children.filterapply"
:filters="filters" :filtersStore="filtersStore" @filter-change="$emit('filter-change', $event)" @filter-apply="$emit('filter-apply')" :filterMenuStyle="columnProp('filterMenuStyle')" :filterMenuClass="columnProp('filterMenuClass')"
:showOperator="columnProp('showFilterOperator')" :showClearButton="columnProp('showClearButton')" :showApplyButton="columnProp('showApplyButton')"
:showMatchModes="columnProp('showFilterMatchModes')" :showAddButton="columnProp('showAddButton')" :matchModeOptions="columnProp('filterMatchModeOptions')" :maxConstraints="columnProp('maxConstraints')"
@operator-change="$emit('operator-change',$event)" @matchmode-change="$emit('matchmode-change', $event)" @constraint-add="$emit('constraint-add', $event)" @constraint-remove="$emit('constraint-remove', $event)" @apply-click="$emit('apply-click',$event)"/>
</div>
</th>
</template>
<script>
import {DomHandler} from 'primevue/utils';
import HeaderCheckbox from './HeaderCheckbox.vue';
import ColumnFilter from './ColumnFilter';
export default {
emits: ['column-click', 'column-mousedown', 'column-dragstart', 'column-dragover', 'column-dragleave', 'column-drop',
'column-resizestart', 'checkbox-change', 'filter-change', 'filter-apply',
'operator-change', 'matchmode-change', 'constraint-add', 'constraint-remove', 'filter-clear', 'apply-click'],
props: {
column: {
type: Object,
default: null
},
resizableColumns: {
type: Boolean,
default: false
},
sortMode: {
type: String,
default: 'single'
},
sortField: {
type: [String, Function],
default: null
},
sortOrder: {
type: Number,
default: null
},
multiSortMeta: {
type: Array,
default: null
},
allRowsSelected: {
type: Boolean,
default: false
},
empty: {
type: Boolean,
default: false
},
filterDisplay: {
type: String,
default: null
},
filters: {
type: Object,
default: null
},
filtersStore: {
type: Object,
default: null
},
filterColumn: {
type: Boolean,
default: false
}
},
data() {
return {
styleObject: {
left: '0px'
}
}
},
mounted() {
if (this.columnProp('frozen')) {
this.updateStickyPosition();
}
},
updated() {
if (this.columnProp('frozen')) {
this.updateStickyPosition();
}
},
methods: {
columnProp(prop) {
return this.column.props ? ((this.column.type.props[prop].type === Boolean && this.column.props[prop] === '') ? true : this.column.props[prop]) : null;
},
onClick(event) {
this.$emit('column-click', {originalEvent: event, column: this.column});
},
onKeyDown(event) {
if (event.which === 13 && event.currentTarget.nodeName === 'TH' && DomHandler.hasClass(event.currentTarget, 'p-sortable-column')) {
this.$emit('column-click', {originalEvent: event, column: this.column});
}
},
onMouseDown(event) {
this.$emit('column-mousedown', {originalEvent: event, column: this.column});
},
onDragStart(event) {
this.$emit('column-dragstart', event);
},
onDragOver(event) {
this.$emit('column-dragover', event);
},
onDragLeave(event) {
this.$emit('column-dragleave', event);
},
onDrop(event) {
this.$emit('column-drop', event);
},
onResizeStart(event) {
this.$emit('column-resizestart', event);
},
getMultiSortMetaIndex() {
let index = -1;
for (let i = 0; i < this.multiSortMeta.length; i++) {
let meta = this.multiSortMeta[i];
if (meta.field === this.columnProp('field') || meta.field === this.columnProp('sortField')) {
index = i;
break;
}
}
return index;
},
isMultiSorted() {
return this.columnProp('sortable') && this.getMultiSortMetaIndex() > -1
},
isColumnSorted() {
return this.sortMode === 'single' ? (this.sortField && (this.sortField === this.columnProp('field') || this.sortField === this.columnProp('sortField'))) : this.isMultiSorted();
},
updateStickyPosition() {
if (this.columnProp('frozen')) {
let left = 0;
let prev = this.$el.previousElementSibling;
if (prev) {
left = DomHandler.getOuterWidth(prev) + parseFloat(prev.style.left);
}
this.styleObject.left = left + 'px';
}
},
onHeaderCheckboxChange(event) {
this.$emit('checkbox-change', event);
}
},
computed: {
containerClass() {
return [this.filterColumn ? this.columnProp('headerClass') : this.columnProp('filterHeaderClass'), this.columnProp('class'), {
'p-sortable-column': this.columnProp('sortable'),
'p-resizable-column': this.resizableColumns,
'p-highlight': this.isColumnSorted(),
'p-filter-column': this.filterColumn,
'p-frozen-column': this.columnProp('frozen')
}];
},
containerStyle() {
let headerStyle = this.filterColumn ? this.columnProp('filterHeaderStyle'): this.columnProp('headerStyle');
let columnStyle = this.columnProp('style');
return this.columnProp('frozen') ? [columnStyle, headerStyle, this.styleObject]: [columnStyle, headerStyle];
},
sortableColumnIcon() {
let sorted = false;
let sortOrder = null;
if (this.sortMode === 'single') {
sorted = this.sortField && (this.sortField === this.columnProp('field') || this.sortField === this.columnProp('sortField'));
sortOrder = sorted ? this.sortOrder: 0;
}
else if (this.sortMode === 'multiple') {
let metaIndex = this.getMultiSortMetaIndex();
if (metaIndex > -1) {
sorted = true;
sortOrder = this.multiSortMeta[metaIndex].order;
}
}
return [
'p-sortable-column-icon pi pi-fw', {
'pi-sort-alt': !sorted,
'pi-sort-amount-up-alt': sorted && sortOrder > 0,
'pi-sort-amount-down': sorted && sortOrder < 0
}
];
},
ariaSort() {
if (this.columnProp('sortable')) {
const sortIcon = this.getSortableColumnIcon();
if (sortIcon[1]['pi-sort-amount-down'])
return 'descending';
else if (sortIcon[1]['pi-sort-amount-up-alt'])
return 'ascending';
else
return 'none';
}
else {
return null;
}
}
},
components: {
'DTHeaderCheckbox': HeaderCheckbox,
'DTColumnFilter': ColumnFilter
}
}
</script>

View File

@ -1,238 +0,0 @@
<template>
<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">
<colgroup>
<template v-for="(col,i) of columns">
<col v-if="shouldRenderCol(col)" :key="columnProp(col,'columnKey')||columnProp(col,'field')||i" :style="columnProp(col,'headerStyle')" :class="columnProp(col,'headerClass')"/>
</template>
</colgroup>
<slot name="header" :columns="columns" :columnGroup="headerColumnGroup"></slot>
<slot name="frozenbody" :columns="columns"></slot>
</table>
</div>
</div>
<div class="p-datatable-scrollable-body" ref="scrollBody" @scroll="onBodyScroll" :style="bodyStyle">
<table ref="scrollTable" :class="bodyTableClass" :style="bodyTableStyle">
<colgroup>
<template v-for="(col,i) of columns">
<col v-if="shouldRenderCol(col)" :key="columnProp(col,'columnKey')||columnProp(col,'field')||i"
:style="columnProp(col,'bodyStyle')" :class="columnProp(col,'bodyClass')"/>
</template>
</colgroup>
<slot name="body" :columns="columns"></slot>
</table>
<table ref="loadingTable" :style="{top:'0', display: 'none'}" class="p-datatable-scrollable-body-table p-datatable-loading-virtual-table p-datatable-virtual-table" v-if="virtualScroll">
<colgroup>
<col v-for="(col,i) of columns" :key="columnProp(col,'columnKey')||columnProp(col,'field')||i"
:style="columnProp(col,'bodyStyle')" :class="columnProp(col,'bodyClass')" />
</colgroup>
<DTTableLoadingBody :columns="columns" :rows="rows" />
</table>
<div class="p-datatable-virtual-scroller" ref="virtualScroller"></div>
</div>
<div class="p-datatable-scrollable-footer" ref="scrollFooter">
<div class="p-datatable-scrollable-footer-box" ref="scrollFooterBox">
<table class="p-datatable-scrollable-footer-table">
<colgroup>
<template v-for="(col,i) of columns">
<col v-if="shouldRenderCol(col)" :key="columnProp(col,'columnKey')||columnProp(col,'field')||i"
:style="columnProp(col,'footerStyle')" :class="columnProp(col,'footerClass')" />
</template>
</colgroup>
<slot name="footer" :columns="columns" :columnGroup="footerColumnGroup"></slot>
</table>
</div>
</div>
</div>
</template>
<script>
import {DomHandler} from 'primevue/utils';
import TableLoadingBody from './TableLoadingBody.vue';
export default {
emits: ['virtual-scroll'],
props: {
frozen: {
type: Boolean,
default: false
},
frozenWidth: {
type: String,
default: null
},
columns: {
type: null,
default: null
},
headerColumnGroup: {
type: null,
default: null
},
footerColumnGroup: {
type: null,
default: null
},
scrollHeight: {
type: String,
default: null
},
virtualScroll: {
type: Boolean,
default: false
},
virtualRowHeight: {
type: Number,
default: null
},
rows: {
type: Number,
default: null,
},
totalRecords: {
type: Number,
default: 0
},
rowGroupMode: {
type: String,
default: null
},
groupRowsBy: {
type: [Array,String],
default: null
}
},
virtualScrollCallback: null,
mounted() {
if (!this.frozen)
this.alignScrollBar();
else
this.$refs.scrollBody.style.paddingBottom = DomHandler.calculateScrollbarWidth() + 'px';
if (this.virtualScroll) {
this.$refs.virtualScroller.style.height = this.totalRecords * this.virtualRowHeight + 'px';
}
},
updated() {
if (this.virtualScrollCallback) {
this.virtualScrollCallback();
this.virtualScrollCallback = null;
}
},
watch: {
totalRecords(newValue) {
if (this.virtualScroll) {
this.$refs.virtualScroller.style.height = newValue * this.virtualRowHeight + 'px';
}
}
},
methods: {
columnProp(col, prop) {
return col.props ? ((col.type.props[prop].type === Boolean && col.props[prop] === '') ? true : col.props[prop]) : null;
},
onHeaderScroll() {
this.$refs.scrollHeader.scrollLeft = 0;
},
onBodyScroll() {
let frozenView = this.$el.previousElementSibling;
let frozenScrollBody;
if (frozenView) {
frozenScrollBody = DomHandler.findSingle(frozenView, '.p-datatable-scrollable-body');
}
if (frozenScrollBody) {
frozenScrollBody.scrollTop = this.$refs.scrollBody.scrollTop;
}
this.$refs.scrollHeaderBox.style.marginLeft = -1 * this.$refs.scrollBody.scrollLeft + 'px';
if (this.$refs.scrollFooterBox) {
this.$refs.scrollFooterBox.style.marginLeft = -1 * this.$refs.scrollBody.scrollLeft + 'px';
}
if (this.virtualScroll) {
let viewport = DomHandler.getClientHeight(this.$refs.scrollBody);
let tableHeight = DomHandler.getOuterHeight(this.$refs.scrollTable);
let pageHeight = this.virtualRowHeight * this.rows;
let virtualTableHeight = DomHandler.getOuterHeight(this.$refs.virtualScroller);
let pageCount = (virtualTableHeight / pageHeight)||1;
let scrollBodyTop = this.$refs.scrollTable.style.top||'0';
if(this.$refs.scrollBody.scrollTop + viewport > parseFloat(scrollBodyTop) + tableHeight || this.$refs.scrollBody.scrollTop < parseFloat(scrollBodyTop)) {
if (this.$refs.loadingTable) {
this.$refs.loadingTable.style.display = 'table';
this.$refs.loadingTable.style.top = this.$refs.scrollBody.scrollTop + 'px';
}
let page = Math.floor((this.$refs.scrollBody.scrollTop * pageCount) / (this.$refs.scrollBody.scrollHeight)) + 1;
this.$emit('virtual-scroll', {
page: page
});
this.virtualScrollCallback = () => {
if (this.$refs.loadingTable) {
this.$refs.loadingTable.style.display = 'none';
}
this.$refs.scrollTable.style.top = ((page - 1) * pageHeight) + 'px';
}
}
}
},
alignScrollBar() {
let scrollBarWidth = DomHandler.calculateScrollbarWidth();
this.$refs.scrollHeaderBox.style.paddingRight = scrollBarWidth + 'px';
if (this.$refs.scrollFooterBox) {
this.$refs.scrollFooterBox.style.paddingRight = scrollBarWidth + 'px';
}
},
shouldRenderCol(column) {
if (this.rowGroupMode && this.rowGroupMode === 'subheader') {
return this.groupRowsBy !== this.columnProp(column, 'field');
}
return true;
}
},
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;
}
},
bodyTableClass() {
return ['p-datatable-scrollable-body-table', {'p-datatable-virtual-table': this.virtualScroll}];
},
bodyTableStyle() {
return this.virtualScroll ? {top: '0'} : null;
},
bodyStyle() {
return {
maxHeight: this.scrollHeight !== 'flex' ? this.scrollHeight: null,
overflowY: !this.frozen && this.scrollHeight ? 'scroll': null
}
}
},
components: {
'DTTableLoadingBody': TableLoadingBody
}
}
</script>

View File

@ -1,8 +1,8 @@
<template> <template>
<tbody class="p-datatable-tbody"> <tbody class="p-datatable-tbody" role="rowgroup">
<template v-if="!empty"> <template v-if="!empty">
<template v-for="(rowData, index) of value"> <template v-for="(rowData, index) of value" :key="getRowKey(rowData, index) + '_subheader'">
<tr class="p-rowgroup-header" v-if="templates['groupheader'] && rowGroupMode === 'subheader' && shouldRenderRowGroupHeader(value, rowData, index)" :key="getRowKey(rowData, index) + '_subheader'"> <tr class="p-rowgroup-header" v-if="templates['groupheader'] && rowGroupMode === 'subheader' && shouldRenderRowGroupHeader(value, rowData, index)" role="row">
<td :colspan="columnsLength - 1"> <td :colspan="columnsLength - 1">
<button class="p-row-toggler p-link" @click="onRowGroupToggle($event, rowData)" v-if="expandableRowGroups" type="button"> <button class="p-row-toggler p-link" @click="onRowGroupToggle($event, rowData)" v-if="expandableRowGroups" type="button">
<span :class="rowGroupTogglerIcon(rowData)"></span> <span :class="rowGroupTogglerIcon(rowData)"></span>
@ -13,9 +13,9 @@
<tr :class="getRowClass(rowData)" :key="getRowKey(rowData, index)" <tr :class="getRowClass(rowData)" :key="getRowKey(rowData, index)"
v-if="expandableRowGroups ? isRowGroupExpanded(rowData): true" v-if="expandableRowGroups ? isRowGroupExpanded(rowData): true"
@click="onRowClick($event, rowData, index)" @contextmenu="onRowRightClick($event, rowData, index)" @touchend="onRowTouchEnd($event)" @keydown="onRowKeyDown($event, rowData, index)" :tabindex="selectionMode || contextMenu ? '0' : null" @click="onRowClick($event, rowData, index)" @contextmenu="onRowRightClick($event, rowData, index)" @touchend="onRowTouchEnd($event)" @keydown="onRowKeyDown($event, rowData, index)" :tabindex="selectionMode || contextMenu ? '0' : null"
@mousedown="onRowMouseDown($event)" @dragstart="onRowDragStart($event, index)" @dragover="onRowDragOver($event,index)" @dragleave="onRowDragLeave($event)" @dragend="onRowDragEnd($event)" @drop="onRowDrop($event)"> @mousedown="onRowMouseDown($event)" @dragstart="onRowDragStart($event, index)" @dragover="onRowDragOver($event,index)" @dragleave="onRowDragLeave($event)" @dragend="onRowDragEnd($event)" @drop="onRowDrop($event)" role="row">
<template v-for="(col,i) of columns"> <template v-for="(col,i) of columns" :key="columnProp(col,'columnKey')||columnProp(col,'field')||i">
<DTBodyCell v-if="shouldRenderBodyCell(value, col, index)" :key="columnProp(col,'columnKey')||columnProp(col,'field')||i" :rowData="rowData" :column="col" :index="index" :selected="isSelected(rowData)" <DTBodyCell v-if="shouldRenderBodyCell(value, col, index)" :rowData="rowData" :column="col" :index="index" :selected="isSelected(rowData)"
:rowTogglerIcon="columnProp(col,'expander') ? rowTogglerIcon(rowData): null" :rowTogglerIcon="columnProp(col,'expander') ? rowTogglerIcon(rowData): null"
:rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(value, col, index) : null" :rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(value, col, index) : null"
:editMode="editMode" :editing="editMode === 'row' && isRowEditing(rowData)" :editMode="editMode" :editing="editMode === 'row' && isRowEditing(rowData)"
@ -24,17 +24,17 @@
@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>
</tr> </tr>
<tr class="p-datatable-row-expansion" v-if="templates['expansion'] && expandedRows && isRowExpanded(rowData)" :key="getRowKey(rowData, index) + '_expansion'"> <tr class="p-datatable-row-expansion" v-if="templates['expansion'] && expandedRows && isRowExpanded(rowData)" :key="getRowKey(rowData, index) + '_expansion'" role="row">
<td :colspan="columnsLength"> <td :colspan="columnsLength">
<component :is="templates['expansion']" :data="rowData" :index="index" /> <component :is="templates['expansion']" :data="rowData" :index="index" />
</td> </td>
</tr> </tr>
<tr class="p-rowgroup-footer" v-if="templates['groupfooter'] && rowGroupMode === 'subheader' && shouldRenderRowGroupFooter(value, rowData, index)" :key="getRowKey(rowData, index) + '_subfooter'"> <tr class="p-rowgroup-footer" v-if="templates['groupfooter'] && rowGroupMode === 'subheader' && shouldRenderRowGroupFooter(value, rowData, index)" :key="getRowKey(rowData, index) + '_subfooter'" role="row">
<component :is="templates['groupfooter']" :data="rowData" :index="index" /> <component :is="templates['groupfooter']" :data="rowData" :index="index" />
</tr> </tr>
</template> </template>
</template> </template>
<tr v-else class="p-datatable-emptymessage"> <tr v-else class="p-datatable-emptymessage" role="row">
<td :colspan="columnsLength"> <td :colspan="columnsLength">
<component :is="templates.empty" v-if="templates.empty && !loading" /> <component :is="templates.empty" v-if="templates.empty && !loading" />
<component :is="templates.loading" v-if="templates.loading && loading" /> <component :is="templates.loading" v-if="templates.loading && loading" />
@ -44,7 +44,7 @@
</template> </template>
<script> <script>
import {ObjectUtils} from 'primevue/utils'; import {ObjectUtils,DomHandler} from 'primevue/utils';
import BodyCell from './BodyCell.vue'; import BodyCell from './BodyCell.vue';
export default { export default {
@ -61,6 +61,10 @@ export default {
type: null, type: null,
default: null default: null
}, },
frozenRow: {
type: Boolean,
default: false
},
empty: { empty: {
type: Boolean, type: Boolean,
default: false default: false
@ -150,6 +154,16 @@ export default {
default: null default: null
} }
}, },
mounted() {
if (this.frozenRow) {
this.updateStickyPosition();
}
},
updated() {
if (this.frozenRow) {
this.updateStickyPosition();
}
},
methods: { methods: {
columnProp(col, prop) { columnProp(col, prop) {
return col.props ? ((col.type.props[prop].type === Boolean && col.props[prop] === '') ? true : col.props[prop]) : null; return col.props ? ((col.type.props[prop].type === Boolean && col.props[prop] === '') ? true : col.props[prop]) : null;
@ -407,6 +421,9 @@ export default {
}, },
onRowEditCancel(event) { onRowEditCancel(event) {
this.$emit('row-edit-cancel', event); this.$emit('row-edit-cancel', event);
},
updateStickyPosition() {
this.$el.style.top = DomHandler.getOuterHeight(this.$el.previousElementSibling) + 'px';
} }
}, },
computed: { computed: {

View File

@ -1,25 +1,23 @@
<template> <template>
<tfoot class="p-datatable-tfoot" v-if="hasFooter"> <tfoot class="p-datatable-tfoot" v-if="hasFooter" role="rowgroup">
<tr v-if="!columnGroup"> <tr v-if="!columnGroup" role="row">
<td v-for="(col,i) of columns" :key="columnProp(col, 'columnKey')||columnProp(col, 'field')||i" :style="columnProp(col, 'footerStyle')" :class="columnProp(col, 'footerClass')" <template v-for="(col,i) of columns" :key="columnProp(col,'columnKey')||columnProp(col,'field')||i" >
:colspan="columnProp(col, 'colspan')" :rowspan="columnProp(col, 'rowspan')"> <DTFooterCell :column="col" />
<component :is="col.children.footer" :column="col" v-if="col.children && col.children.footer"/> </template>
{{columnProp(col, 'footer')}}
</td>
</tr> </tr>
<template v-else> <template v-else>
<tr v-for="(row,i) of columnGroup.children.default()" :key="i"> <tr v-for="(row,i) of columnGroup.children.default()" :key="i">
<td v-for="(col,i) of row.children.default()" :key="columnProp(col, 'columnKey')||columnProp(col, 'field')||i" :style="columnProp(col, 'footerStyle')" :class="columnProp(col, 'footerClass')" <template v-for="(col,j) of row.children.default()" :key="columnProp(col,'columnKey')||columnProp(col,'field')||j">
:colspan="columnProp(col, 'colspan')" :rowspan="columnProp(col, 'rowspan')"> <DTFooterCell :column="col" />
<component :is="col.children.footer" :column="col" v-if="col.children && col.children.footer"/> </template>
{{columnProp(col, 'footer')}}
</td>
</tr> </tr>
</template> </template>
</tfoot> </tfoot>
</template> </template>
<script> <script>
import FooterCell from './FooterCell';
export default { export default {
props: { props: {
columnGroup: { columnGroup: {
@ -54,6 +52,9 @@ export default {
return hasFooter; return hasFooter;
} }
},
components: {
'DTFooterCell': FooterCell
} }
} }
</script> </script>

View File

@ -485,4 +485,15 @@ export default class DomHandler {
this.hasClass(element.parentElement, 'p-checkbox') || this.hasClass(element.parentElement, 'p-radiobutton') this.hasClass(element.parentElement, 'p-checkbox') || this.hasClass(element.parentElement, 'p-radiobutton')
); );
} }
static applyStyle(element, style) {
if (typeof style === 'string') {
element.style.cssText = this.style;
}
else {
for (let prop in this.style) {
element.style[prop] = style[prop];
}
}
}
} }

View File

@ -10,7 +10,7 @@
<div class="content-section implementation"> <div class="content-section implementation">
<div class="card"> <div class="card">
<h5>Vertical</h5> <h5>Vertical</h5>
<DataTable :value="customers" :scrollable="true" scrollHeight="200px" :loading="loading"> <DataTable :value="customers" :scrollable="true" scrollHeight="400px" :loading="loading">
<Column field="name" header="Name"></Column> <Column field="name" header="Name"></Column>
<Column field="country.name" header="Country"></Column> <Column field="country.name" header="Country"></Column>
<Column field="representative.name" header="Representative"></Column> <Column field="representative.name" header="Representative"></Column>
@ -18,10 +18,10 @@
</DataTable> </DataTable>
</div> </div>
<div class="card"> <div class="card">
<h5>Flexible Scroll</h5> <h5>Flexible Scroll</h5>
<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. <p>Flex scroll feature makes the scrollable viewport section dynamic insteaf of a fixed value 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> 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" /> <Button label="Show" icon="pi pi-external-link" @click="openDialog" />
</div> </div>
@ -31,13 +31,13 @@
<Column field="name" header="Name"></Column> <Column field="name" header="Name"></Column>
<Column field="country.name" header="Country"></Column> <Column field="country.name" header="Country"></Column>
<Column field="representative.name" header="Representative"></Column> <Column field="representative.name" header="Representative"></Column>
<Column field="status" header="Company"></Column> <Column field="status" header="Status"></Column>
</DataTable> </DataTable>
<template #footer> <template #footer>
<Button label="Ok" icon="pi pi-check" @click="closeDialog" /> <Button label="Ok" icon="pi pi-check" @click="closeDialog" />
</template> </template>
</Dialog> </Dialog>
<!--
<div class="card"> <div class="card">
<h5>Virtual Scroll</h5> <h5>Virtual Scroll</h5>
<DataTable :value="virtualCustomers" :scrollable="true" scrollHeight="200px" :lazy="true" :rows="20" :loading="loading" <DataTable :value="virtualCustomers" :scrollable="true" scrollHeight="200px" :lazy="true" :rows="20" :loading="loading"
@ -63,25 +63,31 @@
</template> </template>
</Column> </Column>
</DataTable> </DataTable>
</div> </div>-->
<div class="card"> <div class="card">
<h5>Horizontal and Vertical</h5> <h5>Horizontal and Vertical with Footer</h5>
<DataTable :value="customers" :scrollable="true" scrollHeight="200px" style="width: 600px" :loading="loading"> <DataTable :value="customers" :scrollable="true" scrollHeight="400px" :loading="loading" scrollDirection="both">
<Column field="id" header="Id" headerStyle="width: 250px" columnKey="id"></Column> <Column field="id" header="Id" footer="Id" :style="{width:'250px'}"></Column>
<Column field="name" header="Name" headerStyle="width: 250px" columnKey="name"></Column> <Column field="name" header="Name" footer="Name" :style="{width:'250px'}"></Column>
<Column field="country.name" header="Country" headerStyle="width: 250px" columnKey="country"></Column> <Column field="country.name" header="Country" footer="Country" :style="{width:'250px'}"></Column>
<Column field="date" header="Date" headerStyle="width: 250px" columnKey="date"></Column> <Column field="date" header="Date" footer="Date" :style="{width:'250px'}"></Column>
<Column field="company" header="Company" headerStyle="width: 250px" columnKey="company"></Column> <Column field="balance" header="Balance" footer="Balance" :style="{width:'250px'}">
<Column field="status" header="Status" headerStyle="width: 250px" columnKey="status"></Column> <template #body="{data}">
<Column field="activity" header="Activity" headerStyle="width: 250px" columnKey="activity"></Column> {{formatCurrency(data.balance)}}
<Column field="representative.name" header="Representative" headerStyle="width: 250px" columnKey="representative"></Column> </template>
</Column>
<Column field="company" header="Company" footer="Company" :style="{width:'250px'}"></Column>
<Column field="status" header="Status" footer="Status" :style="{width:'250px'}"></Column>
<Column field="activity" header="Activity" footer="Activity" :style="{width:'250px'}"></Column>
<Column field="representative.name" header="Representative" footer="Representative" :style="{width:'250px'}"></Column>
</DataTable> </DataTable>
</div> </div>
<div class="card"> <div class="card">
<h5>Frozen Rows</h5> <h5>Frozen Rows</h5>
<DataTable :value="customers" :frozenValue="frozenValue" :scrollable="true" scrollHeight="200px" :loading="loading"> <DataTable :value="customers" :frozenValue="frozenValue" :scrollable="true" scrollHeight="400px" :loading="loading">
<Column field="name" header="Name"></Column> <Column field="name" header="Name"></Column>
<Column field="country.name" header="Country"></Column> <Column field="country.name" header="Country"></Column>
<Column field="representative.name" header="Representative"></Column> <Column field="representative.name" header="Representative"></Column>
@ -91,19 +97,25 @@
<div class="card"> <div class="card">
<h5>Frozen Columns</h5> <h5>Frozen Columns</h5>
<DataTable :value="customers" :scrollable="true" scrollHeight="200px" frozenWidth="300px" :loading="loading"> <DataTable :value="customers" :scrollable="true" scrollHeight="400px" :loading="loading" scrollDirection="both">
<Column field="name" header="Name" headerStyle="width: 300px" columnKey="name" :frozen="true"> <Column field="name" header="Name" :style="{width:'250px'}" frozen>
<template #body="slotProps"> <template #body="slotProps">
<span style="font-weight: 700">{{slotProps.data.name}}</span> <span style="font-weight: 700">{{slotProps.data.name}}</span>
</template> </template>
</Column> </Column>
<Column field="id" header="Id" headerStyle="width: 300px" columnKey="id"></Column> <Column field="id" header="Id" :style="{width:'250px'}"></Column>
<Column field="country.name" header="Country" headerStyle="width: 300px" columnKey="country"></Column> <Column field="name" header="Name" :style="{width:'250px'}"></Column>
<Column field="date" header="Date" headerStyle="width: 300px" columnKey="date"></Column> <Column field="country.name" header="Country" :style="{width:'250px'}"></Column>
<Column field="company" header="Country" headerStyle="width: 300px" columnKey="company"></Column> <Column field="date" header="Date" :style="{width:'250px'}"></Column>
<Column field="status" header="Status" headerStyle="width: 300px" columnKey="status"></Column> <Column field="balance" header="Balance" :style="{width:'250px'}">
<Column field="activity" header="Activity" headerStyle="width: 300px" columnKey="activity"></Column> <template #body="{data}">
<Column field="representative.name" header="Representative" headerStyle="width: 300px" columnKey="representative"></Column> {{formatCurrency(data.balance)}}
</template>
</Column>
<Column field="company" header="Company" :style="{width:'250px'}"></Column>
<Column field="status" header="Status" :style="{width:'250px'}"></Column>
<Column field="activity" header="Activity" :style="{width:'250px'}"></Column>
<Column field="representative.name" header="Representative" :style="{width:'250px'}"></Column>
</DataTable> </DataTable>
</div> </div>
</div> </div>
@ -128,7 +140,7 @@
&lt;div class="card"&gt; &lt;div class="card"&gt;
&lt;h5&gt;Flexible Scroll&lt;/h5&gt; &lt;h5&gt;Flexible Scroll&lt;/h5&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. &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; 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;Button label="Show" icon="pi pi-external-link" @click="openDialog" /&gt;
&lt;/div&gt; &lt;/div&gt;
@ -175,14 +187,14 @@
&lt;div class="card"&gt; &lt;div class="card"&gt;
&lt;h5&gt;Horizontal and Vertical&lt;/h5&gt; &lt;h5&gt;Horizontal and Vertical&lt;/h5&gt;
&lt;DataTable :value="customers" :scrollable="true" scrollHeight="200px" style="width: 600px" :loading="loading"&gt; &lt;DataTable :value="customers" :scrollable="true" scrollHeight="200px" style="width: 600px" :loading="loading"&gt;
&lt;Column field="id" header="Id" headerStyle="width: 250px" columnKey="id"&gt;&lt;/Column&gt; &lt;Column field="id" header="Id" :headerStyle="{width:'250px'}" columnKey="id"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name" headerStyle="width: 250px" columnKey="name"&gt;&lt;/Column&gt; &lt;Column field="name" header="Name" :headerStyle="{width:'250px'}" columnKey="name"&gt;&lt;/Column&gt;
&lt;Column field="country.name" header="Country" headerStyle="width: 250px" columnKey="country"&gt;&lt;/Column&gt; &lt;Column field="country.name" header="Country" :headerStyle="{width:'250px'}" columnKey="country"&gt;&lt;/Column&gt;
&lt;Column field="date" header="Date" headerStyle="width: 250px" columnKey="date"&gt;&lt;/Column&gt; &lt;Column field="date" header="Date" :headerStyle="{width:'250px'}" columnKey="date"&gt;&lt;/Column&gt;
&lt;Column field="company" header="Company" headerStyle="width: 250px" columnKey="company"&gt;&lt;/Column&gt; &lt;Column field="company" header="Company" :headerStyle="{width:'250px'}" columnKey="company"&gt;&lt;/Column&gt;
&lt;Column field="status" header="Status" headerStyle="width: 250px" columnKey="status"&gt;&lt;/Column&gt; &lt;Column field="status" header="Status" :headerStyle="{width:'250px'}" columnKey="status"&gt;&lt;/Column&gt;
&lt;Column field="activity" header="Activity" headerStyle="width: 250px" columnKey="activity"&gt;&lt;/Column&gt; &lt;Column field="activity" header="Activity" :headerStyle="{width:'250px'}" columnKey="activity"&gt;&lt;/Column&gt;
&lt;Column field="representative.name" header="Representative" headerStyle="width: 250px" columnKey="representative"&gt;&lt;/Column&gt; &lt;Column field="representative.name" header="Representative" :headerStyle="{width:'250px'}" columnKey="representative"&gt;&lt;/Column&gt;
&lt;/DataTable&gt; &lt;/DataTable&gt;
&lt;/div&gt; &lt;/div&gt;
@ -222,7 +234,7 @@ import CustomerService from '../../service/CustomerService';
export default { export default {
data() { data() {
return { return {
customers: null, customers: null,
virtualCustomers: null, virtualCustomers: null,
lazyTotalRecords: 0, lazyTotalRecords: 0,
frozenValue: null, frozenValue: null,
@ -230,9 +242,9 @@ export default {
dialogVisible: false dialogVisible: false
} }
}, },
customerService: null, customerService: null,
inmemoryData: null, inmemoryData: null,
created() { created() {
this.customerService = new CustomerService(); this.customerService = new CustomerService();
}, },
mounted() { mounted() {
@ -248,11 +260,11 @@ export default {
{ {
id: 1255, id: 1255,
name: "James McAdams", name: "James McAdams",
country: { country: {
name: "United States", name: "United States",
code: "us" code: "us"
}, },
company: "McAdams Consulting Ltd", company: "McAdams Consulting Ltd",
date: "2014-02-13", date: "2014-02-13",
status: "qualified", status: "qualified",
activity: 23, activity: 23,
@ -264,11 +276,11 @@ export default {
{ {
id: 5135, id: 5135,
name: "Geraldine Bisset", name: "Geraldine Bisset",
country: { country: {
name: "France", name: "France",
code: "fr" code: "fr"
}, },
company: "Bisset Group", company: "Bisset Group",
status: "proposal", status: "proposal",
date: "2019-05-05", date: "2019-05-05",
activity: 0, activity: 0,
@ -288,7 +300,7 @@ export default {
loadChunk(index, length) { loadChunk(index, length) {
let chunk = []; let chunk = [];
for (let i = 0; i &lt; length; i++) { for (let i = 0; i &lt; length; i++) {
chunk[i] = {...this.inmemoryData[i]}; chunk[i] = {...this.inmemoryData[i]};
} }
return chunk; return chunk;
@ -305,7 +317,7 @@ export default {
openDialog() { openDialog() {
this.dialogVisible = true; this.dialogVisible = true;
}, },
closeDialog() { closeDialog() {
this.dialogVisible = false; this.dialogVisible = false;
} }
} }
@ -325,7 +337,7 @@ import LiveEditor from '../liveeditor/LiveEditor';
export default { export default {
data() { data() {
return { return {
customers: null, customers: null,
virtualCustomers: null, virtualCustomers: null,
lazyTotalRecords: 0, lazyTotalRecords: 0,
frozenValue: null, frozenValue: null,
@ -333,7 +345,7 @@ export default {
dialogVisible: false, dialogVisible: false,
sources: { sources: {
'template': { 'template': {
content: `<template> content: `<template>
<div class="layout-content"> <div class="layout-content">
<div class="content-section implementation"> <div class="content-section implementation">
<div class="card"> <div class="card">
@ -349,7 +361,7 @@ export default {
<div class="card"> <div class="card">
<h5>Flexible Scroll</h5> <h5>Flexible Scroll</h5>
<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. <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> 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" /> <Button label="Show" icon="pi pi-external-link" @click="openDialog" />
</div> </div>
@ -396,14 +408,14 @@ export default {
<div class="card"> <div class="card">
<h5>Horizontal and Vertical</h5> <h5>Horizontal and Vertical</h5>
<DataTable :value="customers" :scrollable="true" scrollHeight="200px" style="width: 600px" :loading="loading"> <DataTable :value="customers" :scrollable="true" scrollHeight="200px" style="width: 600px" :loading="loading">
<Column field="id" header="Id" headerStyle="width: 250px" columnKey="id"></Column> <Column field="id" header="Id" :headerStyle="{width:'250px'}" columnKey="id"></Column>
<Column field="name" header="Name" headerStyle="width: 250px" columnKey="name"></Column> <Column field="name" header="Name" :headerStyle="{width:'250px'}" columnKey="name"></Column>
<Column field="country.name" header="Country" headerStyle="width: 250px" columnKey="country"></Column> <Column field="country.name" header="Country" :headerStyle="{width:'250px'}" columnKey="country"></Column>
<Column field="date" header="Date" headerStyle="width: 250px" columnKey="date"></Column> <Column field="date" header="Date" :headerStyle="{width:'250px'}" columnKey="date"></Column>
<Column field="company" header="Company" headerStyle="width: 250px" columnKey="company"></Column> <Column field="company" header="Company" :headerStyle="{width:'250px'}" columnKey="company"></Column>
<Column field="status" header="Status" headerStyle="width: 250px" columnKey="status"></Column> <Column field="status" header="Status" :headerStyle="{width:'250px'}" columnKey="status"></Column>
<Column field="activity" header="Activity" headerStyle="width: 250px" columnKey="activity"></Column> <Column field="activity" header="Activity" :headerStyle="{width:'250px'}" columnKey="activity"></Column>
<Column field="representative.name" header="Representative" headerStyle="width: 250px" columnKey="representative"></Column> <Column field="representative.name" header="Representative" :headerStyle="{width:'250px'}" columnKey="representative"></Column>
</DataTable> </DataTable>
</div> </div>
@ -444,7 +456,7 @@ import CustomerService from '../service/CustomerService';
export default { export default {
data() { data() {
return { return {
customers: null, customers: null,
virtualCustomers: null, virtualCustomers: null,
lazyTotalRecords: 0, lazyTotalRecords: 0,
frozenValue: null, frozenValue: null,
@ -452,9 +464,9 @@ export default {
dialogVisible: false dialogVisible: false
} }
}, },
customerService: null, customerService: null,
inmemoryData: null, inmemoryData: null,
created() { created() {
this.customerService = new CustomerService(); this.customerService = new CustomerService();
}, },
mounted() { mounted() {
@ -470,11 +482,11 @@ export default {
{ {
id: 1255, id: 1255,
name: "James McAdams", name: "James McAdams",
country: { country: {
name: "United States", name: "United States",
code: "us" code: "us"
}, },
company: "McAdams Consulting Ltd", company: "McAdams Consulting Ltd",
date: "2014-02-13", date: "2014-02-13",
status: "qualified", status: "qualified",
activity: 23, activity: 23,
@ -486,11 +498,11 @@ export default {
{ {
id: 5135, id: 5135,
name: "Geraldine Bisset", name: "Geraldine Bisset",
country: { country: {
name: "France", name: "France",
code: "fr" code: "fr"
}, },
company: "Bisset Group", company: "Bisset Group",
status: "proposal", status: "proposal",
date: "2019-05-05", date: "2019-05-05",
activity: 0, activity: 0,
@ -510,7 +522,7 @@ export default {
loadChunk(index, length) { loadChunk(index, length) {
let chunk = []; let chunk = [];
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
chunk[i] = {...this.inmemoryData[i]}; chunk[i] = {...this.inmemoryData[i]};
} }
return chunk; return chunk;
@ -527,7 +539,7 @@ export default {
openDialog() { openDialog() {
this.dialogVisible = true; this.dialogVisible = true;
}, },
closeDialog() { closeDialog() {
this.dialogVisible = false; this.dialogVisible = false;
} }
} }
@ -546,9 +558,9 @@ export default {
} }
} }
}, },
customerService: null, customerService: null,
inmemoryData: null, inmemoryData: null,
created() { created() {
this.customerService = new CustomerService(); this.customerService = new CustomerService();
}, },
mounted() { mounted() {
@ -564,11 +576,11 @@ export default {
{ {
id: 1255, id: 1255,
name: "James McAdams", name: "James McAdams",
country: { country: {
name: "United States", name: "United States",
code: "us" code: "us"
}, },
company: "McAdams Consulting Ltd", company: "McAdams Consulting Ltd",
date: "2014-02-13", date: "2014-02-13",
status: "qualified", status: "qualified",
activity: 23, activity: 23,
@ -580,11 +592,11 @@ export default {
{ {
id: 5135, id: 5135,
name: "Geraldine Bisset", name: "Geraldine Bisset",
country: { country: {
name: "France", name: "France",
code: "fr" code: "fr"
}, },
company: "Bisset Group", company: "Bisset Group",
status: "proposal", status: "proposal",
date: "2019-05-05", date: "2019-05-05",
activity: 0, activity: 0,
@ -604,7 +616,7 @@ export default {
loadChunk(index, length) { loadChunk(index, length) {
let chunk = []; let chunk = [];
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
chunk[i] = {...this.inmemoryData[i]}; chunk[i] = {...this.inmemoryData[i]};
} }
return chunk; return chunk;
@ -623,9 +635,12 @@ export default {
}, },
closeDialog() { closeDialog() {
this.dialogVisible = false; this.dialogVisible = false;
},
formatCurrency(value) {
return value.toLocaleString('en-US', {style: 'currency', currency: 'USD'});
} }
}, },
components: { components: {
LiveEditor LiveEditor
} }
} }