2019-06-27 21:17:21 +00:00
|
|
|
<template>
|
2019-07-03 10:07:57 +00:00
|
|
|
<div :class="containerClass">
|
2019-06-27 21:17:21 +00:00
|
|
|
<slot></slot>
|
2019-07-02 14:29:30 +00:00
|
|
|
<div class="p-datatable-loading" v-if="loading">
|
|
|
|
<div class="p-datatable-loading-overlay p-component-overlay"></div>
|
|
|
|
<div class="p-datatable-loading-content">
|
|
|
|
<i :class="loadingIconClass"></i>
|
|
|
|
</div>
|
|
|
|
</div>
|
2019-06-27 21:17:21 +00:00
|
|
|
<div class="p-datatable-wrapper">
|
2019-06-29 12:27:35 +00:00
|
|
|
<div class="p-datatable-header" v-if="$scopedSlots.header">
|
2019-06-28 14:40:32 +00:00
|
|
|
<slot name="header"></slot>
|
|
|
|
</div>
|
2019-07-28 14:11:23 +00:00
|
|
|
<DTPaginator v-if="paginatorTop" :rows="d_rows" :first="d_first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
2019-06-29 12:27:35 +00:00
|
|
|
:currentPageReportTemplate="currentPageReportTemplate" class="p-paginator-top" @page="onPage($event)" :alwaysShow="alwaysShowPaginator">
|
2019-06-29 11:29:19 +00:00
|
|
|
<template #left v-if="$scopedSlots.paginatorLeft">
|
|
|
|
<slot name="paginatorLeft"></slot>
|
|
|
|
</template>
|
|
|
|
<template #right v-if="$scopedSlots.paginatorRight">
|
|
|
|
<slot name="paginatorRight"></slot>
|
|
|
|
</template>
|
|
|
|
</DTPaginator>
|
2019-06-27 21:17:21 +00:00
|
|
|
<table>
|
|
|
|
<thead class="p-datatable-thead">
|
|
|
|
<tr>
|
2019-07-01 13:50:55 +00:00
|
|
|
<th v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.headerStyle" :class="getColumnHeaderClass(col)" @click="onColumnHeaderClick($event, col)">
|
2019-07-02 10:46:06 +00:00
|
|
|
<ColumnSlot :column="col" type="header" v-if="col.$scopedSlots.header" />
|
2019-06-27 21:17:21 +00:00
|
|
|
<span class="p-column-title" v-if="col.header">{{col.header}}</span>
|
2019-07-01 13:50:55 +00:00
|
|
|
<span v-if="col.sortable" :class="getSortableColumnIcon(col)"></span>
|
2019-07-02 12:57:03 +00:00
|
|
|
<ColumnSlot :column="col" type="filter" v-if="col.$scopedSlots.filter" />
|
2019-07-09 12:41:15 +00:00
|
|
|
<DTHeaderCheckbox :checked="allRowsSelected" @change="toggleRowsWithCheckbox" :disabled="empty" v-if="col.selectionMode ==='multiple'" />
|
2019-06-27 21:17:21 +00:00
|
|
|
</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
2019-07-02 10:46:06 +00:00
|
|
|
<tfoot class="p-datatable-tfoot" v-if="hasFooter">
|
|
|
|
<tr>
|
|
|
|
<td v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.footerStyle" :class="col.footerClass">
|
|
|
|
<ColumnSlot :column="col" type="footer" v-if="col.$scopedSlots.footer" />
|
|
|
|
{{col.footer}}
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
</tfoot>
|
2019-06-27 21:17:21 +00:00
|
|
|
<tbody class="p-datatable-tbody">
|
2019-06-29 11:47:14 +00:00
|
|
|
<template v-if="!empty">
|
2019-07-03 10:07:57 +00:00
|
|
|
<tr :class="getRowClass(rowData)" v-for="(rowData, index) of dataToRender" :key="getRowKey(rowData, index)"
|
2019-07-09 09:44:46 +00:00
|
|
|
@click="onRowClick($event, rowData, index)" @touchend="onRowTouchEnd($event)" @keydown="onRowKeyDown($event, rowData, index)" :tabindex="selectionMode ? '0' : null">
|
2019-06-29 11:47:14 +00:00
|
|
|
<td v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.bodyStyle" :class="col.bodyClass">
|
|
|
|
<ColumnSlot :data="rowData" :column="col" type="body" v-if="col.$scopedSlots.body" />
|
2019-07-09 11:36:24 +00:00
|
|
|
<template v-else-if="col.selectionMode">
|
2019-07-09 12:41:15 +00:00
|
|
|
<DTRadioButton :value="rowData" :checked="isSelected(rowData)" @change="toggleRowWithRadio" v-if="col.selectionMode === 'single'" />
|
|
|
|
<DTCheckbox :value="rowData" :checked="isSelected(rowData)" @change="toggleRowWithCheckbox" v-else-if="col.selectionMode ==='multiple'" />
|
2019-07-09 11:36:24 +00:00
|
|
|
</template>
|
2019-06-29 11:47:14 +00:00
|
|
|
<template v-else>{{resolveFieldData(rowData, col.field)}}</template>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
</template>
|
|
|
|
<tr v-else class="p-datatable-emptymessage">
|
|
|
|
<td :colspan="columns.length">
|
|
|
|
<slot name="empty"></slot>
|
2019-06-27 21:17:21 +00:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
2019-07-28 14:11:23 +00:00
|
|
|
<DTPaginator v-if="paginatorBottom" :rows="d_rows" :first="d_first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
2019-06-29 12:27:35 +00:00
|
|
|
:currentPageReportTemplate="currentPageReportTemplate" class="p-paginator-bottom" @page="onPage($event)" :alwaysShow="alwaysShowPaginator">
|
2019-06-29 11:29:19 +00:00
|
|
|
<template #left v-if="$scopedSlots.paginatorLeft">
|
|
|
|
<slot name="paginatorLeft"></slot>
|
|
|
|
</template>
|
|
|
|
<template #right v-if="$scopedSlots.paginatorRight">
|
|
|
|
<slot name="paginatorRight"></slot>
|
|
|
|
</template>
|
|
|
|
</DTPaginator>
|
2019-06-29 12:27:35 +00:00
|
|
|
<div class="p-datatable-footer" v-if="$scopedSlots.footer">
|
2019-06-29 11:29:19 +00:00
|
|
|
<slot name="footer"></slot>
|
|
|
|
</div>
|
2019-06-27 21:17:21 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import ObjectUtils from '../utils/ObjectUtils';
|
2019-07-02 12:57:03 +00:00
|
|
|
import FilterUtils from '../utils/FilterUtils';
|
2019-07-01 13:50:55 +00:00
|
|
|
import DomHandler from '../utils/DomHandler';
|
2019-06-29 11:29:19 +00:00
|
|
|
import Paginator from '../paginator/Paginator';
|
2019-07-09 11:36:24 +00:00
|
|
|
import RowRadioButton from './RowRadioButton';
|
2019-07-09 12:41:15 +00:00
|
|
|
import RowCheckbox from './RowCheckbox.vue';
|
|
|
|
import HeaderCheckbox from './HeaderCheckbox.vue';
|
2019-06-27 21:17:21 +00:00
|
|
|
|
2019-06-28 14:40:32 +00:00
|
|
|
const ColumnSlot = {
|
|
|
|
functional: true,
|
|
|
|
props: {
|
|
|
|
column: {
|
|
|
|
type: null,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
data: {
|
|
|
|
type: null,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
type: {
|
|
|
|
type: String,
|
|
|
|
default: null
|
|
|
|
}
|
|
|
|
},
|
|
|
|
render(createElement, context) {
|
|
|
|
const content = context.props.column.$scopedSlots[context.props.type]({
|
|
|
|
'data': context.props.data,
|
|
|
|
'column': context.props.column
|
|
|
|
});
|
|
|
|
return [content];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-06-27 21:17:21 +00:00
|
|
|
export default {
|
|
|
|
props: {
|
|
|
|
value: {
|
|
|
|
type: Array,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
dataKey: {
|
|
|
|
type: String,
|
|
|
|
default: null
|
2019-06-29 11:29:19 +00:00
|
|
|
},
|
|
|
|
rows: {
|
|
|
|
type: Number,
|
|
|
|
default: 0
|
|
|
|
},
|
|
|
|
first: {
|
|
|
|
type: Number,
|
|
|
|
default: 0
|
|
|
|
},
|
|
|
|
totalRecords: {
|
|
|
|
type: Number,
|
|
|
|
default: 0
|
|
|
|
},
|
|
|
|
paginator: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
},
|
|
|
|
paginatorPosition: {
|
|
|
|
type: String,
|
|
|
|
default: 'bottom'
|
|
|
|
},
|
|
|
|
alwaysShowPaginator: {
|
|
|
|
type: Boolean,
|
|
|
|
default: true
|
|
|
|
},
|
|
|
|
paginatorTemplate: {
|
|
|
|
type: String,
|
|
|
|
default: 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown'
|
|
|
|
},
|
|
|
|
pageLinkSize: {
|
|
|
|
type: Number,
|
|
|
|
default: 5
|
|
|
|
},
|
|
|
|
rowsPerPageOptions: {
|
|
|
|
type: Array,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
currentPageReportTemplate: {
|
|
|
|
type: String,
|
|
|
|
default: '({currentPage} of {totalPages})'
|
|
|
|
},
|
|
|
|
lazy: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
2019-06-29 11:34:29 +00:00
|
|
|
},
|
|
|
|
loading: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
},
|
|
|
|
loadingIcon: {
|
|
|
|
type: String,
|
|
|
|
default: 'pi pi-spinner'
|
2019-07-01 13:50:55 +00:00
|
|
|
},
|
|
|
|
sortField: {
|
|
|
|
type: String,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
sortOrder: {
|
|
|
|
type: Number,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
defaultSortOrder: {
|
|
|
|
type: Number,
|
|
|
|
default: 1
|
2019-07-02 10:15:50 +00:00
|
|
|
},
|
|
|
|
multiSortMeta: {
|
|
|
|
type: Array,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
sortMode: {
|
|
|
|
type: String,
|
|
|
|
default: 'single'
|
2019-07-02 12:57:03 +00:00
|
|
|
},
|
|
|
|
filters: {
|
|
|
|
type: Object,
|
|
|
|
default: null
|
2019-07-03 10:07:57 +00:00
|
|
|
},
|
|
|
|
selection: {
|
|
|
|
type: [Array,Object],
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
selectionMode: {
|
|
|
|
type: String,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
compareSelectionBy: {
|
|
|
|
type: String,
|
|
|
|
default: 'deepEquals'
|
|
|
|
},
|
|
|
|
metaKeySelection: {
|
|
|
|
type: Boolean,
|
|
|
|
default: true
|
|
|
|
},
|
|
|
|
rowHover: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
2019-07-09 13:21:42 +00:00
|
|
|
},
|
|
|
|
csvSeparator: {
|
|
|
|
type: String,
|
|
|
|
default: ','
|
|
|
|
},
|
|
|
|
exportFilename: {
|
|
|
|
type: String,
|
|
|
|
default: 'download'
|
2019-07-10 14:20:12 +00:00
|
|
|
},
|
|
|
|
autoLayout: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
2019-06-27 21:17:21 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
2019-07-02 09:02:55 +00:00
|
|
|
allChildren: null,
|
2019-06-29 11:29:19 +00:00
|
|
|
d_first: this.first,
|
2019-07-01 13:50:55 +00:00
|
|
|
d_rows: this.rows,
|
|
|
|
d_sortField: this.sortField,
|
2019-07-02 10:15:50 +00:00
|
|
|
d_sortOrder: this.sortOrder,
|
2019-07-03 10:07:57 +00:00
|
|
|
d_multiSortMeta: this.multiSortMeta ? [...this.multiSortMeta] : [],
|
|
|
|
d_selectionKeys: null
|
2019-06-27 21:17:21 +00:00
|
|
|
};
|
|
|
|
},
|
2019-07-03 10:07:57 +00:00
|
|
|
rowTouched: false,
|
|
|
|
anchorRowIndex: null,
|
|
|
|
rangeRowIndex: null,
|
2019-06-29 11:29:19 +00:00
|
|
|
watch: {
|
|
|
|
first(newValue) {
|
|
|
|
this.d_first = newValue;
|
|
|
|
},
|
|
|
|
rows(newValue) {
|
|
|
|
this.d_rows = newValue;
|
2019-07-01 13:50:55 +00:00
|
|
|
},
|
|
|
|
sortField(newValue) {
|
|
|
|
this.d_sortField = newValue;
|
|
|
|
},
|
|
|
|
sortOrder(newValue) {
|
|
|
|
this.d_sortOrder = newValue;
|
2019-07-02 10:15:50 +00:00
|
|
|
},
|
|
|
|
multiSortMeta(newValue) {
|
|
|
|
this.d_multiSortMeta = newValue;
|
2019-07-03 10:07:57 +00:00
|
|
|
},
|
|
|
|
selection(newValue) {
|
|
|
|
if (this.dataKey) {
|
|
|
|
this.updateSelectionKeys(newValue);
|
|
|
|
}
|
2019-06-29 11:29:19 +00:00
|
|
|
}
|
|
|
|
},
|
2019-06-27 21:17:21 +00:00
|
|
|
mounted() {
|
2019-07-02 09:02:55 +00:00
|
|
|
this.allChildren = this.$children;
|
2019-06-27 21:17:21 +00:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
resolveFieldData(rowData, field) {
|
|
|
|
return ObjectUtils.resolveFieldData(rowData, field);
|
2019-06-29 11:29:19 +00:00
|
|
|
},
|
|
|
|
onPage(event) {
|
|
|
|
this.d_first = event.first;
|
|
|
|
this.d_rows = event.rows;
|
|
|
|
|
|
|
|
this.$emit('update:first', this.d_first);
|
|
|
|
this.$emit('update:rows', this.d_rows);
|
|
|
|
this.$emit('page', event);
|
2019-07-01 13:50:55 +00:00
|
|
|
},
|
2019-07-02 10:15:50 +00:00
|
|
|
onColumnHeaderClick(event, column) {
|
2019-07-01 13:50:55 +00:00
|
|
|
if (column.sortable) {
|
2019-07-28 14:11:23 +00:00
|
|
|
this.resetPage();
|
2019-07-02 10:15:50 +00:00
|
|
|
const targetNode = event.target;
|
|
|
|
const columnField = column.field || column.sortField;
|
2019-07-01 13:50:55 +00:00
|
|
|
|
2019-07-02 10:15:50 +00:00
|
|
|
if (DomHandler.hasClass(targetNode, 'p-sortable-column') || DomHandler.hasClass(targetNode, 'p-column-title')
|
|
|
|
|| DomHandler.hasClass(targetNode, 'p-sortable-column-icon') || DomHandler.hasClass(targetNode.parentElement, 'p-sortable-column-icon')) {
|
|
|
|
|
|
|
|
DomHandler.clearSelection();
|
2019-07-01 13:50:55 +00:00
|
|
|
|
|
|
|
this.d_sortOrder = (this.d_sortField === columnField) ? this.d_sortOrder * -1 : this.defaultSortOrder;
|
|
|
|
this.d_sortField = columnField;
|
2019-07-02 10:15:50 +00:00
|
|
|
|
|
|
|
if(this.sortMode === 'multiple') {
|
|
|
|
let metaKey = event.metaKey || event.ctrlKey;
|
|
|
|
if (!metaKey) {
|
|
|
|
this.d_multiSortMeta = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
this.addSortMeta({field: this.d_sortField, order: this.d_sortOrder});
|
|
|
|
}
|
|
|
|
|
|
|
|
this.$emit('update:sortField', this.d_sortFied);
|
|
|
|
this.$emit('update:sortOrder', this.d_sortOrder);
|
|
|
|
this.$emit('update:multiSortMeta', this.d_multiSortMeta);
|
|
|
|
|
|
|
|
this.$emit('sort', {
|
|
|
|
originalEvent: event,
|
|
|
|
sortField: this.d_sortField,
|
|
|
|
sortOrder: this.d_sortOrder,
|
|
|
|
multiSortMeta: this.d_multiSortMeta
|
|
|
|
});
|
2019-07-01 13:50:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2019-07-02 10:15:50 +00:00
|
|
|
sortSingle(value) {
|
2019-07-02 10:46:06 +00:00
|
|
|
let data = [...value];
|
2019-07-02 10:15:50 +00:00
|
|
|
|
|
|
|
data.sort((data1, data2) => {
|
|
|
|
let value1 = ObjectUtils.resolveFieldData(data1, this.d_sortField);
|
|
|
|
let value2 = ObjectUtils.resolveFieldData(data2, this.d_sortField);
|
|
|
|
let result = null;
|
|
|
|
|
|
|
|
if (value1 == null && value2 != null)
|
|
|
|
result = -1;
|
|
|
|
else if (value1 != null && value2 == null)
|
|
|
|
result = 1;
|
|
|
|
else if (value1 == null && value2 == null)
|
|
|
|
result = 0;
|
|
|
|
else if (typeof value1 === 'string' && typeof value2 === 'string')
|
|
|
|
result = value1.localeCompare(value2, undefined, { numeric: true });
|
|
|
|
else
|
|
|
|
result = (value1 < value2) ? -1 : (value1 > value2) ? 1 : 0;
|
2019-07-01 13:50:55 +00:00
|
|
|
|
2019-07-02 10:15:50 +00:00
|
|
|
return (this.d_sortOrder * result);
|
|
|
|
});
|
2019-07-01 13:50:55 +00:00
|
|
|
|
2019-07-02 10:15:50 +00:00
|
|
|
return data;
|
|
|
|
},
|
|
|
|
sortMultiple(value) {
|
2019-07-02 10:46:06 +00:00
|
|
|
let data = [...value];
|
2019-07-02 10:15:50 +00:00
|
|
|
|
|
|
|
data.sort((data1, data2) => {
|
|
|
|
return this.multisortField(data1, data2, 0);
|
|
|
|
});
|
2019-07-01 13:50:55 +00:00
|
|
|
|
2019-07-02 10:15:50 +00:00
|
|
|
return data;
|
|
|
|
},
|
|
|
|
multisortField(data1, data2, index) {
|
|
|
|
const value1 = ObjectUtils.resolveFieldData(data1, this.d_multiSortMeta[index].field);
|
|
|
|
const value2 = ObjectUtils.resolveFieldData(data2, this.d_multiSortMeta[index].field);
|
|
|
|
let result = null;
|
2019-07-01 13:50:55 +00:00
|
|
|
|
2019-07-02 10:15:50 +00:00
|
|
|
if (typeof value1 === 'string' || value1 instanceof String) {
|
|
|
|
if (value1.localeCompare && (value1 !== value2)) {
|
|
|
|
return (this.d_multiSortMeta[index].order * value1.localeCompare(value2, undefined, { numeric: true }));
|
|
|
|
}
|
2019-07-01 13:50:55 +00:00
|
|
|
}
|
|
|
|
else {
|
2019-07-02 10:15:50 +00:00
|
|
|
result = (value1 < value2) ? -1 : 1;
|
2019-07-01 13:50:55 +00:00
|
|
|
}
|
2019-07-02 10:15:50 +00:00
|
|
|
|
|
|
|
if (value1 === value2) {
|
|
|
|
return (this.d_multiSortMeta.length - 1) > (index) ? (this.multisortField(data1, data2, index + 1)) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (this.d_multiSortMeta[index].order * result);
|
|
|
|
},
|
|
|
|
getMultiSortMetaIndex(column) {
|
|
|
|
let index = -1;
|
|
|
|
|
|
|
|
for (let i = 0; i < this.d_multiSortMeta.length; i++) {
|
|
|
|
let meta = this.d_multiSortMeta[i];
|
|
|
|
if (meta.field === (column.field || column.sortField)) {
|
|
|
|
index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return index;
|
2019-07-01 13:50:55 +00:00
|
|
|
},
|
|
|
|
getColumnHeaderClass(column) {
|
2019-07-02 10:15:50 +00:00
|
|
|
const sorted = this.sortMode === 'single' ? (this.d_sortField === (column.field || column.sortField)) : this.getMultiSortMetaIndex(column) > -1;
|
2019-07-01 13:50:55 +00:00
|
|
|
|
|
|
|
return [column.headerClass,
|
|
|
|
{'p-sortable-column': column.sortable},
|
|
|
|
{'p-highlight': sorted}
|
|
|
|
];
|
|
|
|
},
|
|
|
|
getSortableColumnIcon(column) {
|
2019-07-02 10:15:50 +00:00
|
|
|
let sorted = false;
|
|
|
|
let sortOrder = null;
|
|
|
|
|
|
|
|
if (this.sortMode === 'single') {
|
|
|
|
sorted = this.d_sortField === (column.field || column.sortField);
|
|
|
|
sortOrder = sorted ? this.d_sortOrder: 0;
|
|
|
|
}
|
|
|
|
else if (this.sortMode === 'multiple') {
|
|
|
|
let metaIndex = this.getMultiSortMetaIndex(column);
|
|
|
|
if (metaIndex > -1) {
|
|
|
|
sorted = true;
|
|
|
|
sortOrder = this.d_multiSortMeta[metaIndex].order;
|
|
|
|
}
|
|
|
|
}
|
2019-07-01 13:50:55 +00:00
|
|
|
|
|
|
|
return [
|
|
|
|
'p-sortable-column-icon pi pi-fw',
|
|
|
|
{'pi-sort': !sorted},
|
2019-07-02 10:15:50 +00:00
|
|
|
{'pi-sort-up': sorted && sortOrder > 0},
|
|
|
|
{'pi-sort-down': sorted && sortOrder < 0},
|
2019-07-01 13:50:55 +00:00
|
|
|
];
|
2019-07-02 10:15:50 +00:00
|
|
|
},
|
|
|
|
addSortMeta(meta) {
|
|
|
|
let index = -1;
|
|
|
|
for (let i = 0; i < this.d_multiSortMeta.length; i++) {
|
|
|
|
if (this.d_multiSortMeta[i].field === meta.field) {
|
|
|
|
index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(index >= 0)
|
|
|
|
this.d_multiSortMeta[index] = meta;
|
|
|
|
else
|
|
|
|
this.d_multiSortMeta.push(meta);
|
|
|
|
|
|
|
|
this.d_multiSortMeta = [...this.d_multiSortMeta];
|
2019-07-02 12:57:03 +00:00
|
|
|
},
|
|
|
|
filter(data) {
|
|
|
|
let filteredValue = [];
|
|
|
|
|
|
|
|
for(let i = 0; i < data.length; i++) {
|
|
|
|
let localMatch = true;
|
|
|
|
let globalMatch = false;
|
|
|
|
|
|
|
|
for(let j = 0; j < this.columns.length; j++) {
|
|
|
|
let col = this.columns[j];
|
|
|
|
let columnField = col.field;
|
|
|
|
|
|
|
|
//local
|
|
|
|
if (this.filters.hasOwnProperty(columnField)) {
|
|
|
|
let filterValue = this.filters[columnField];
|
|
|
|
let dataFieldValue = ObjectUtils.resolveFieldData(data[i], columnField);
|
|
|
|
let filterConstraint = FilterUtils[col.filterMatchMode];
|
|
|
|
|
|
|
|
if (!filterConstraint(dataFieldValue, filterValue)) {
|
|
|
|
localMatch = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!localMatch) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!col.excludeGlobalFilter && this.hasGlobalFilter && !globalMatch) {
|
|
|
|
globalMatch = FilterUtils.contains(ObjectUtils.resolveFieldData(data[i], columnField), this.filters['global']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let matches = localMatch;
|
|
|
|
if(this.hasGlobalFilter) {
|
|
|
|
matches = localMatch && globalMatch;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(matches) {
|
|
|
|
filteredValue.push(data[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filteredValue.length === data.length) {
|
|
|
|
filteredValue = data;
|
|
|
|
}
|
|
|
|
|
2019-07-10 17:59:21 +00:00
|
|
|
this.$emit('filter', {
|
|
|
|
filters: this.filters,
|
|
|
|
filteredValue: filteredValue
|
|
|
|
});
|
|
|
|
|
2019-07-02 12:57:03 +00:00
|
|
|
return filteredValue;
|
2019-07-03 10:07:57 +00:00
|
|
|
},
|
2019-07-09 09:37:19 +00:00
|
|
|
onRowClick(event, rowData, rowIndex) {
|
2019-07-03 10:07:57 +00:00
|
|
|
if (this.selectionMode) {
|
|
|
|
let target = event.target;
|
|
|
|
let targetNode = target.nodeName;
|
|
|
|
let parentNode = target.parentElement && target.parentElement.nodeName;
|
|
|
|
|
|
|
|
if (targetNode == 'INPUT' || targetNode == 'BUTTON' || targetNode == 'A' ||
|
|
|
|
parentNode == 'INPUT' || parentNode == 'BUTTON' || parentNode == 'A' ||
|
|
|
|
(DomHandler.hasClass(target, 'p-clickable'))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.isMultipleSelectionMode() && event.shiftKey && this.anchorRowIndex != null) {
|
|
|
|
DomHandler.clearSelection();
|
2019-07-09 09:37:19 +00:00
|
|
|
this.rangeRowIndex = rowIndex;
|
2019-07-09 09:57:21 +00:00
|
|
|
this.selectRange(event);
|
2019-07-03 10:07:57 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
const selected = this.isSelected(rowData);
|
|
|
|
const metaSelection = this.rowTouched ? false : this.metaKeySelection;
|
2019-07-09 09:37:19 +00:00
|
|
|
this.anchorRowIndex = rowIndex;
|
|
|
|
this.rangeRowIndex = rowIndex;
|
2019-07-03 10:07:57 +00:00
|
|
|
|
|
|
|
if (metaSelection) {
|
|
|
|
let metaKey = event.metaKey || event.ctrlKey;
|
|
|
|
|
|
|
|
if (selected && metaKey) {
|
|
|
|
if(this.isSingleSelectionMode()) {
|
|
|
|
this.$emit('update:selection', null);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const selectionIndex = this.findIndexInSelection(rowData);
|
|
|
|
const _selection = this.selection.filter((val,i) => i != selectionIndex);
|
|
|
|
this.$emit('update:selection', _selection);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.$emit('row-unselect', {originalEvent: event, data: rowData, type: 'row'});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(this.isSingleSelectionMode()) {
|
|
|
|
this.$emit('update:selection', rowData);
|
|
|
|
}
|
|
|
|
else if (this.isMultipleSelectionMode()) {
|
|
|
|
let _selection = metaKey ? (this.selection || []) : [];
|
|
|
|
_selection = [..._selection, rowData];
|
|
|
|
this.$emit('update:selection', _selection);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.$emit('row-select', {originalEvent: event, data: rowData, type: 'row'});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (this.selectionMode === 'single') {
|
|
|
|
if (selected) {
|
|
|
|
this.$emit('update:selection', null);
|
|
|
|
this.$emit('row-unselect', {originalEvent: event, data: rowData, type: 'row'});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.$emit('update:selection', rowData);
|
|
|
|
this.$emit('row-select', {originalEvent: event, data: rowData, type: 'row'});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (this.selectionMode === 'multiple') {
|
|
|
|
if (selected) {
|
|
|
|
const selectionIndex = this.findIndexInSelection(rowData);
|
|
|
|
const _selection = this.selection.filter((val, i) => i != selectionIndex);
|
|
|
|
this.$emit('update:selection', _selection);
|
|
|
|
this.$emit('row-unselect', {originalEvent: event, data: rowData, type: 'row'});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const _selection = this.selection ? [...this.selection, rowData] : [rowData];
|
|
|
|
this.$emit('update:selection', _selection);
|
|
|
|
this.$emit('row-select', {originalEvent: event, data: rowData, type: 'row'});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.rowTouched = false;
|
|
|
|
},
|
|
|
|
onRowTouchEnd() {
|
|
|
|
this.rowTouched = true;
|
|
|
|
},
|
2019-07-09 09:44:46 +00:00
|
|
|
onRowKeyDown(event, rowData, rowIndex) {
|
|
|
|
if (this.selectionMode) {
|
|
|
|
const row = event.target;
|
|
|
|
|
|
|
|
switch (event.which) {
|
|
|
|
//down arrow
|
|
|
|
case 40:
|
2019-07-09 09:57:21 +00:00
|
|
|
var nextRow = this.findNextSelectableRow(row);
|
2019-07-09 09:44:46 +00:00
|
|
|
if (nextRow) {
|
|
|
|
nextRow.focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
break;
|
|
|
|
|
|
|
|
//up arrow
|
|
|
|
case 38:
|
2019-07-09 09:57:21 +00:00
|
|
|
var prevRow = this.findPrevSelectableRow(row);
|
2019-07-09 09:44:46 +00:00
|
|
|
if (prevRow) {
|
|
|
|
prevRow.focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
break;
|
|
|
|
|
|
|
|
//enter
|
|
|
|
case 13:
|
|
|
|
this.onRowClick(event, rowData, rowIndex);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
//no op
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
findNextSelectableRow(row) {
|
|
|
|
let nextRow = row.nextElementSibling;
|
|
|
|
if (nextRow) {
|
|
|
|
if (DomHandler.hasClass(nextRow, 'p-datatable-row'))
|
|
|
|
return nextRow;
|
|
|
|
else
|
|
|
|
return this.findNextSelectableRow(nextRow);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
findPrevSelectableRow(row) {
|
|
|
|
let prevRow = row.previousElementSibling;
|
|
|
|
if (prevRow) {
|
|
|
|
if (DomHandler.hasClass(prevRow, 'p-datatable-row'))
|
|
|
|
return prevRow;
|
|
|
|
else
|
|
|
|
return this.findPrevSelectableRow(prevRow);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
},
|
2019-07-09 11:36:24 +00:00
|
|
|
toggleRowWithRadio(event) {
|
|
|
|
const rowData = event.data;
|
|
|
|
|
|
|
|
if (this.isSelected(rowData)) {
|
|
|
|
this.$emit('update:selection', null);
|
|
|
|
this.$emit('row-unselect', {originalEvent: event, data: rowData, type: 'radiobutton'});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.$emit('update:selection', rowData);
|
|
|
|
this.$emit('row-select', {originalEvent: event, data: rowData, type: 'radiobutton'});
|
|
|
|
}
|
|
|
|
},
|
2019-07-09 12:41:15 +00:00
|
|
|
toggleRowWithCheckbox(event) {
|
|
|
|
const rowData = event.data;
|
|
|
|
|
|
|
|
if (this.isSelected(rowData)) {
|
|
|
|
const selectionIndex = this.findIndexInSelection(rowData);
|
|
|
|
const _selection = this.selection.filter((val, i) => i != selectionIndex);
|
|
|
|
this.$emit('update:selection', _selection);
|
|
|
|
this.$emit('row-unselect', {originalEvent: event, data: rowData, type: 'checkbox'});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
let _selection = this.selection ? [...this.selection] : [];
|
|
|
|
_selection = [..._selection, rowData];
|
|
|
|
this.$emit('update:selection', _selection);
|
|
|
|
this.$emit('row-select', {originalEvent: event, data: rowData, type: 'checkbox'});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
toggleRowsWithCheckbox(event) {
|
|
|
|
const processedData = this.processedData;
|
|
|
|
const checked = this.allRowsSelected;
|
|
|
|
const _selection = checked ? [] : (processedData ? [...processedData] : [...this.value]);
|
|
|
|
this.$emit('update:selection', _selection);
|
|
|
|
|
|
|
|
if (checked)
|
|
|
|
this.$emit('row-unselect-all', {originalEvent: event});
|
|
|
|
else
|
|
|
|
this.$emit('row-select-all', {originalEvent: event, data: _selection});
|
|
|
|
},
|
2019-07-03 10:07:57 +00:00
|
|
|
isSingleSelectionMode() {
|
|
|
|
return this.selectionMode === 'single';
|
|
|
|
},
|
|
|
|
isMultipleSelectionMode() {
|
|
|
|
return this.selectionMode === 'multiple';
|
|
|
|
},
|
|
|
|
isSelected(rowData) {
|
|
|
|
if (rowData && this.selection) {
|
|
|
|
if (this.dataKey) {
|
2019-07-09 09:44:46 +00:00
|
|
|
return this.d_selectionKeys ? this.d_selectionKeys[ObjectUtils.resolveFieldData(rowData, this.dataKey)] !== undefined : false;
|
2019-07-03 10:07:57 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (this.selection instanceof Array)
|
|
|
|
return this.findIndexInSelection(rowData) > -1;
|
|
|
|
else
|
|
|
|
return this.equals(rowData, this.selection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
findIndexInSelection(rowData) {
|
|
|
|
let index = -1;
|
|
|
|
if (this.selection && this.selection.length) {
|
|
|
|
for (let i = 0; i < this.selection.length; i++) {
|
|
|
|
if (this.equals(rowData, this.selection[i])) {
|
|
|
|
index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return index;
|
|
|
|
},
|
|
|
|
updateSelectionKeys(selection) {
|
|
|
|
this.d_selectionKeys = {};
|
|
|
|
if (Array.isArray(selection)) {
|
|
|
|
for (let data of selection) {
|
|
|
|
this.d_selectionKeys[String(ObjectUtils.resolveFieldData(data, this.dataKey))] = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this.d_selectionKeys[String(ObjectUtils.resolveFieldData(selection, this.dataKey))] = 1;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
equals(data1, data2) {
|
|
|
|
return this.compareSelectionBy === 'equals' ? (data1 === data2) : ObjectUtils.equals(data1, data2, this.dataKey);
|
|
|
|
},
|
|
|
|
getRowKey(rowData, index) {
|
|
|
|
return this.dataKey ? ObjectUtils.resolveFieldData(rowData, this.dataKey): index;
|
|
|
|
},
|
|
|
|
getRowClass(rowData) {
|
|
|
|
if (this.selection) {
|
2019-07-09 09:44:46 +00:00
|
|
|
return ['p-datatable-row', {
|
2019-07-03 10:07:57 +00:00
|
|
|
'p-highlight': this.isSelected(rowData)
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 'p-datatable-row';
|
|
|
|
}
|
2019-07-09 09:37:19 +00:00
|
|
|
},
|
2019-07-09 09:57:21 +00:00
|
|
|
selectRange(event) {
|
2019-07-09 09:37:19 +00:00
|
|
|
let rangeStart, rangeEnd;
|
|
|
|
|
|
|
|
if (this.rangeRowIndex > this.anchorRowIndex) {
|
|
|
|
rangeStart = this.anchorRowIndex;
|
|
|
|
rangeEnd = this.rangeRowIndex;
|
|
|
|
}
|
|
|
|
else if(this.rangeRowIndex < this.anchorRowIndex) {
|
|
|
|
rangeStart = this.rangeRowIndex;
|
|
|
|
rangeEnd = this.anchorRowIndex;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rangeStart = this.rangeRowIndex;
|
|
|
|
rangeEnd = this.rangeRowIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.lazy && this.paginator) {
|
|
|
|
rangeStart -= this.first;
|
|
|
|
rangeEnd -= this.first;
|
|
|
|
}
|
|
|
|
|
2019-07-09 12:41:15 +00:00
|
|
|
const value = this.processedData;
|
2019-07-09 09:37:19 +00:00
|
|
|
let _selection = [];
|
|
|
|
for(let i = rangeStart; i <= rangeEnd; i++) {
|
2019-07-09 12:41:15 +00:00
|
|
|
let rangeRowData = value[i];
|
2019-07-09 09:37:19 +00:00
|
|
|
_selection.push(rangeRowData);
|
|
|
|
this.$emit('row-select', {originalEvent: event, data: rangeRowData, type: 'row'});
|
|
|
|
}
|
|
|
|
|
|
|
|
this.$emit('update:selection', _selection);
|
2019-07-09 13:21:42 +00:00
|
|
|
},
|
|
|
|
exportCSV(options) {
|
|
|
|
let data = this.processedData;
|
|
|
|
let csv = '\ufeff';
|
|
|
|
|
|
|
|
if (options && options.selectionOnly) {
|
|
|
|
data = this.selection || [];
|
|
|
|
}
|
|
|
|
|
|
|
|
//headers
|
|
|
|
for (let i = 0; i < this.columns.length; i++) {
|
|
|
|
let column = this.columns[i];
|
|
|
|
if (column.exportable !== false && column.field) {
|
|
|
|
csv += '"' + (column.header || column.field) + '"';
|
|
|
|
|
|
|
|
if (i < (this.columns.length - 1)) {
|
|
|
|
csv += this.csvSeparator;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//body
|
2019-07-10 17:44:54 +00:00
|
|
|
data.forEach(record => {
|
2019-07-09 13:21:42 +00:00
|
|
|
csv += '\n';
|
|
|
|
for (let i = 0; i < this.columns.length; i++) {
|
|
|
|
let column = this.columns[i];
|
|
|
|
if (column.exportable !== false && column.field) {
|
|
|
|
let cellData = ObjectUtils.resolveFieldData(record, column.field);
|
|
|
|
|
|
|
|
if (cellData != null) {
|
|
|
|
if (this.exportFunction) {
|
|
|
|
cellData = this.exportFunction({
|
|
|
|
data: cellData,
|
|
|
|
field: column.field
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else
|
|
|
|
cellData = String(cellData).replace(/"/g, '""');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
cellData = '';
|
|
|
|
|
|
|
|
|
|
|
|
csv += '"' + cellData + '"';
|
|
|
|
|
|
|
|
if (i < (this.columns.length - 1)) {
|
|
|
|
csv += this.csvSeparator;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let blob = new Blob([csv], {
|
|
|
|
type: 'text/csv;charset=utf-8;'
|
|
|
|
});
|
|
|
|
|
|
|
|
if (window.navigator.msSaveOrOpenBlob) {
|
|
|
|
navigator.msSaveOrOpenBlob(blob, this.exportFilename + '.csv');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
let link = document.createElement("a");
|
|
|
|
link.style.display = 'none';
|
|
|
|
document.body.appendChild(link);
|
|
|
|
if (link.download !== undefined) {
|
|
|
|
link.setAttribute('href', URL.createObjectURL(blob));
|
|
|
|
link.setAttribute('download', this.exportFilename + '.csv');
|
|
|
|
link.click();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
csv = 'data:text/csv;charset=utf-8,' + csv;
|
|
|
|
window.open(encodeURI(csv));
|
|
|
|
}
|
|
|
|
document.body.removeChild(link);
|
|
|
|
}
|
2019-07-28 14:11:23 +00:00
|
|
|
},
|
|
|
|
resetPage() {
|
|
|
|
this.d_first = 0;
|
|
|
|
this.$emit('update:first', this.d_first);
|
2019-06-27 21:17:21 +00:00
|
|
|
}
|
2019-06-28 14:40:32 +00:00
|
|
|
},
|
2019-06-29 11:29:19 +00:00
|
|
|
computed: {
|
2019-07-03 10:07:57 +00:00
|
|
|
containerClass() {
|
|
|
|
return [
|
|
|
|
'p-datatable p-component', {
|
2019-07-10 14:20:12 +00:00
|
|
|
'p-datatable-hoverable-rows': (this.rowHover || this.selectionMode),
|
|
|
|
'p-datatable-auto-layout': this.autoLayout
|
2019-07-03 10:07:57 +00:00
|
|
|
}
|
|
|
|
];
|
|
|
|
},
|
2019-07-02 09:02:55 +00:00
|
|
|
columns() {
|
|
|
|
if (this.allChildren) {
|
|
|
|
return this.allChildren.filter(child => child.$options._propKeys.indexOf('columnKey') !== -1);
|
|
|
|
}
|
|
|
|
return [];
|
|
|
|
},
|
2019-07-02 14:12:19 +00:00
|
|
|
processedData() {
|
2019-07-10 18:09:22 +00:00
|
|
|
if (this.lazy) {
|
|
|
|
return this.value;
|
2019-06-29 11:29:19 +00:00
|
|
|
}
|
|
|
|
else {
|
2019-07-10 18:09:22 +00:00
|
|
|
if (this.value && this.value.length) {
|
|
|
|
let data = this.value;
|
|
|
|
|
|
|
|
if (this.sorted) {
|
|
|
|
if(this.sortMode === 'single')
|
|
|
|
data = this.sortSingle(data);
|
|
|
|
else if(this.sortMode === 'multiple')
|
|
|
|
data = this.sortMultiple(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.hasFilters) {
|
|
|
|
data = this.filter(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return null;
|
|
|
|
}
|
2019-06-29 11:29:19 +00:00
|
|
|
}
|
|
|
|
},
|
2019-07-02 14:12:19 +00:00
|
|
|
dataToRender() {
|
|
|
|
const data = this.processedData;
|
|
|
|
|
|
|
|
if (this.paginator) {
|
|
|
|
const first = this.lazy ? 0 : this.d_first;
|
|
|
|
return data.slice(first, first + this.d_rows);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
},
|
2019-06-29 11:29:19 +00:00
|
|
|
totalRecordsLength() {
|
2019-07-02 14:12:19 +00:00
|
|
|
if (this.lazy) {
|
2019-06-29 11:29:19 +00:00
|
|
|
return this.totalRecords;
|
2019-07-02 14:12:19 +00:00
|
|
|
}
|
|
|
|
else {
|
2019-07-09 12:41:15 +00:00
|
|
|
const data = this.processedData;
|
2019-07-02 14:12:19 +00:00
|
|
|
return data ? data.length : 0;
|
|
|
|
}
|
2019-06-29 11:29:19 +00:00
|
|
|
},
|
|
|
|
empty() {
|
2019-07-10 18:09:22 +00:00
|
|
|
const data = this.processedData;
|
|
|
|
return (!data || data.length === 0);
|
2019-06-29 11:29:19 +00:00
|
|
|
},
|
|
|
|
paginatorTop() {
|
2019-06-29 12:27:35 +00:00
|
|
|
return this.paginator && (this.paginatorPosition !== 'bottom' || this.paginatorPosition === 'both');
|
2019-06-29 11:29:19 +00:00
|
|
|
},
|
|
|
|
paginatorBottom() {
|
2019-06-29 12:27:35 +00:00
|
|
|
return this.paginator && (this.paginatorPosition !== 'top' || this.paginatorPosition === 'both');
|
2019-07-02 10:15:50 +00:00
|
|
|
},
|
|
|
|
sorted() {
|
|
|
|
return this.d_sortField || (this.d_multiSortMeta && this.d_multiSortMeta.length > 0);
|
2019-07-02 10:46:06 +00:00
|
|
|
},
|
|
|
|
hasFooter() {
|
|
|
|
let hasFooter = false;
|
|
|
|
|
|
|
|
for (let col of this.columns) {
|
|
|
|
if (col.footer || col.$scopedSlots.footer) {
|
|
|
|
hasFooter = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return hasFooter;
|
2019-07-02 12:57:03 +00:00
|
|
|
},
|
|
|
|
hasFilters() {
|
|
|
|
return this.filters && Object.keys(this.filters).length > 0 && this.filters.constructor === Object;
|
|
|
|
},
|
|
|
|
hasGlobalFilter() {
|
|
|
|
return this.filters && this.filters.hasOwnProperty('global');
|
2019-07-02 14:29:30 +00:00
|
|
|
},
|
|
|
|
loadingIconClass() {
|
|
|
|
return ['p-datatable-loading-icon pi-spin', this.loadingIcon];
|
2019-07-09 12:41:15 +00:00
|
|
|
},
|
|
|
|
allRowsSelected() {
|
|
|
|
const val = this.processedData;
|
2019-07-09 13:15:42 +00:00
|
|
|
return (val && val.length > 0 && this.selection && this.selection.length > 0 && this.selection.length === val.length);
|
2019-06-29 11:47:14 +00:00
|
|
|
}
|
2019-06-29 11:29:19 +00:00
|
|
|
},
|
2019-06-28 14:40:32 +00:00
|
|
|
components: {
|
2019-06-29 11:29:19 +00:00
|
|
|
'ColumnSlot': ColumnSlot,
|
2019-07-09 11:36:24 +00:00
|
|
|
'DTPaginator': Paginator,
|
2019-07-09 12:41:15 +00:00
|
|
|
'DTRadioButton': RowRadioButton,
|
|
|
|
'DTCheckbox': RowCheckbox,
|
|
|
|
'DTHeaderCheckbox': HeaderCheckbox
|
2019-06-27 21:17:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style>
|
|
|
|
.p-datatable {
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable table {
|
|
|
|
border-collapse: collapse;
|
|
|
|
width: 100%;
|
|
|
|
table-layout: fixed;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable .p-datatable-thead > tr > th,
|
|
|
|
.p-datatable .p-datatable-tbody > tr > td,
|
|
|
|
.p-datatable .p-datatable-tfoot > tr > td {
|
|
|
|
padding: .25em .5em;
|
|
|
|
}
|
|
|
|
|
2019-08-07 07:31:44 +00:00
|
|
|
.p-datatable .p-column-title {
|
|
|
|
user-select: none;
|
|
|
|
}
|
|
|
|
|
2019-06-27 21:17:21 +00:00
|
|
|
.p-datatable .p-sortable-column {
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable .p-sortable-column-icon {
|
|
|
|
vertical-align: middle;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-auto-layout > .p-datatable-wrapper {
|
|
|
|
overflow-x: auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-auto-layout > .p-datatable-wrapper > table {
|
|
|
|
table-layout: auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Sections */
|
|
|
|
.p-datatable-header,
|
|
|
|
.p-datatable-footer {
|
|
|
|
padding: .25em .5em;
|
|
|
|
text-align: center;
|
|
|
|
font-weight: bold;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-header {
|
|
|
|
border-bottom: 0 none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-footer {
|
|
|
|
border-top: 0 none;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Paginator */
|
|
|
|
.p-datatable .p-paginator-top {
|
|
|
|
border-bottom: 0 none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable .p-paginator-bottom {
|
|
|
|
border-top: 0 none;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scrollable */
|
|
|
|
.p-datatable-scrollable-wrapper {
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
.p-datatable-scrollable-header,
|
|
|
|
.p-datatable-scrollable-footer {
|
|
|
|
overflow: hidden;
|
|
|
|
border: 0 none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-scrollable-body {
|
|
|
|
overflow: auto;
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-scrollable-body > table > .p-datatable-tbody > tr:first-child > td {
|
|
|
|
border-top: 0 none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-virtual-table {
|
|
|
|
position: absolute;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Frozen Columns */
|
|
|
|
.p-datatable-frozen-view .p-datatable-scrollable-body {
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-frozen-view > .p-datatable-scrollable-body > table > .p-datatable-tbody > tr > td:last-child {
|
|
|
|
border-right: 0 none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-unfrozen-view {
|
|
|
|
position: absolute;
|
|
|
|
top: 0px;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Filter */
|
|
|
|
.p-column-filter {
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Resizable */
|
|
|
|
.p-datatable-resizable > .p-datatable-wrapper {
|
|
|
|
overflow-x: auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-resizable .p-datatable-thead > tr > th,
|
|
|
|
.p-datatable-resizable .p-datatable-tfoot > tr > td,
|
|
|
|
.p-datatable-resizable .p-datatable-tbody > tr > td {
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-resizable .p-resizable-column {
|
|
|
|
background-clip: padding-box;
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable-resizable-fit .p-resizable-column:last-child .p-column-resizer {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable .p-column-resizer {
|
|
|
|
display: block;
|
|
|
|
position: absolute !important;
|
|
|
|
top: 0;
|
|
|
|
right: 0;
|
|
|
|
margin: 0;
|
|
|
|
width: .5em;
|
|
|
|
height: 100%;
|
|
|
|
padding: 0px;
|
|
|
|
cursor:col-resize;
|
|
|
|
border: 1px solid transparent;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable .p-column-resizer-helper {
|
|
|
|
width: 1px;
|
|
|
|
position: absolute;
|
|
|
|
z-index: 10;
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Edit */
|
|
|
|
.p-datatable .p-datatable-tbody > tr > td.p-cell-editing .p-component {
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reorder */
|
|
|
|
.p-datatable-reorder-indicator-up,
|
|
|
|
.p-datatable-reorder-indicator-down {
|
|
|
|
position: absolute;
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Loader */
|
2019-07-02 14:29:30 +00:00
|
|
|
.p-datatable .p-datatable-loading-overlay {
|
2019-06-27 21:17:21 +00:00
|
|
|
position: absolute;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=10)";
|
|
|
|
opacity: 0.1;
|
|
|
|
z-index: 1;
|
|
|
|
}
|
|
|
|
|
2019-07-02 14:29:30 +00:00
|
|
|
.p-datatable .p-datatable-loading-content {
|
2019-06-27 21:17:21 +00:00
|
|
|
position: absolute;
|
|
|
|
left: 50%;
|
|
|
|
top: 50%;
|
|
|
|
z-index: 2;
|
|
|
|
margin-top: -1em;
|
|
|
|
margin-left: -1em;
|
|
|
|
}
|
|
|
|
|
|
|
|
.p-datatable .p-datatable-loading-icon {
|
|
|
|
font-size: 2em;
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|