Fixed #1843 - Add virtualScroller feature to DataTable
parent
330a1119c3
commit
fa578b9673
|
@ -1,5 +1,6 @@
|
|||
import { VNode } from 'vue';
|
||||
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
|
||||
import { VirtualScrollerLoaderOptions } from '../virtualscroller';
|
||||
|
||||
type ColumnFieldType = string | ((item: any) => string) | undefined;
|
||||
|
||||
|
@ -22,6 +23,37 @@ export interface ColumnFilterMatchModeOptions {
|
|||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface ColumnLoadingOptions extends VirtualScrollerLoaderOptions {
|
||||
/**
|
||||
* Cell index
|
||||
*/
|
||||
cellIndex: number;
|
||||
/**
|
||||
* Whether the cell is first.
|
||||
*/
|
||||
cellFirst: boolean;
|
||||
/**
|
||||
* Whether the cell is last.
|
||||
*/
|
||||
cellLast: boolean;
|
||||
/**
|
||||
* Whether the cell is even.
|
||||
*/
|
||||
cellEven: boolean;
|
||||
/**
|
||||
* Whether the item is odd.
|
||||
*/
|
||||
cellOdd: boolean;
|
||||
/**
|
||||
* Column instance
|
||||
*/
|
||||
column: Column;
|
||||
/**
|
||||
* Column field
|
||||
*/
|
||||
field: string;
|
||||
}
|
||||
|
||||
export interface ColumnProps {
|
||||
/**
|
||||
* Identifier of a column if field property is not defined.
|
||||
|
@ -375,6 +407,37 @@ export interface ColumnSlots {
|
|||
*/
|
||||
filterCallback: () => void;
|
||||
}) => VNode[];
|
||||
/**
|
||||
* Custom loading template.
|
||||
* @param {Object} scope - loading slot's params.
|
||||
*/
|
||||
loading: (scope: {
|
||||
/**
|
||||
* Row data.
|
||||
*/
|
||||
data: any;
|
||||
/**
|
||||
* Column node.
|
||||
*/
|
||||
column: Column;
|
||||
/**
|
||||
* Column field.
|
||||
*/
|
||||
field: string;
|
||||
/**
|
||||
* Row index.
|
||||
*/
|
||||
index: number;
|
||||
/**
|
||||
* Whether the row is frozen.
|
||||
*/
|
||||
frozenRow: boolean;
|
||||
/**
|
||||
* Loading options.
|
||||
* @see ColumnLoadingOptions
|
||||
*/
|
||||
loadingOptions: ColumnLoadingOptions;
|
||||
}) => VNode[];
|
||||
}
|
||||
|
||||
export declare type ColumnEmits = {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<td :style="containerStyle" :class="containerClass" @click="onClick" @keydown="onKeyDown" role="cell">
|
||||
<td v-if="loading" :style="containerStyle" :class="containerClass">
|
||||
<component :is="column.children.loading" :data="rowData" :column="column" :field="field" :index="rowIndex" :frozenRow="frozenRow" :loadingOptions="loadingOptions" />
|
||||
</td>
|
||||
<td v-else :style="containerStyle" :class="containerClass" @click="onClick" @keydown="onKeyDown" role="cell">
|
||||
<span v-if="responsiveLayout === 'stack'" class="p-column-title">{{columnProp('header')}}</span>
|
||||
<component :is="column.children.body" :data="rowData" :column="column" :field="field" :index="rowIndex" :frozenRow="frozenRow" v-if="column.children && column.children.body && !d_editing" />
|
||||
<component :is="column.children.editor" :data="editingRowData" :column="column" :field="field" :index="rowIndex" :frozenRow="frozenRow" v-else-if="column.children && column.children.editor && d_editing" />
|
||||
|
@ -86,6 +89,10 @@ export default {
|
|||
responsiveLayout: {
|
||||
type: String,
|
||||
default: 'stack'
|
||||
},
|
||||
virtualScrollerContentProps: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
documentEditListener: null,
|
||||
|
@ -339,6 +346,9 @@ export default {
|
|||
this.styleObject.left = left + 'px';
|
||||
}
|
||||
}
|
||||
},
|
||||
getVirtualScrollerProp(option) {
|
||||
return this.virtualScrollerContentProps ? this.virtualScrollerContentProps[option] : null;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -361,6 +371,21 @@ export default {
|
|||
let columnStyle = this.columnProp('style');
|
||||
|
||||
return this.columnProp('frozen') ? [columnStyle, bodyStyle, this.styleObject]: [columnStyle, bodyStyle];
|
||||
},
|
||||
loading() {
|
||||
return this.getVirtualScrollerProp('loading');
|
||||
},
|
||||
loadingOptions() {
|
||||
const getLoaderOptions = this.getVirtualScrollerProp('getLoaderOptions');
|
||||
return getLoaderOptions && getLoaderOptions(this.rowIndex, {
|
||||
cellIndex: this.index,
|
||||
cellFirst: this.index === 0,
|
||||
cellLast: this.index === (this.getVirtualScrollerProp('columns').length - 1),
|
||||
cellEven: this.index % 2 === 0,
|
||||
cellOdd: this.index % 2 !== 0,
|
||||
column: this.column,
|
||||
field: this.field
|
||||
});
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -16,36 +16,41 @@
|
|||
<slot name="paginatorend"></slot>
|
||||
</template>
|
||||
</DTPaginator>
|
||||
<div class="p-datatable-wrapper" :style="{maxHeight: scrollHeight}">
|
||||
<table ref="table" role="table" :class="[tableClass, 'p-datatable-table']" :style="tableStyle">
|
||||
<DTTableHeader :columnGroup="headerColumnGroup" :columns="columns" :rowGroupMode="rowGroupMode"
|
||||
:groupRowsBy="groupRowsBy" :groupRowSortField="groupRowSortField" :resizableColumns="resizableColumns" :allRowsSelected="allRowsSelected" :empty="empty"
|
||||
: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-dragstart="onColumnHeaderDragStart($event)" @column-dragover="onColumnHeaderDragOver($event)" @column-dragleave="onColumnHeaderDragLeave($event)" @column-drop="onColumnHeaderDrop($event)"
|
||||
@column-resizestart="onColumnResizeStart($event)" @checkbox-change="toggleRowsWithCheckbox($event)" />
|
||||
<DTTableBody v-if="frozenValue" :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" :rowStyle="rowStyle" :editMode="editMode" :compareSelectionBy="compareSelectionBy" :scrollable="scrollable"
|
||||
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
|
||||
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$slots" :loading="loading" :responsiveLayout="responsiveLayout"
|
||||
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-dblclick="onRowDblClick($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)"
|
||||
:editingMeta="d_editingMeta" @editing-meta-change="onEditingMetaChange" />
|
||||
<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" :rowStyle="rowStyle" :editMode="editMode" :compareSelectionBy="compareSelectionBy" :scrollable="scrollable"
|
||||
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
|
||||
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$slots" :loading="loading" :responsiveLayout="responsiveLayout"
|
||||
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-dblclick="onRowDblClick($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)"
|
||||
:editingMeta="d_editingMeta" @editing-meta-change="onEditingMetaChange" />
|
||||
<DTTableFooter :columnGroup="footerColumnGroup" :columns="columns" />
|
||||
</table>
|
||||
<div class="p-datatable-wrapper" :style="{ maxHeight: virtualScrollerDisabled ? scrollHeight : '' }">
|
||||
<DTVirtualScroller v-bind="virtualScrollerOptions" :items="processedData" :columns="columns" :style="{ height: scrollHeight }" :disabled="virtualScrollerDisabled" loaderDisabled :showSpacer="false">
|
||||
<template #content="slotProps">
|
||||
<table ref="table" role="table" :class="[tableClass, 'p-datatable-table']" :style="[tableStyle, slotProps.spacerStyle]">
|
||||
<DTTableHeader :columnGroup="headerColumnGroup" :columns="slotProps.columns" :rowGroupMode="rowGroupMode"
|
||||
:groupRowsBy="groupRowsBy" :groupRowSortField="groupRowSortField" :resizableColumns="resizableColumns" :allRowsSelected="allRowsSelected" :empty="empty"
|
||||
: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-dragstart="onColumnHeaderDragStart($event)" @column-dragover="onColumnHeaderDragOver($event)" @column-dragleave="onColumnHeaderDragLeave($event)" @column-drop="onColumnHeaderDrop($event)"
|
||||
@column-resizestart="onColumnResizeStart($event)" @checkbox-change="toggleRowsWithCheckbox($event)" />
|
||||
<DTTableBody v-if="frozenValue" :value="frozenValue" :frozenRow="true" class="p-datatable-frozen-tbody" :columns="slotProps.columns" :dataKey="dataKey" :selection="selection" :selectionKeys="d_selectionKeys" :selectionMode="selectionMode" :contextMenu="contextMenu" :contextMenuSelection="contextMenuSelection"
|
||||
:rowGroupMode="rowGroupMode" :groupRowsBy="groupRowsBy" :expandableRowGroups="expandableRowGroups" :rowClass="rowClass" :rowStyle="rowStyle" :editMode="editMode" :compareSelectionBy="compareSelectionBy" :scrollable="scrollable"
|
||||
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
|
||||
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$slots" :loading="loading" :responsiveLayout="responsiveLayout"
|
||||
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-dblclick="onRowDblClick($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)"
|
||||
:editingMeta="d_editingMeta" @editing-meta-change="onEditingMetaChange" :isVirtualScrollerDisabled="true" />
|
||||
<DTTableBody :value="dataToRender(slotProps.rows)" :class="slotProps.styleClass" :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" :rowStyle="rowStyle" :editMode="editMode" :compareSelectionBy="compareSelectionBy" :scrollable="scrollable"
|
||||
:expandedRowIcon="expandedRowIcon" :collapsedRowIcon="collapsedRowIcon" :expandedRows="expandedRows" :expandedRowKeys="d_expandedRowKeys" :expandedRowGroups="expandedRowGroups"
|
||||
:editingRows="editingRows" :editingRowKeys="d_editingRowKeys" :templates="$slots" :loading="loading" :responsiveLayout="responsiveLayout"
|
||||
@rowgroup-toggle="toggleRowGroup" @row-click="onRowClick($event)" @row-dblclick="onRowDblClick($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)"
|
||||
:editingMeta="d_editingMeta" @editing-meta-change="onEditingMetaChange"
|
||||
:virtualScrollerContentProps="slotProps" :isVirtualScrollerDisabled="virtualScrollerDisabled" />
|
||||
<DTTableFooter :columnGroup="footerColumnGroup" :columns="slotProps.columns" />
|
||||
</table>
|
||||
</template>
|
||||
</DTVirtualScroller>
|
||||
</div>
|
||||
<DTPaginator v-if="paginatorBottom" :rows="d_rows" :first="lazy ? 0 : d_first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
||||
:currentPageReportTemplate="currentPageReportTemplate" class="p-paginator-bottom" @page="onPage($event)" :alwaysShow="alwaysShowPaginator">
|
||||
|
@ -69,6 +74,7 @@
|
|||
import {ObjectUtils,DomHandler,UniqueComponentId} from 'primevue/utils';
|
||||
import {FilterMatchMode,FilterOperator,FilterService} from 'primevue/api';
|
||||
import Paginator from 'primevue/paginator';
|
||||
import VirtualScroller from 'primevue/virtualscroller';
|
||||
import TableHeader from './TableHeader.vue';
|
||||
import TableBody from './TableBody.vue';
|
||||
import TableFooter from './TableFooter.vue';
|
||||
|
@ -297,6 +303,10 @@ export default {
|
|||
type: String,
|
||||
default: "vertical"
|
||||
},
|
||||
virtualScrollerOptions: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
scrollHeight: {
|
||||
type: String,
|
||||
default: null
|
||||
|
@ -1766,6 +1776,16 @@ export default {
|
|||
}
|
||||
return results;
|
||||
},
|
||||
dataToRender(data) {
|
||||
const _data = data || this.processedData;
|
||||
|
||||
if (_data && this.paginator) {
|
||||
const first = this.lazy ? 0 : this.d_first;
|
||||
return _data.slice(first, first + this.d_rows);
|
||||
}
|
||||
|
||||
return _data;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
containerClass() {
|
||||
|
@ -1859,17 +1879,6 @@ export default {
|
|||
|
||||
return data;
|
||||
},
|
||||
dataToRender() {
|
||||
const data = this.processedData;
|
||||
|
||||
if (data && this.paginator) {
|
||||
const first = this.lazy ? 0 : this.d_first;
|
||||
return data.slice(first, first + this.d_rows);
|
||||
}
|
||||
else {
|
||||
return data;
|
||||
}
|
||||
},
|
||||
totalRecordsLength() {
|
||||
if (this.lazy) {
|
||||
return this.totalRecords;
|
||||
|
@ -1905,6 +1914,9 @@ export default {
|
|||
},
|
||||
groupRowSortField() {
|
||||
return this.sortMode === 'single' ? this.sortField : (this.d_groupRowsSortMeta ? this.d_groupRowsSortMeta.field : null);
|
||||
},
|
||||
virtualScrollerDisabled() {
|
||||
return ObjectUtils.isEmpty(this.virtualScrollerOptions) || !this.scrollable;
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
@ -1912,6 +1924,7 @@ export default {
|
|||
'DTTableHeader': TableHeader,
|
||||
'DTTableBody': TableBody,
|
||||
'DTTableFooter': TableFooter,
|
||||
'DTVirtualScroller': VirtualScroller
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -2205,4 +2218,13 @@ export default {
|
|||
.p-datatable .p-datatable-tbody > tr > td > .p-column-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* VirtualScroller */
|
||||
.p-datatable .p-virtualscroller-loading {
|
||||
transform: none !important;
|
||||
min-height: 0;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
<template>
|
||||
<tbody class="p-datatable-tbody" role="rowgroup">
|
||||
<tbody :ref="bodyRef" class="p-datatable-tbody" role="rowgroup" :style="bodyStyle">
|
||||
<template v-if="!empty">
|
||||
<template v-for="(rowData, index) of value" :key="getRowKey(rowData, index) + '_subheader'">
|
||||
<tr class="p-rowgroup-header" :style="rowGroupHeaderStyle" v-if="templates['groupheader'] && rowGroupMode === 'subheader' && shouldRenderRowGroupHeader(value, rowData, index)" role="row">
|
||||
<template v-for="(rowData, index) of value" :key="getRowKey(rowData, getRowIndex(index)) + '_subheader'">
|
||||
<tr class="p-rowgroup-header" :style="rowGroupHeaderStyle" v-if="templates['groupheader'] && rowGroupMode === 'subheader' && shouldRenderRowGroupHeader(value, rowData, getRowIndex(index))" role="row">
|
||||
<td :colspan="columnsLength - 1">
|
||||
<button class="p-row-toggler p-link" @click="onRowGroupToggle($event, rowData)" v-if="expandableRowGroups" type="button">
|
||||
<span :class="rowGroupTogglerIcon(rowData)"></span>
|
||||
</button>
|
||||
<component :is="templates['groupheader']" :data="rowData" :index="index" />
|
||||
<component :is="templates['groupheader']" :data="rowData" :index="getRowIndex(index)" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr :class="getRowClass(rowData)" :style="rowStyle" :key="getRowKey(rowData, index)"
|
||||
<tr :class="getRowClass(rowData)" :style="rowStyle" :key="getRowKey(rowData, getRowIndex(index))"
|
||||
v-if="expandableRowGroups ? isRowGroupExpanded(rowData): true"
|
||||
@click="onRowClick($event, rowData, index)" @dblclick="onRowDblClick($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)" role="row">
|
||||
@click="onRowClick($event, rowData, getRowIndex(index))" @dblclick="onRowDblClick($event, rowData, getRowIndex(index))" @contextmenu="onRowRightClick($event, rowData, getRowIndex(index))" @touchend="onRowTouchEnd($event)" @keydown="onRowKeyDown($event, rowData, getRowIndex(index))" :tabindex="selectionMode || contextMenu ? '0' : null"
|
||||
@mousedown="onRowMouseDown($event)" @dragstart="onRowDragStart($event, getRowIndex(index))" @dragover="onRowDragOver($event, getRowIndex(index))" @dragleave="onRowDragLeave($event)" @dragend="onRowDragEnd($event)" @drop="onRowDrop($event)" role="row">
|
||||
<template v-for="(col,i) of columns" :key="columnProp(col,'columnKey')||columnProp(col,'field')||i">
|
||||
<DTBodyCell v-if="shouldRenderBodyCell(value, col, index)" :rowData="rowData" :column="col" :rowIndex="index" :index="i" :selected="isSelected(rowData)"
|
||||
<DTBodyCell v-if="shouldRenderBodyCell(value, col, getRowIndex(index))" :rowData="rowData" :column="col" :rowIndex="getRowIndex(index)" :index="i" :selected="isSelected(rowData)"
|
||||
:rowTogglerIcon="columnProp(col,'expander') ? rowTogglerIcon(rowData): null" :frozenRow="frozenRow"
|
||||
:rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(value, col, index) : null"
|
||||
:rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(value, col, getRowIndex(index)) : null"
|
||||
:editMode="editMode" :editing="editMode === 'row' && isRowEditing(rowData)" :responsiveLayout="responsiveLayout"
|
||||
@radio-change="onRadioChange($event)" @checkbox-change="onCheckboxChange($event)" @row-toggle="onRowToggle($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)"
|
||||
:editingMeta="editingMeta" @editing-meta-change="onEditingMetaChange"/>
|
||||
:editingMeta="editingMeta" @editing-meta-change="onEditingMetaChange" :virtualScrollerContentProps="virtualScrollerContentProps"/>
|
||||
</template>
|
||||
</tr>
|
||||
<tr class="p-datatable-row-expansion" v-if="templates['expansion'] && expandedRows && isRowExpanded(rowData)" :key="getRowKey(rowData, index) + '_expansion'" role="row">
|
||||
<tr class="p-datatable-row-expansion" v-if="templates['expansion'] && expandedRows && isRowExpanded(rowData)" :key="getRowKey(rowData, getRowIndex(index)) + '_expansion'" role="row">
|
||||
<td :colspan="columnsLength">
|
||||
<component :is="templates['expansion']" :data="rowData" :index="index" />
|
||||
<component :is="templates['expansion']" :data="rowData" :index="getRowIndex(index)" />
|
||||
</td>
|
||||
</tr>
|
||||
<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" />
|
||||
<tr class="p-rowgroup-footer" v-if="templates['groupfooter'] && rowGroupMode === 'subheader' && shouldRenderRowGroupFooter(value, rowData, getRowIndex(index))" :key="getRowKey(rowData, getRowIndex(index)) + '_subfooter'" role="row">
|
||||
<component :is="templates['groupfooter']" :data="rowData" :index="getRowIndex(index)" />
|
||||
</tr>
|
||||
</template>
|
||||
</template>
|
||||
|
@ -170,6 +170,21 @@ export default {
|
|||
responsiveLayout: {
|
||||
type: String,
|
||||
default: 'stack'
|
||||
},
|
||||
virtualScrollerContentProps: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
isVirtualScrollerDisabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
virtualScrollerContentProps(newValue, oldValue) {
|
||||
if (!this.isVirtualScrollerDisabled && this.getVirtualScrollerProp('vertical') && this.getVirtualScrollerProp('itemSize', oldValue) !== this.getVirtualScrollerProp('itemSize', newValue)) {
|
||||
this.updateVirtualScrollerPosition();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -180,6 +195,10 @@ export default {
|
|||
if (this.scrollable && this.rowGroupMode === 'subheader') {
|
||||
this.updateFrozenRowGroupHeaderStickyPosition();
|
||||
}
|
||||
|
||||
if (!this.isVirtualScrollerDisabled && this.getVirtualScrollerProp('vertical')) {
|
||||
this.updateVirtualScrollerPosition();
|
||||
}
|
||||
},
|
||||
updated() {
|
||||
if (this.frozenRow) {
|
||||
|
@ -213,6 +232,10 @@ export default {
|
|||
getRowKey(rowData, index) {
|
||||
return this.dataKey ? ObjectUtils.resolveFieldData(rowData, this.dataKey): index;
|
||||
},
|
||||
getRowIndex(index) {
|
||||
const getItemOptions = this.getVirtualScrollerProp('getItemOptions');
|
||||
return getItemOptions ? getItemOptions(index).index : index;
|
||||
},
|
||||
getRowClass(rowData) {
|
||||
let rowStyleClass = [];
|
||||
if (this.selectionMode) {
|
||||
|
@ -465,6 +488,19 @@ export default {
|
|||
updateFrozenRowGroupHeaderStickyPosition() {
|
||||
let tableHeaderHeight = DomHandler.getOuterHeight(this.$el.previousElementSibling);
|
||||
this.rowGroupHeaderStyleObject.top = tableHeaderHeight + 'px'
|
||||
},
|
||||
updateVirtualScrollerPosition() {
|
||||
const tableHeaderHeight = DomHandler.getOuterHeight(this.$el.previousElementSibling);
|
||||
this.$el.style.top = (this.$el.style.top || 0) + tableHeaderHeight + 'px';
|
||||
},
|
||||
getVirtualScrollerProp(option, options) {
|
||||
options = options || this.virtualScrollerContentProps;
|
||||
return options ? options[option] : null;
|
||||
},
|
||||
bodyRef(el) {
|
||||
// For VirtualScroller
|
||||
const contentRef = this.getVirtualScrollerProp('contentRef');
|
||||
contentRef && contentRef(el);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -477,6 +513,9 @@ export default {
|
|||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
bodyStyle() {
|
||||
return this.getVirtualScrollerProp('contentStyle');
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
Loading…
Reference in New Issue