primevue
Version:
[](https://opensource.org/licenses/MIT) [](https://badge.fury.io/js/primevue) [ • 73.6 kB
JavaScript
import { DomHandler, ObjectUtils } from 'primevue/utils';
import { FilterService } from 'primevue/api';
import Ripple from 'primevue/ripple';
import { resolveDirective, openBlock, createBlock, withDirectives, createVNode, createCommentVNode, resolveDynamicComponent, toDisplayString, resolveComponent, Fragment, renderList, createTextVNode, renderSlot, createSlots, withCtx } from 'vue';
import Paginator from 'primevue/paginator';
var script = {
name: 'BodyCell',
emits: ['node-toggle','checkbox-toggle'],
props: {
node: {
type: Object,
default: null
},
column: {
type: Object,
default: null
},
level: {
type: Number,
default: 0
},
indentation: {
type: Number,
default: 1
},
leaf: {
type: Boolean,
default: false
},
expanded: {
type: Boolean,
default: false
},
selectionMode: {
type: String,
default: null
},
checked: {
type: Boolean,
default: false
},
partialChecked: {
type: Boolean,
default: false
}
},
data() {
return {
styleObject: {},
checkboxFocused: false
}
},
mounted() {
if (this.columnProp('frozen')) {
this.updateStickyPosition();
}
},
updated() {
if (this.columnProp('frozen')) {
this.updateStickyPosition();
}
},
methods: {
toggle() {
this.$emit('node-toggle', this.node);
},
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 align = this.columnProp('alignFrozen');
if (align === 'right') {
let right = 0;
let next = this.$el.nextElementSibling;
if (next) {
right = DomHandler.getOuterWidth(next) + parseFloat(next.style.right);
}
this.styleObject.right = right + 'px';
}
else {
let left = 0;
let prev = this.$el.previousElementSibling;
if (prev) {
left = DomHandler.getOuterWidth(prev) + parseFloat(prev.style.left);
}
this.styleObject.left = left + 'px';
}
}
},
resolveFieldData(rowData, field) {
return ObjectUtils.resolveFieldData(rowData, field);
},
toggleCheckbox() {
this.$emit('checkbox-toggle');
},
onCheckboxFocus() {
this.checkboxFocused = true;
},
onCheckboxBlur() {
this.checkboxFocused = false;
}
},
computed: {
containerClass() {
return [this.columnProp('bodyClass'), this.columnProp('class'), {
'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];
},
togglerStyle() {
return {
marginLeft: this.level * this.indentation + 'rem',
visibility: this.leaf ? 'hidden' : 'visible'
};
},
togglerIcon() {
return ['p-treetable-toggler-icon pi', {'pi-chevron-right': !this.expanded, 'pi-chevron-down': this.expanded}];
},
checkboxSelectionMode() {
return this.selectionMode === 'checkbox';
},
checkboxClass() {
return ['p-checkbox-box', {'p-highlight': this.checked, 'p-focus': this.checkboxFocused, 'p-indeterminate': this.partialChecked}];
},
checkboxIcon() {
return ['p-checkbox-icon', {'pi pi-check': this.checked, 'pi pi-minus': this.partialChecked}];
}
},
directives: {
'ripple': Ripple
}
};
const _hoisted_1 = { class: "p-hidden-accessible" };
const _hoisted_2 = { key: 3 };
function render(_ctx, _cache, $props, $setup, $data, $options) {
const _directive_ripple = resolveDirective("ripple");
return (openBlock(), createBlock("td", {
style: $options.containerStyle,
class: $options.containerClass
}, [
($options.columnProp('expander'))
? withDirectives((openBlock(), createBlock("button", {
key: 0,
type: "button",
class: "p-treetable-toggler p-link",
onClick: _cache[1] || (_cache[1] = (...args) => ($options.toggle && $options.toggle(...args))),
style: $options.togglerStyle,
tabindex: "-1"
}, [
createVNode("i", { class: $options.togglerIcon }, null, 2)
], 4)), [
[_directive_ripple]
])
: createCommentVNode("", true),
($options.checkboxSelectionMode && $options.columnProp('expander'))
? (openBlock(), createBlock("div", {
key: 1,
class: "p-checkbox p-treetable-checkbox p-component",
onClick: _cache[4] || (_cache[4] = (...args) => ($options.toggleCheckbox && $options.toggleCheckbox(...args))),
role: "checkbox",
"aria-checked": $props.checked
}, [
createVNode("div", _hoisted_1, [
createVNode("input", {
type: "checkbox",
onFocus: _cache[2] || (_cache[2] = (...args) => ($options.onCheckboxFocus && $options.onCheckboxFocus(...args))),
onBlur: _cache[3] || (_cache[3] = (...args) => ($options.onCheckboxBlur && $options.onCheckboxBlur(...args)))
}, null, 32)
]),
createVNode("div", {
ref: "checkboxEl",
class: $options.checkboxClass
}, [
createVNode("span", { class: $options.checkboxIcon }, null, 2)
], 2)
], 8, ["aria-checked"]))
: createCommentVNode("", true),
($props.column.children && $props.column.children.body)
? (openBlock(), createBlock(resolveDynamicComponent($props.column.children.body), {
key: 2,
node: $props.node,
column: $props.column
}, null, 8, ["node", "column"]))
: (openBlock(), createBlock("span", _hoisted_2, toDisplayString($options.resolveFieldData($props.node.data, $options.columnProp('field'))), 1))
], 6))
}
script.render = render;
var script$1 = {
name: 'TreeTableRow',
emits: ['node-click', 'node-toggle', 'checkbox-change','nodeClick', 'nodeToggle', 'checkboxChange'],
props: {
node: {
type: null,
default: null
},
parentNode: {
type: null,
default: null
},
columns: {
type: null,
default: null
},
expandedKeys: {
type: null,
default: null
},
selectionKeys: {
type: null,
default: null
},
selectionMode: {
type: String,
default: null
},
level: {
type: Number,
default: 0
},
indentation: {
type: Number,
default: 1
}
},
nodeTouched: false,
methods: {
columnProp(col, prop) {
return col.props ? ((col.type.props[prop].type === Boolean && col.props[prop] === '') ? true : col.props[prop]) : null;
},
toggle() {
this.$emit('node-toggle', this.node);
},
onClick(event) {
if (DomHandler.isClickable(event.target) ||
DomHandler.hasClass(event.target, 'p-treetable-toggler') || DomHandler.hasClass(event.target.parentElement, 'p-treetable-toggler')) {
return;
}
this.$emit('node-click', {
originalEvent: event,
nodeTouched: this.nodeTouched,
node: this.node
});
this.nodeTouched = false;
},
onTouchEnd() {
this.nodeTouched = true;
},
onKeyDown(event) {
if (event.target === this.$el) {
const rowElement = this.$el;
switch (event.which) {
//down arrow
case 40: {
const nextRow = rowElement.nextElementSibling;
if (nextRow) {
nextRow.focus();
}
event.preventDefault();
break;
}
//up arrow
case 38: {
const previousRow = rowElement.previousElementSibling;
if (previousRow) {
previousRow.focus();
}
event.preventDefault();
break;
}
//right-left arrows
case 37:
case 39: {
if (!this.leaf) {
this.$emit('node-toggle', this.node);
event.preventDefault();
}
break;
}
//enter
case 13: {
this.onClick(event);
event.preventDefault();
break;
}
}
}
},
toggleCheckbox() {
let _selectionKeys = this.selectionKeys ? {...this.selectionKeys} : {};
const _check = !this.checked;
this.propagateDown(this.node, _check, _selectionKeys);
this.$emit('checkbox-change', {
node: this.node,
check: _check,
selectionKeys: _selectionKeys
});
},
propagateDown(node, check, selectionKeys) {
if (check)
selectionKeys[node.key] = {checked: true, partialChecked: false};
else
delete selectionKeys[node.key];
if (node.children && node.children.length) {
for (let child of node.children) {
this.propagateDown(child, check, selectionKeys);
}
}
},
propagateUp(event) {
let check = event.check;
let _selectionKeys = {...event.selectionKeys};
let checkedChildCount = 0;
let childPartialSelected = false;
for(let child of this.node.children) {
if(_selectionKeys[child.key] && _selectionKeys[child.key].checked)
checkedChildCount++;
else if(_selectionKeys[child.key] && _selectionKeys[child.key].partialChecked)
childPartialSelected = true;
}
if(check && checkedChildCount === this.node.children.length) {
_selectionKeys[this.node.key] = {checked: true, partialChecked: false};
}
else {
if (!check) {
delete _selectionKeys[this.node.key];
}
if(childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length))
_selectionKeys[this.node.key] = {checked: false, partialChecked: true};
else
_selectionKeys[this.node.key] = {checked: false, partialChecked: false};
}
this.$emit('checkbox-change', {
node: event.node,
check: event.check,
selectionKeys: _selectionKeys
});
},
onCheckboxChange(event) {
let check = event.check;
let _selectionKeys = {...event.selectionKeys};
let checkedChildCount = 0;
let childPartialSelected = false;
for(let child of this.node.children) {
if(_selectionKeys[child.key] && _selectionKeys[child.key].checked)
checkedChildCount++;
else if(_selectionKeys[child.key] && _selectionKeys[child.key].partialChecked)
childPartialSelected = true;
}
if(check && checkedChildCount === this.node.children.length) {
_selectionKeys[this.node.key] = {checked: true, partialChecked: false};
}
else {
if (!check) {
delete _selectionKeys[this.node.key];
}
if(childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length))
_selectionKeys[this.node.key] = {checked: false, partialChecked: true};
else
_selectionKeys[this.node.key] = {checked: false, partialChecked: false};
}
this.$emit('checkbox-change', {
node: event.node,
check: event.check,
selectionKeys: _selectionKeys
});
}
},
computed: {
containerClass() {
return [this.node.styleClass, {
'p-highlight': this.selected
}]
},
hasChildren() {
return this.node.children && this.node.children.length > 0;
},
expanded() {
return this.expandedKeys && this.expandedKeys[this.node.key] === true;
},
leaf() {
return this.node.leaf === false ? false : !(this.node.children && this.node.children.length);
},
selected() {
return (this.selectionMode && this.selectionKeys) ? this.selectionKeys[this.node.key] === true : false;
},
childLevel() {
return this.level + 1;
},
checked() {
return this.selectionKeys ? this.selectionKeys[this.node.key] && this.selectionKeys[this.node.key].checked: false;
},
partialChecked() {
return this.selectionKeys ? this.selectionKeys[this.node.key] && this.selectionKeys[this.node.key].partialChecked: false;
}
},
components: {
'TTBodyCell': script
}
};
function render$1(_ctx, _cache, $props, $setup, $data, $options) {
const _component_TTBodyCell = resolveComponent("TTBodyCell");
const _component_TreeTableRow = resolveComponent("TreeTableRow", true);
return (openBlock(), createBlock(Fragment, null, [
createVNode("tr", {
class: $options.containerClass,
onClick: _cache[2] || (_cache[2] = (...args) => ($options.onClick && $options.onClick(...args))),
onKeydown: _cache[3] || (_cache[3] = (...args) => ($options.onKeyDown && $options.onKeyDown(...args))),
onTouchend: _cache[4] || (_cache[4] = (...args) => ($options.onTouchEnd && $options.onTouchEnd(...args))),
style: $props.node.style,
tabindex: "0"
}, [
(openBlock(true), createBlock(Fragment, null, renderList($props.columns, (col, i) => {
return (openBlock(), createBlock(Fragment, {
key: $options.columnProp(col, 'columnKey')||$options.columnProp(col, 'field')||i
}, [
(!$options.columnProp(col, 'hidden'))
? (openBlock(), createBlock(_component_TTBodyCell, {
key: 0,
column: col,
node: $props.node,
level: $props.level,
leaf: $options.leaf,
indentation: $props.indentation,
expanded: $options.expanded,
selectionMode: $props.selectionMode,
checked: $options.checked,
partialChecked: $options.partialChecked,
onNodeToggle: _cache[1] || (_cache[1] = $event => (_ctx.$emit('node-toggle', $event))),
onCheckboxToggle: $options.toggleCheckbox
}, null, 8, ["column", "node", "level", "leaf", "indentation", "expanded", "selectionMode", "checked", "partialChecked", "onCheckboxToggle"]))
: createCommentVNode("", true)
], 64))
}), 128))
], 38),
($options.expanded && $props.node.children && $props.node.children.length)
? (openBlock(true), createBlock(Fragment, { key: 0 }, renderList($props.node.children, (childNode) => {
return (openBlock(), createBlock(_component_TreeTableRow, {
key: childNode.key,
columns: $props.columns,
node: childNode,
parentNode: $props.node,
level: $props.level + 1,
expandedKeys: $props.expandedKeys,
selectionMode: $props.selectionMode,
selectionKeys: $props.selectionKeys,
indentation: $props.indentation,
onNodeToggle: _cache[5] || (_cache[5] = $event => (_ctx.$emit('node-toggle', $event))),
onNodeClick: _cache[6] || (_cache[6] = $event => (_ctx.$emit('node-click', $event))),
onCheckboxChange: $options.onCheckboxChange
}, null, 8, ["columns", "node", "parentNode", "level", "expandedKeys", "selectionMode", "selectionKeys", "indentation", "onCheckboxChange"]))
}), 128))
: createCommentVNode("", true)
], 64))
}
script$1.render = render$1;
var script$2 = {
name: 'HeaderCell',
emits: ['column-click','column-resizestart'],
props: {
column: {
type: Object,
default: null
},
resizableColumns: {
type: Boolean,
default: false
},
sortField: {
type: [String, Function],
default: null
},
sortOrder: {
type: Number,
default: null
},
multiSortMeta: {
type: Array,
default: null
},
sortMode: {
type: String,
default: 'single'
}
},
data() {
return {
styleObject: {}
}
},
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 align = this.columnProp('alignFrozen');
if (align === 'right') {
let right = 0;
let next = this.$el.nextElementSibling;
if (next) {
right = DomHandler.getOuterWidth(next) + parseFloat(next.style.right);
}
this.styleObject.right = right + 'px';
}
else {
let left = 0;
let prev = this.$el.previousElementSibling;
if (prev) {
left = DomHandler.getOuterWidth(prev) + parseFloat(prev.style.left);
}
this.styleObject.left = left + 'px';
}
let filterRow = this.$el.parentElement.nextElementSibling;
if (filterRow) {
let index = DomHandler.index(this.$el);
filterRow.children[index].style.left = this.styleObject.left;
filterRow.children[index].style.right = this.styleObject.right;
}
}
},
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});
}
},
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();
}
},
computed: {
containerClass() {
return [this.columnProp('headerClass'), this.columnProp('class'), {
'p-sortable-column': this.columnProp('sortable'),
'p-resizable-column': this.resizableColumns,
'p-highlight': this.isColumnSorted(),
'p-frozen-column': this.columnProp('frozen')
}];
},
containerStyle() {
let headerStyle = 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.sortableColumnIcon;
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;
}
},
}
};
const _hoisted_1$1 = {
key: 2,
class: "p-column-title"
};
const _hoisted_2$1 = {
key: 4,
class: "p-sortable-column-badge"
};
function render$2(_ctx, _cache, $props, $setup, $data, $options) {
return (openBlock(), createBlock("th", {
style: [$options.containerStyle],
class: $options.containerClass,
onClick: _cache[2] || (_cache[2] = (...args) => ($options.onClick && $options.onClick(...args))),
onKeydown: _cache[3] || (_cache[3] = (...args) => ($options.onKeyDown && $options.onKeyDown(...args))),
tabindex: $options.columnProp('sortable') ? '0' : null,
"aria-sort": $options.ariaSort
}, [
($props.resizableColumns && !$options.columnProp('frozen'))
? (openBlock(), createBlock("span", {
key: 0,
class: "p-column-resizer",
onMousedown: _cache[1] || (_cache[1] = (...args) => ($options.onResizeStart && $options.onResizeStart(...args)))
}, null, 32))
: createCommentVNode("", true),
($props.column.children && $props.column.children.header)
? (openBlock(), createBlock(resolveDynamicComponent($props.column.children.header), {
key: 1,
column: $props.column
}, null, 8, ["column"]))
: createCommentVNode("", true),
($options.columnProp('header'))
? (openBlock(), createBlock("span", _hoisted_1$1, toDisplayString($options.columnProp('header')), 1))
: createCommentVNode("", true),
($options.columnProp('sortable'))
? (openBlock(), createBlock("span", {
key: 3,
class: $options.sortableColumnIcon
}, null, 2))
: createCommentVNode("", true),
($options.isMultiSorted())
? (openBlock(), createBlock("span", _hoisted_2$1, toDisplayString($options.getMultiSortMetaIndex() + 1), 1))
: createCommentVNode("", true)
], 46, ["tabindex", "aria-sort"]))
}
script$2.render = render$2;
var script$3 = {
name: 'FooterCell',
props: {
column: {
type: Object,
default: null
}
},
data() {
return {
styleObject: {}
}
},
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 align = this.columnProp('alignFrozen');
if (align === 'right') {
let right = 0;
let next = this.$el.nextElementSibling;
if (next) {
right = DomHandler.getOuterWidth(next) + parseFloat(next.style.right);
}
this.styleObject.right = right + 'px';
}
else {
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];
}
}
};
function render$3(_ctx, _cache, $props, $setup, $data, $options) {
return (openBlock(), createBlock("td", {
style: $options.containerStyle,
class: $options.containerClass
}, [
($props.column.children && $props.column.children.footer)
? (openBlock(), createBlock(resolveDynamicComponent($props.column.children.footer), {
key: 0,
column: _ctx.col
}, null, 8, ["column"]))
: createCommentVNode("", true),
createTextVNode(" " + toDisplayString($options.columnProp('footer')), 1)
], 6))
}
script$3.render = render$3;
var script$4 = {
name: 'TreeTable',
emits: ['node-expand', 'node-collapse', 'update:expandedKeys', 'update:selectionKeys', 'node-select', 'node-unselect',
'update:first', 'update:rows', 'page', 'update:sortField', 'update:sortOrder', 'update:multiSortMeta', 'sort', 'filter', 'column-resize-end'],
props: {
value: {
type: null,
default: null
},
expandedKeys: {
type: null,
default: null
},
selectionKeys: {
type: null,
default: null
},
selectionMode: {
type: String,
default: null
},
metaKeySelection: {
type: Boolean,
default: true
},
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
},
loading: {
type: Boolean,
default: false
},
loadingIcon: {
type: String,
default: 'pi pi-spinner'
},
rowHover: {
type: Boolean,
default: false
},
autoLayout: {
type: Boolean,
default: false
},
sortField: {
type: [String, Function],
default: null
},
sortOrder: {
type: Number,
default: null
},
defaultSortOrder: {
type: Number,
default: 1
},
multiSortMeta: {
type: Array,
default: null
},
sortMode: {
type: String,
default: 'single'
},
removableSort: {
type: Boolean,
default: false
},
filters: {
type: Object,
default: null
},
filterMode: {
type: String,
default: 'lenient'
},
filterLocale: {
type: String,
default: undefined
},
resizableColumns: {
type: Boolean,
default: false
},
columnResizeMode: {
type: String,
default: 'fit'
},
indentation: {
type: Number,
default: 1
},
showGridlines: {
type: Boolean,
default: false
},
scrollable: {
type: Boolean,
default: false
},
scrollDirection: {
type: String,
default: "vertical"
},
scrollHeight: {
type: String,
default: null
},
responsiveLayout: {
type: String,
default: null
}
},
documentColumnResizeListener: null,
documentColumnResizeEndListener: null,
lastResizeHelperX: null,
resizeColumnElement: null,
data() {
return {
d_expandedKeys: this.expandedKeys || {},
d_first: this.first,
d_rows: this.rows,
d_sortField: this.sortField,
d_sortOrder: this.sortOrder,
d_multiSortMeta: this.multiSortMeta ? [...this.multiSortMeta] : [],
}
},
watch: {
expandedKeys(newValue) {
this.d_expandedKeys = newValue;
},
first(newValue) {
this.d_first = newValue;
},
rows(newValue) {
this.d_rows = newValue;
},
sortField(newValue) {
this.d_sortField = newValue;
},
sortOrder(newValue) {
this.d_sortOrder = newValue;
},
multiSortMeta(newValue) {
this.d_multiSortMeta = newValue;
}
},
mounted() {
if (this.scrollable && this.scrollDirection !== 'vertical') {
this.updateScrollWidth();
}
},
updated() {
if (this.scrollable && this.scrollDirection !== 'vertical') {
this.updateScrollWidth();
}
},
methods: {
columnProp(col, prop) {
return col.props ? ((col.type.props[prop].type === Boolean && col.props[prop] === '') ? true : col.props[prop]) : null;
},
onNodeToggle(node) {
const key = node.key;
if (this.d_expandedKeys[key]) {
delete this.d_expandedKeys[key];
this.$emit('node-collapse', node);
}
else {
this.d_expandedKeys[key] = true;
this.$emit('node-expand', node);
}
this.d_expandedKeys = {...this.d_expandedKeys};
this.$emit('update:expandedKeys', this.d_expandedKeys);
},
onNodeClick(event) {
if (this.rowSelectionMode && event.node.selectable !== false) {
const metaSelection = event.nodeTouched ? false : this.metaKeySelection;
const _selectionKeys = metaSelection ? this.handleSelectionWithMetaKey(event) : this.handleSelectionWithoutMetaKey(event);
this.$emit('update:selectionKeys', _selectionKeys);
}
},
handleSelectionWithMetaKey(event) {
const originalEvent = event.originalEvent;
const node = event.node;
const metaKey = (originalEvent.metaKey||originalEvent.ctrlKey);
const selected = this.isNodeSelected(node);
let _selectionKeys;
if (selected && metaKey) {
if (this.isSingleSelectionMode()) {
_selectionKeys = {};
}
else {
_selectionKeys = {...this.selectionKeys};
delete _selectionKeys[node.key];
}
this.$emit('node-unselect', node);
}
else {
if (this.isSingleSelectionMode()) {
_selectionKeys = {};
}
else if (this.isMultipleSelectionMode()) {
_selectionKeys = !metaKey ? {} : (this.selectionKeys ? {...this.selectionKeys} : {});
}
_selectionKeys[node.key] = true;
this.$emit('node-select', node);
}
return _selectionKeys;
},
handleSelectionWithoutMetaKey(event) {
const node = event.node;
const selected = this.isNodeSelected(node);
let _selectionKeys;
if (this.isSingleSelectionMode()) {
if (selected) {
_selectionKeys = {};
this.$emit('node-unselect', node);
}
else {
_selectionKeys = {};
_selectionKeys[node.key] = true;
this.$emit('node-select', node);
}
}
else {
if (selected) {
_selectionKeys = {...this.selectionKeys};
delete _selectionKeys[node.key];
this.$emit('node-unselect', node);
}
else {
_selectionKeys = this.selectionKeys ? {...this.selectionKeys} : {};
_selectionKeys[node.key] = true;
this.$emit('node-select', node);
}
}
return _selectionKeys;
},
onCheckboxChange(event) {
this.$emit('update:selectionKeys', event.selectionKeys);
if (event.check)
this.$emit('node-select', event.node);
else
this.$emit('node-unselect', event.node);
},
isSingleSelectionMode() {
return this.selectionMode === 'single';
},
isMultipleSelectionMode() {
return this.selectionMode === 'multiple';
},
onPage(event) {
this.d_first = event.first;
this.d_rows = event.rows;
let pageEvent = this.createLazyLoadEvent(event);
pageEvent.pageCount = event.pageCount;
pageEvent.page = event.page;
this.$emit('update:first', this.d_first);
this.$emit('update:rows', this.d_rows);
this.$emit('page', pageEvent);
},
resetPage() {
this.d_first = 0;
this.$emit('update:first', this.d_first);
},
getFilterColumnHeaderClass(column) {
return ['p-filter-column', this.columnProp(column, 'filterHeaderClass'), {
'p-frozen-column': this.columnProp(column, 'frozen')
}];
},
onColumnHeaderClick(e) {
let event = e.originalEvent;
let column = e.column;
if (this.columnProp(column, 'sortable')) {
const targetNode = event.target;
const columnField = this.columnProp(column, 'sortField') || this.columnProp(column, 'field');
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();
if (this.sortMode === 'single') {
if (this.d_sortField === columnField) {
if (this.removableSort && (this.d_sortOrder * -1 === this.defaultSortOrder)) {
this.d_sortOrder = null;
this.d_sortField = null;
}
else {
this.d_sortOrder = this.d_sortOrder * -1;
}
}
else {
this.d_sortOrder = this.defaultSortOrder;
this.d_sortField = columnField;
}
this.$emit('update:sortField', this.d_sortField);
this.$emit('update:sortOrder', this.d_sortOrder);
this.resetPage();
}
else if (this.sortMode === 'multiple') {
let metaKey = event.metaKey || event.ctrlKey;
if (!metaKey) {
this.d_multiSortMeta = this.d_multiSortMeta.filter(meta => meta.field === columnField);
}
this.addMultiSortField(columnField);
this.$emit('update:multiSortMeta', this.d_multiSortMeta);
}
this.$emit('sort', this.createLazyLoadEvent(event));
}
}
},
addMultiSortField(field) {
let index = this.d_multiSortMeta.findIndex(meta => meta.field === field);
if (index >= 0) {
if (this.removableSort && (this.d_multiSortMeta[index].order * -1 === this.defaultSortOrder))
this.d_multiSortMeta.splice(index, 1);
else
this.d_multiSortMeta[index] = {field: field, order: this.d_multiSortMeta[index].order * -1};
}
else {
this.d_multiSortMeta.push({field: field, order: this.defaultSortOrder});
}
this.d_multiSortMeta = [...this.d_multiSortMeta];
},
sortSingle(nodes) {
return this.sortNodesSingle(nodes);
},
sortNodesSingle(nodes) {
let _nodes = [...nodes];
_nodes.sort((node1, node2) => {
const value1 = ObjectUtils.resolveFieldData(node1.data, this.d_sortField);
const value2 = ObjectUtils.resolveFieldData(node2.data, 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;
return (this.d_sortOrder * result);
});
return _nodes;
},
sortMultiple(nodes) {
return this.sortNodesMultiple(nodes);
},
sortNodesMultiple(nodes) {
let _nodes = [...nodes];
_nodes.sort((node1, node2) => {
return this.multisortField(node1, node2, 0);
});
return _nodes;
},
multisortField(node1, node2, index) {
const value1 = ObjectUtils.resolveFieldData(node1.data, this.d_multiSortMeta[index].field);
const value2 = ObjectUtils.resolveFieldData(node2.data, this.d_multiSortMeta[index].field);
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 (value1 === value2) {
return (this.d_multiSortMeta.length - 1) > (index) ? (this.multisortField(node1, node2, index + 1)) : 0;
}
else {
if ((typeof value1 === 'string' || value1 instanceof String) && (typeof value2 === 'string' || value2 instanceof String))
return (this.d_multiSortMeta[index].order * value1.localeCompare(value2, undefined, { numeric: true }));
else
result = (value1 < value2) ? -1 : 1;
}
}
return (this.d_multiSortMeta[index].order * result);
},
filter(value) {
let filteredNodes = [];
const strict = this.filterMode === 'strict';
for (let node of value) {
let copyNode = {...node};
let localMatch = true;
let globalMatch = false;
for (let j = 0; j < this.columns.length; j++) {
let col = this.columns[j];
let filterField = this.columnProp(col, 'field');
//local
if (Object.prototype.hasOwnProperty.call(this.filters, this.columnProp(col, 'field'))) {
let filterMatchMode = this.columnProp(col, 'filterMatchMode') || 'startsWith';
let filterValue = this.filters[this.columnProp(col, 'field')];
let filterConstraint = FilterService.filters[filterMatchMode];
let paramsWithoutNode = {filterField, filterValue, filterConstraint, strict};
if ((strict && !(this.findFilteredNodes(copyNode, paramsWithoutNode) || this.isFilterMatched(copyNode, paramsWithoutNode))) ||
(!strict && !(this.isFilterMatched(copyNode, paramsWithoutNode) || this.findFilteredNodes(copyNode, paramsWithoutNode)))) {
localMatch = false;
}
if (!localMatch) {
break;
}
}
//global
if (this.hasGlobalFilter() && !globalMatch) {
let copyNodeForGlobal = {...copyNode};
let filterValue = this.filters['global'];
let filterConstraint = FilterService.filters['contains'];
let globalFilterParamsWithoutNode = {filterField, filterValue, filterConstraint, strict};
if ((strict && (this.findFilteredNodes(copyNodeForGlobal, globalFilterParamsWithoutNode) || this.isFilterMatched(copyNodeForGlobal, globalFilterParamsWithoutNode))) ||
(!strict && (this.isFilterMatched(copyNodeForGlobal, globalFilterParamsWithoutNode) || this.findFilteredNodes(copyNodeForGlobal, globalFilterParamsWithoutNode)))) {
globalMatch = true;
copyNode = copyNodeForGlobal;
}
}
}
let matches = localMatch;
if (this.hasGlobalFilter()) {
matches = localMatch && globalMatch;
}
if (matches) {
filteredNodes.push(copyNode);
}
}
let filterEvent = this.createLazyLoadEvent(event);
filterEvent.filteredValue = filteredNodes;
this.$emit('filter', filterEvent);
return filteredNodes;
},
findFilteredNodes(node, paramsWithoutNode) {
if (node) {
let matched = false;
if (node.children) {
let childNodes = [...node.children];
node.children = [];
for (let childNode of childNodes) {
let copyChildNode = {...childNode};
if (this.isFilterMatched(copyChildNode, paramsWithoutNode)) {
matched = true;
node.children.push(copyChildNode);
}
}
}
if (matched) {
return true;
}
}
},
isFilterMatched(node, {filterField, filterValue, filterConstraint, strict}) {
let matched = false;
let dataFieldValue = ObjectUtils.resolveFieldData(node.data, filterField);
if (filterConstraint(dataFieldValue, filterValue, this.filterLocale)) {
matched = true;
}
if (!matched || (strict && !this.isNodeLeaf(node))) {
matched = this.findFilteredNodes(node, {filterField, filterValue, filterConstraint, strict}) || matched;
}
return matched;
},
isNodeSelected(node) {
return (this.selectionMode && this.selectionKeys) ? this.selectionKeys[node.key] === true : false;
},
isNodeLeaf(node) {
return node.leaf === false ? false : !(node.children && node.children.length);
},
createLazyLoadEvent(event) {
let filterMatchModes;
if (this.hasFilters()) {
filterMatchModes = {};
this.columns.forEach(col => {
if (this.columnProp(col, 'field')) {
filterMatchModes[col.props.field] = this.columnProp(col, 'filterMatchMode');
}
});
}
return {
originalEvent: event,
first: this.d_first,
rows: this.d_rows,
sortField: this.d_sortField,
sortOrder: this.d_sortOrder,
multiSortMeta: this.d_multiSortMeta,
filters: this.filters,
filterMatchModes: filterMatchModes
};
},
onColumnResizeStart(event) {
let containerLeft = DomHandler.getOffset(this.$el).left;
this.resizeColumnElement = event.target.parentElement;
this.columnResizing = true;
this.lastResizeHelperX = (event.pageX - containerLeft + this.$el.scrollLeft);
this.bindColumnResizeEvents();
},
onColumnResize(event) {
let containerLeft = DomHandler.getOffset(this.$el).left;
DomHandler.addClass(this.$el, 'p-unselectable-text');
this.$refs.resizeHelper.style.height = this.$el.offsetHeight + 'px';
this.$refs.resizeHelper.style.top = 0 + 'px';
this.$refs.resizeHelper.style.left = (event.pageX - containerLeft + this.$el.scrollLeft) + 'px';
this.$refs.resizeHelper.style.display = 'block';
},
onColumnResizeEnd() {
let delta = this.$refs.resizeHelper.offsetLeft - this.lastResizeHelperX;
let columnWidth = this.resizeColumnElement.offsetWidth;
let newColumnWidth = columnWidth + delta;
let minWidth = this.resizeColumnElement.style.minWidth||15;
if (columnWidth + delta > parseInt(minWidth, 10)) {
if (this.columnResizeMode === 'fit') {
let nextColumn = this.resizeColumnElement.nextElementSibling;
let nextColumnWidth = nextColumn.offsetWidth - delta;
if (newColumnWidth > 15 && nextColumnWidth > 15) {
if (!this.scrollable) {
this.resizeColumnElement.style.wi