2019-11-18 07:42:32 +00:00
|
|
|
<template>
|
|
|
|
<thead class="p-datatable-thead">
|
2020-03-05 08:59:07 +00:00
|
|
|
<template v-if="!columnGroup">
|
|
|
|
<tr>
|
|
|
|
<template v-for="(col,i) of columns">
|
2021-02-02 13:21:10 +00:00
|
|
|
<th v-if="rowGroupMode !== 'subheader' || (groupRowsBy !== columnProp(col, 'field'))" :tabindex="columnProp(col, 'sortable') ? '0' : null" @keydown="onColumnKeyDown($event, col)"
|
|
|
|
:key="columnProp(col, 'columnKey')||columnProp(col, 'field')||i" :style="columnProp(col, 'headerStyle')" :class="getColumnHeaderClass(col)"
|
2020-03-05 08:59:07 +00:00
|
|
|
@click="onColumnHeaderClick($event, col)" @mousedown="onColumnHeaderMouseDown($event, col)"
|
|
|
|
@dragstart="onColumnHeaderDragStart($event)" @dragover="onColumnHeaderDragOver($event)" @dragleave="onColumnHeaderDragLeave($event)" @drop="onColumnHeaderDrop($event)"
|
2021-02-02 13:21:10 +00:00
|
|
|
:colspan="columnProp(col, 'colspan')" :rowspan="columnProp(col, 'rowspan')" :aria-sort="getAriaSort(col)">
|
2020-05-02 09:19:17 +00:00
|
|
|
<span class="p-column-resizer" @mousedown="onColumnResizeStart($event)" v-if="resizableColumns"></span>
|
2021-02-06 12:21:39 +00:00
|
|
|
<div class="p-column-header-content">
|
|
|
|
<component :is="col.children.header" :column="col" v-if="col.children && col.children.header"/>
|
|
|
|
<span class="p-column-title" v-if="columnProp(col, 'header')">{{columnProp(col, 'header')}}</span>
|
|
|
|
<span v-if="columnProp(col, 'sortable')" :class="getSortableColumnIcon(col)"></span>
|
|
|
|
<span v-if="isMultiSorted(col)" class="p-sortable-column-badge">{{getMultiSortMetaIndex(col) + 1}}</span>
|
|
|
|
<DTHeaderCheckbox :checked="allRowsSelected" @change="onHeaderCheckboxChange($event)" :disabled="empty" v-if="columnProp(col, 'selectionMode') ==='multiple' && filterDisplay !== 'row'" />
|
2021-02-06 23:47:55 +00:00
|
|
|
<DTColumnFilter v-if="filterDisplay === 'menu' && col.children && col.children.filter" :field="columnProp(col, 'filterField')||columnProp(col, 'field')" :type="columnProp(col, 'dataType')" display="menu"
|
2021-02-08 11:34:23 +00:00
|
|
|
:showMenu="columnProp(col, 'showFilterMenu')" :filterElement="col.children && col.children.filter"
|
|
|
|
:filterHeaderTemplate="col.children && col.children.filterheader" :filterFooterTemplate="col.children && col.children.filterfooter"
|
|
|
|
:filterClearTemplate="col.children && col.children.filterclear" :filterApplyTemplate="col.children && col.children.filterapply"
|
2021-02-08 11:07:06 +00:00
|
|
|
:filters="filters" :filtersStore="filtersStore" @filter-change="$emit('filter-change', $event)" @filter-apply="$emit('filter-apply')" :filterMenuStyle="columnProp(col, 'filterMenuStyle')" :filterMenuClass="columnProp(col, 'filterMenuClass')"
|
2021-02-06 12:21:39 +00:00
|
|
|
:showOperator="columnProp(col, 'showFilterOperator')" :showClearButton="columnProp(col, 'showClearButton')" :showApplyButton="columnProp(col, 'showApplyButton')"
|
2021-02-08 11:20:52 +00:00
|
|
|
:showMatchModes="columnProp(col, 'showFilterMatchModes')" :showAddButton="columnProp(col, 'showAddButton')" :matchModeOptions="columnProp(col, 'filterMatchModeOptions')" :maxConstraints="columnProp(col, '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)"/>
|
2021-02-06 12:21:39 +00:00
|
|
|
</div>
|
2020-03-05 08:59:07 +00:00
|
|
|
</th>
|
|
|
|
</template>
|
|
|
|
</tr>
|
2021-02-06 23:47:55 +00:00
|
|
|
<tr v-if="filterDisplay === 'row'">
|
2020-03-05 08:59:07 +00:00
|
|
|
<template v-for="(col,i) of columns">
|
2021-02-02 13:21:10 +00:00
|
|
|
<th v-if="rowGroupMode !== 'subheader' || (groupRowsBy !== columnProp(col, 'field'))" :key="columnProp(col, 'columnKey')||columnProp(col, 'field')||i"
|
|
|
|
:class="getFilterColumnHeaderClass(col)" :style="columnProp(col, 'filterHeaderStyle')">
|
2021-02-06 23:47:55 +00:00
|
|
|
<DTColumnFilter v-if="col.children && col.children.filter" :field="columnProp(col, 'filterField')||columnProp(col, 'field')" :type="columnProp(col, 'dataType')" display="row"
|
2021-02-06 09:26:12 +00:00
|
|
|
:showMenu="columnProp(col, 'showFilterMenu')" :filterElement="col.children && col.children.filter" :filterHeader="col.children && col.children.filterHeader" :filterFooter="col.children && col.children.filterFooter"
|
2021-02-08 11:07:06 +00:00
|
|
|
:filters="filters" :filtersStore="filtersStore" @filter-change="$emit('filter-change', $event)" @filter-apply="$emit('filter-apply')" :filterMenuStyle="columnProp(col, 'filterMenuStyle')" :filterMenuClass="columnProp(col, 'filterMenuClass')"
|
2021-02-06 11:23:00 +00:00
|
|
|
:showOperator="columnProp(col, 'showFilterOperator')" :showClearButton="columnProp(col, 'showClearButton')" :showApplyButton="columnProp(col, 'showApplyButton')"
|
2021-02-08 11:20:52 +00:00
|
|
|
:showMatchModes="columnProp(col, 'showFilterMatchModes')" :showAddButton="columnProp(col, 'showAddButton')" :matchModeOptions="columnProp(col, 'filterMatchModeOptions')" :maxConstraints="columnProp(col, '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)"/>
|
2021-02-02 13:21:10 +00:00
|
|
|
<DTHeaderCheckbox :checked="allRowsSelected" @change="onHeaderCheckboxChange($event)" :disabled="empty" v-if="columnProp(col, 'selectionMode')==='multiple'" />
|
2020-03-05 08:59:07 +00:00
|
|
|
</th>
|
|
|
|
</template>
|
|
|
|
</tr>
|
|
|
|
</template>
|
2019-11-18 07:42:32 +00:00
|
|
|
<template v-else>
|
2020-09-23 17:55:00 +00:00
|
|
|
<tr v-for="(row,i) of columnGroup.children.default()" :key="i">
|
2021-02-03 11:26:14 +00:00
|
|
|
<th v-for="(col,i) of row.children.default()" :key="columnProp(col, 'columnKey')||columnProp(col, 'field')||i" :style="columnProp(col, 'headerStyle')" :class="getColumnHeaderClass(col)" :tabindex="columnProp(col, 'sortable') ? '0' : null"
|
2020-03-04 10:36:14 +00:00
|
|
|
@click="onColumnHeaderClick($event, col)" @keydown="onColumnKeyDown($event, col)" @dragstart="onColumnHeaderDragStart($event)" @dragover="onColumnHeaderDragOver($event)" @dragleave="onColumnHeaderDragLeave($event)" @drop="onColumnHeaderDrop($event)"
|
2021-02-02 13:21:10 +00:00
|
|
|
:colspan="columnProp(col, 'colspan')" :rowspan="columnProp(col, 'rowspan')" :aria-sort="getAriaSort(col)">
|
2021-02-06 23:47:55 +00:00
|
|
|
<component :is="col.children.header" :column="col" v-if="col.children && col.children.header"/>
|
2021-02-02 13:21:10 +00:00
|
|
|
<span class="p-column-title" v-if="columnProp(col, 'header')">{{columnProp(col, 'header')}}</span>
|
|
|
|
<span v-if="columnProp(col, 'sortable')" :class="getSortableColumnIcon(col)"></span>
|
2020-04-18 16:03:21 +00:00
|
|
|
<span v-if="isMultiSorted(col)" class="p-sortable-column-badge">{{getMultiSortMetaIndex(col) + 1}}</span>
|
2020-09-23 17:55:00 +00:00
|
|
|
<component :is="col.children.filter" :column="col" v-if="col.children && col.children.filter"/>
|
2021-02-02 13:21:10 +00:00
|
|
|
<DTHeaderCheckbox :checked="allRowsSelected" @change="onHeaderCheckboxChange($event)" :disabled="empty" v-if="columnProp(col, 'selectionMode') ==='multiple'" />
|
2019-11-18 07:42:32 +00:00
|
|
|
</th>
|
|
|
|
</tr>
|
|
|
|
</template>
|
|
|
|
</thead>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2021-01-18 11:20:34 +00:00
|
|
|
import {DomHandler} from 'primevue/utils';
|
2019-11-18 07:42:32 +00:00
|
|
|
import HeaderCheckbox from './HeaderCheckbox.vue';
|
2021-02-06 09:26:12 +00:00
|
|
|
import ColumnFilter from './ColumnFilter';
|
2019-11-18 07:42:32 +00:00
|
|
|
|
|
|
|
export default {
|
2020-10-21 18:03:17 +00:00
|
|
|
emits: ['column-click', 'column-mousedown', 'column-dragstart', 'column-dragover', 'column-dragleave', 'column-drop',
|
2021-02-08 11:20:52 +00:00
|
|
|
'column-resizestart', 'checkbox-change', 'column-click','filter-change', 'filter-apply',
|
|
|
|
'operator-change', 'matchmode-change', 'constraint-add', 'constraint-remove', 'filter-clear', 'apply-click'],
|
2019-11-18 07:42:32 +00:00
|
|
|
props: {
|
|
|
|
columnGroup: {
|
|
|
|
type: null,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
columns: {
|
|
|
|
type: null,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
rowGroupMode: {
|
|
|
|
type: String,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
groupRowsBy: {
|
|
|
|
type: [Array,String],
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
resizableColumns: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
},
|
|
|
|
allRowsSelected: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
},
|
|
|
|
empty: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
},
|
|
|
|
sortMode: {
|
|
|
|
type: String,
|
|
|
|
default: 'single'
|
|
|
|
},
|
|
|
|
sortField: {
|
2020-12-08 11:16:38 +00:00
|
|
|
type: [String, Function],
|
2019-11-18 07:42:32 +00:00
|
|
|
default: null
|
|
|
|
},
|
|
|
|
sortOrder: {
|
|
|
|
type: Number,
|
|
|
|
default: null
|
|
|
|
},
|
|
|
|
multiSortMeta: {
|
|
|
|
type: Array,
|
|
|
|
default: null
|
2021-02-06 09:26:12 +00:00
|
|
|
},
|
|
|
|
filters: {
|
|
|
|
type: Object,
|
|
|
|
default: null
|
|
|
|
},
|
2021-02-08 11:07:06 +00:00
|
|
|
filtersStore: {
|
|
|
|
type: Object,
|
|
|
|
default: null
|
|
|
|
},
|
2021-02-06 09:26:12 +00:00
|
|
|
filterDisplay: {
|
|
|
|
type: String,
|
|
|
|
default: null
|
2019-11-18 07:42:32 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
2021-02-02 13:21:10 +00:00
|
|
|
columnProp(col, prop) {
|
2021-02-02 13:50:37 +00:00
|
|
|
return col.props ? ((col.type.props[prop].type === Boolean && col.props[prop] === '') ? true : col.props[prop]) : null;
|
2021-02-02 13:21:10 +00:00
|
|
|
},
|
2020-04-18 16:03:21 +00:00
|
|
|
isMultiSorted(column) {
|
2021-02-02 13:21:10 +00:00
|
|
|
return this.columnProp(column, 'sortable') && this.getMultiSortMetaIndex(column) > -1
|
2020-04-18 16:03:21 +00:00
|
|
|
},
|
|
|
|
isColumnSorted(column) {
|
2021-02-02 13:21:10 +00:00
|
|
|
return this.sortMode === 'single' ? (this.sortField && (this.sortField === this.columnProp(column, 'field') || this.sortField === this.columnProp(column, 'sortField'))) : this.isMultiSorted(column);
|
2020-04-18 16:03:21 +00:00
|
|
|
},
|
2019-11-18 07:42:32 +00:00
|
|
|
getColumnHeaderClass(column) {
|
2021-02-02 13:21:10 +00:00
|
|
|
return [this.columnProp(column, 'headerClass'),
|
|
|
|
{'p-sortable-column': this.columnProp(column, 'sortable')},
|
2019-11-18 07:42:32 +00:00
|
|
|
{'p-resizable-column': this.resizableColumns},
|
2020-04-18 16:03:21 +00:00
|
|
|
{'p-highlight': this.isColumnSorted(column)}
|
2019-11-18 07:42:32 +00:00
|
|
|
];
|
|
|
|
},
|
2020-03-16 16:11:49 +00:00
|
|
|
getFilterColumnHeaderClass(column) {
|
2021-02-02 13:21:10 +00:00
|
|
|
return ['p-filter-column', this.columnProp(column, 'filterHeaderClass')];
|
2020-03-05 08:59:07 +00:00
|
|
|
},
|
2019-11-18 07:42:32 +00:00
|
|
|
getSortableColumnIcon(column) {
|
|
|
|
let sorted = false;
|
|
|
|
let sortOrder = null;
|
|
|
|
|
|
|
|
if (this.sortMode === 'single') {
|
2021-02-02 13:21:10 +00:00
|
|
|
sorted = this.sortField && (this.sortField === this.columnProp(column, 'field') || this.sortField === this.columnProp(column, 'sortField'));
|
2019-11-18 07:42:32 +00:00
|
|
|
sortOrder = sorted ? this.sortOrder: 0;
|
|
|
|
}
|
|
|
|
else if (this.sortMode === 'multiple') {
|
|
|
|
let metaIndex = this.getMultiSortMetaIndex(column);
|
|
|
|
if (metaIndex > -1) {
|
|
|
|
sorted = true;
|
|
|
|
sortOrder = this.multiSortMeta[metaIndex].order;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return [
|
2019-12-26 11:24:53 +00:00
|
|
|
'p-sortable-column-icon pi pi-fw', {
|
2020-04-17 19:38:11 +00:00
|
|
|
'pi-sort-alt': !sorted,
|
|
|
|
'pi-sort-amount-up-alt': sorted && sortOrder > 0,
|
|
|
|
'pi-sort-amount-down': sorted && sortOrder < 0
|
2019-12-26 11:24:53 +00:00
|
|
|
}
|
2019-11-18 07:42:32 +00:00
|
|
|
];
|
|
|
|
},
|
|
|
|
getMultiSortMetaIndex(column) {
|
|
|
|
let index = -1;
|
|
|
|
|
|
|
|
for (let i = 0; i < this.multiSortMeta.length; i++) {
|
|
|
|
let meta = this.multiSortMeta[i];
|
2021-02-02 13:21:10 +00:00
|
|
|
if (meta.field === this.columnProp(column, 'field') || meta.field === this.columnProp(column, 'sortField')) {
|
2019-11-18 07:42:32 +00:00
|
|
|
index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return index;
|
|
|
|
},
|
|
|
|
onColumnHeaderClick(event, col) {
|
|
|
|
this.$emit('column-click', {originalEvent: event, column: col});
|
|
|
|
},
|
|
|
|
onColumnHeaderMouseDown(event, col) {
|
|
|
|
this.$emit('column-mousedown', {originalEvent: event, column: col});
|
|
|
|
},
|
|
|
|
onColumnHeaderDragStart(event) {
|
|
|
|
this.$emit('column-dragstart', event);
|
|
|
|
},
|
|
|
|
onColumnHeaderDragOver(event) {
|
|
|
|
this.$emit('column-dragover', event);
|
|
|
|
},
|
|
|
|
onColumnHeaderDragLeave(event) {
|
|
|
|
this.$emit('column-dragleave', event);
|
|
|
|
},
|
|
|
|
onColumnHeaderDrop(event) {
|
|
|
|
this.$emit('column-drop', event);
|
|
|
|
},
|
|
|
|
onColumnResizeStart(event) {
|
|
|
|
this.$emit('column-resizestart', event);
|
|
|
|
},
|
|
|
|
onHeaderCheckboxChange(event) {
|
|
|
|
this.$emit('checkbox-change', event);
|
2019-12-26 11:24:53 +00:00
|
|
|
},
|
|
|
|
onColumnKeyDown(event, col) {
|
2019-12-30 18:23:43 +00:00
|
|
|
if (event.which === 13 && event.currentTarget.nodeName === 'TH' && DomHandler.hasClass(event.currentTarget, 'p-sortable-column')) {
|
2019-12-26 11:24:53 +00:00
|
|
|
this.$emit('column-click', {originalEvent: event, column: col});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getAriaSort(column) {
|
2021-02-02 13:21:10 +00:00
|
|
|
if (this.columnProp(column, 'sortable')) {
|
2019-12-26 11:24:53 +00:00
|
|
|
const sortIcon = this.getSortableColumnIcon(column);
|
2020-04-17 19:38:11 +00:00
|
|
|
if (sortIcon[1]['pi-sort-amount-down'])
|
2019-12-26 11:24:53 +00:00
|
|
|
return 'descending';
|
2020-04-17 19:38:11 +00:00
|
|
|
else if (sortIcon[1]['pi-sort-amount-up-alt'])
|
2019-12-26 11:24:53 +00:00
|
|
|
return 'ascending';
|
|
|
|
else
|
|
|
|
return 'none';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return null;
|
|
|
|
}
|
2019-11-18 07:42:32 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
components: {
|
2021-02-06 09:26:12 +00:00
|
|
|
'DTHeaderCheckbox': HeaderCheckbox,
|
|
|
|
'DTColumnFilter': ColumnFilter
|
2019-11-18 07:42:32 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-18 09:53:47 +00:00
|
|
|
</script>
|