Initated datatable migration

pull/496/head
Cagatay Civici 2020-09-23 20:55:00 +03:00
parent 6aeefbce5a
commit 2efaa699c7
13 changed files with 160 additions and 288 deletions

View File

@ -1,9 +1,3 @@
<template>
<div>
<slot></slot>
</div>
</template>
<script> <script>
export default { export default {
name: 'columngroup', name: 'columngroup',
@ -13,18 +7,8 @@ export default {
default: null default: null
} }
}, },
data() { render() {
return { return null;
children: null
};
},
mounted() {
this.children = this.$children;
},
computed: {
rows() {
return this.children;
}
} }
} }
</script> </script>

View File

@ -1,20 +1,20 @@
<template> <template>
<td :style="column.bodyStyle" :class="containerClass" @click="onClick" @keydown="onKeyDown"> <td :style="column.props.bodyStyle" :class="containerClass" @click="onClick" @keydown="onKeyDown">
<ColumnSlot :data="rowData" :column="column" :index="index" type="body" v-if="column.$scopedSlots.body && !d_editing" /> <component :is="column.children.body" :data="rowData" :column="column" :index="index" v-if="column.children && column.children.body && !d_editing" />
<ColumnSlot :data="rowData" :column="column" :index="index" type="editor" v-else-if="column.$scopedSlots.editor && d_editing" /> <component :is="column.children.editor" :data="rowData" :column="column" :index="index" v-else-if="column.children && column.children.editor && d_editing" />
<template v-else-if="column.selectionMode"> <template v-else-if="column.props.selectionMode">
<DTRadioButton :value="rowData" :checked="selected" @change="toggleRowWithRadio" v-if="column.selectionMode === 'single'" /> <DTRadioButton :value="rowData" :checked="selected" @change="toggleRowWithRadio" v-if="column.props.selectionMode === 'single'" />
<DTCheckbox :value="rowData" :checked="selected" @change="toggleRowWithCheckbox" v-else-if="column.selectionMode ==='multiple'" /> <DTCheckbox :value="rowData" :checked="selected" @change="toggleRowWithCheckbox" v-else-if="column.props.selectionMode ==='multiple'" />
</template> </template>
<template v-else-if="column.rowReorder"> <template v-else-if="column.props.rowReorder">
<i :class="['p-datatable-reorderablerow-handle', column.rowReorderIcon]"></i> <i :class="['p-datatable-reorderablerow-handle', column.props.rowReorderIcon]"></i>
</template> </template>
<template v-else-if="column.expander"> <template v-else-if="column.props.expander">
<button class="p-row-toggler p-link" @click="toggleRow" type="button" v-ripple> <button class="p-row-toggler p-link" @click="toggleRow" type="button" v-ripple>
<span :class="rowTogglerIcon"></span> <span :class="rowTogglerIcon"></span>
</button> </button>
</template> </template>
<template v-else-if="editMode === 'row' && column.rowEditor"> <template v-else-if="editMode === 'row' && column.props.rowEditor">
<button class="p-row-editor-init p-link" v-if="!d_editing" @click="onRowEditInit" type="button" v-ripple> <button class="p-row-editor-init p-link" v-if="!d_editing" @click="onRowEditInit" type="button" v-ripple>
<span class="p-row-editor-init-icon pi pi-fw pi-pencil"></span> <span class="p-row-editor-init-icon pi pi-fw pi-pencil"></span>
</button> </button>
@ -32,7 +32,6 @@
<script> <script>
import DomHandler from '../utils/DomHandler'; import DomHandler from '../utils/DomHandler';
import ObjectUtils from '../utils/ObjectUtils'; import ObjectUtils from '../utils/ObjectUtils';
import ColumnSlot from './ColumnSlot.vue';
import RowRadioButton from './RowRadioButton'; import RowRadioButton from './RowRadioButton';
import RowCheckbox from './RowCheckbox.vue'; import RowCheckbox from './RowCheckbox.vue';
import Ripple from '../ripple/Ripple'; import Ripple from '../ripple/Ripple';
@ -91,7 +90,7 @@ export default {
}, },
methods: { methods: {
resolveFieldData() { resolveFieldData() {
return ObjectUtils.resolveFieldData(this.rowData, this.column.field); return ObjectUtils.resolveFieldData(this.rowData, this.column.props.field);
}, },
toggleRow(event) { toggleRow(event) {
this.$emit('row-toggle', { this.$emit('row-toggle', {
@ -106,7 +105,7 @@ export default {
this.$emit('checkbox-change', event); this.$emit('checkbox-change', event);
}, },
isEditable() { isEditable() {
return this.column.$scopedSlots.editor != null; return this.column.children && this.column.children.editor != null;
}, },
bindDocumentEditListener() { bindDocumentEditListener() {
if (!this.documentEditListener) { if (!this.documentEditListener) {
@ -136,14 +135,14 @@ export default {
if (this.editMode === 'cell' && this.isEditable() && !this.d_editing) { if (this.editMode === 'cell' && this.isEditable() && !this.d_editing) {
this.d_editing = true; this.d_editing = true;
this.bindDocumentEditListener(); this.bindDocumentEditListener();
this.$emit('cell-edit-init', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index}); this.$emit('cell-edit-init', {originalEvent: event, data: this.rowData, field: this.column.props.field, index: this.index});
} }
}, },
completeEdit(event, type) { completeEdit(event, type) {
let completeEvent = { let completeEvent = {
originalEvent: event, originalEvent: event,
data: this.rowData, data: this.rowData,
field: this.column.field, field: this.column.props.field,
index: this.index, index: this.index,
type: type, type: type,
defaultPrevented: false, defaultPrevented: false,
@ -167,7 +166,7 @@ export default {
case 27: case 27:
this.switchCellToViewMode(); this.switchCellToViewMode();
this.$emit('cell-edit-cancel', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index}); this.$emit('cell-edit-cancel', {originalEvent: event, data: this.rowData, field: this.column.props.field, index: this.index});
break; break;
case 9: case 9:
@ -256,26 +255,25 @@ export default {
return (DomHandler.find(this.$el, '.p-invalid').length === 0); return (DomHandler.find(this.$el, '.p-invalid').length === 0);
}, },
onRowEditInit(event) { onRowEditInit(event) {
this.$emit('row-edit-init', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index}); this.$emit('row-edit-init', {originalEvent: event, data: this.rowData, field: this.column.props.field, index: this.index});
}, },
onRowEditSave(event) { onRowEditSave(event) {
this.$emit('row-edit-save', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index}); this.$emit('row-edit-save', {originalEvent: event, data: this.rowData, field: this.column.props.field, index: this.index});
}, },
onRowEditCancel(event) { onRowEditCancel(event) {
this.$emit('row-edit-cancel', {originalEvent: event, data: this.rowData, field: this.column.field, index: this.index}); this.$emit('row-edit-cancel', {originalEvent: event, data: this.rowData, field: this.column.props.field, index: this.index});
} }
}, },
computed: { computed: {
containerClass() { containerClass() {
return [this.column.bodyClass, { return [this.column.props.bodyClass, {
'p-selection-column': this.column.selectionMode != null, 'p-selection-column': this.column.props.selectionMode != null,
'p-editable-column': this.isEditable(), 'p-editable-column': this.isEditable(),
'p-cell-editing': this.d_editing 'p-cell-editing': this.d_editing
}]; }];
} }
}, },
components: { components: {
'ColumnSlot': ColumnSlot,
'DTRadioButton': RowRadioButton, 'DTRadioButton': RowRadioButton,
'DTCheckbox': RowCheckbox 'DTCheckbox': RowCheckbox
}, },

View File

@ -1,31 +0,0 @@
<script>
export default {
functional: true,
props: {
column: {
type: null,
default: null
},
data: {
type: null,
default: null
},
index: {
type: Number,
default: null
},
type: {
type: String,
default: null
}
},
render(createElement, context) {
const content = context.props.column.$scopedSlots[context.props.type]({
'data': context.props.data,
'index': context.props.index,
'column': context.props.column
});
return [content];
}
}
</script>

View File

@ -364,7 +364,6 @@ export default {
}, },
data() { data() {
return { return {
allChildren: null,
d_first: this.first, d_first: this.first,
d_rows: this.rows, d_rows: this.rows,
d_sortField: this.sortField, d_sortField: this.sortField,
@ -432,13 +431,12 @@ export default {
} }
}, },
mounted() { mounted() {
this.allChildren = this.$children;
if (this.reorderableColumns) { if (this.reorderableColumns) {
let columnOrder = []; let columnOrder = [];
for (let child of this.allChildren) { const children = this.$slots.default();
if (child.$options._propKeys.indexOf('columnKey') !== -1) { for (let child of children) {
columnOrder.push(child.columnKey||child.field); if (child.type.name === 'column') {
columnOrder.push(child.props.columnKey||child.props.field);
} }
} }
this.d_columnOrder = columnOrder; this.d_columnOrder = columnOrder;
@ -474,9 +472,9 @@ export default {
const event = e.originalEvent; const event = e.originalEvent;
const column = e.column; const column = e.column;
if (column.sortable) { if (column.props.sortable) {
const targetNode = event.target; const targetNode = event.target;
const columnField = column.sortField || column.field; const columnField = column.props.sortField || column.props.field;
if (DomHandler.hasClass(targetNode, 'p-sortable-column') || DomHandler.hasClass(targetNode, 'p-column-title') 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.hasClass(targetNode, 'p-sortable-column-icon') || DomHandler.hasClass(targetNode.parentElement, 'p-sortable-column-icon')) {
@ -1636,7 +1634,7 @@ export default {
filters: this.filters, filters: this.filters,
filterMatchModes: filterMatchModes filterMatchModes: filterMatchModes
}; };
} },
}, },
computed: { computed: {
containerClass() { containerClass() {
@ -1653,10 +1651,7 @@ export default {
]; ];
}, },
columns() { columns() {
let columns = []; let columns = this.$slots.default().filter(child => child.type.name === 'column');
if (this.allChildren) {
columns = this.allChildren.filter(child => child.$options._propKeys.indexOf('columnKey') !== -1);
if (this.reorderableColumns && this.d_columnOrder) { if (this.reorderableColumns && this.d_columnOrder) {
let orderedColumns = []; let orderedColumns = [];
@ -1671,7 +1666,7 @@ export default {
return orderedColumns.indexOf(item) < 0; return orderedColumns.indexOf(item) < 0;
})]; })];
} }
}
return columns; return columns;
}, },
frozenColumns() { frozenColumns() {
@ -1702,46 +1697,42 @@ export default {
return this.frozenColumns.length > 0; return this.frozenColumns.length > 0;
}, },
headerColumnGroup() { headerColumnGroup() {
if (this.allChildren) { const children = this.$slots.default();
for (let child of this.allChildren) { for (let child of children) {
if (child.$vnode.tag.indexOf('columngroup') !== -1 && child.type === 'header') { if (child.type.name === 'columngroup' && child.props.type === 'header') {
return child; return child;
} }
} }
}
return null; return null;
}, },
frozenHeaderColumnGroup() { frozenHeaderColumnGroup() {
if (this.allChildren) { const children = this.$slots.default();
for (let child of this.allChildren) { for (let child of children) {
if (child.$vnode.tag.indexOf('columngroup') !== -1 && child.type === 'frozenheader') { if (child.type.name === 'columngroup' && child.props.type === 'frozenheader') {
return child; return child;
} }
} }
}
return null; return null;
}, },
footerColumnGroup() { footerColumnGroup() {
if (this.allChildren) { const children = this.$slots.default();
for (let child of this.allChildren) { for (let child of children) {
if (child.$vnode.tag.indexOf('columngroup') !== -1 && child.type === 'footer') { if (child.type.name === 'columngroup' && child.props.type === 'footer') {
return child; return child;
} }
} }
}
return null; return null;
}, },
frozenFooterColumnGroup() { frozenFooterColumnGroup() {
if (this.allChildren) { const children = this.$slots.default();
for (let child of this.allChildren) { for (let child of children) {
if (child.$vnode.tag.indexOf('columngroup') !== -1 && child.type === 'frozenfooter') { if (child.type.name === 'columngroup' && child.props.type === 'frozenfooter') {
return child; return child;
} }
} }
}
return null; return null;
}, },

View File

@ -5,7 +5,7 @@
<table class="p-datatable-scrollable-header-table"> <table class="p-datatable-scrollable-header-table">
<colgroup> <colgroup>
<template v-for="(col,i) of columns"> <template v-for="(col,i) of columns">
<col v-if="shouldRenderCol(col)" :key="col.columnKey||col.field||i" :style="col.headerStyle" /> <col v-if="shouldRenderCol(col)" :key="col.props.columnKey||col.props.field||i" :style="col.props.headerStyle" />
</template> </template>
</colgroup> </colgroup>
<slot name="header"></slot> <slot name="header"></slot>
@ -17,14 +17,14 @@
<table ref="scrollTable" :class="bodyTableClass" :style="bodyTableStyle"> <table ref="scrollTable" :class="bodyTableClass" :style="bodyTableStyle">
<colgroup> <colgroup>
<template v-for="(col,i) of columns"> <template v-for="(col,i) of columns">
<col v-if="shouldRenderCol(col)" :key="col.columnKey||col.field||i" :style="col.bodyStyle || col.headerStyle" /> <col v-if="shouldRenderCol(col)" :key="col.props.columnKey||col.props.field||i" :style="col.props.bodyStyle || col.props.headerStyle" />
</template> </template>
</colgroup> </colgroup>
<slot name="body"></slot> <slot name="body"></slot>
</table> </table>
<table ref="loadingTable" :style="{top:'0', display: 'none'}" class="p-datatable-scrollable-body-table p-datatable-loading-virtual-table p-datatable-virtual-table" v-if="virtualScroll"> <table ref="loadingTable" :style="{top:'0', display: 'none'}" class="p-datatable-scrollable-body-table p-datatable-loading-virtual-table p-datatable-virtual-table" v-if="virtualScroll">
<colgroup> <colgroup>
<col v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.bodyStyle || col.headerStyle" /> <col v-for="(col,i) of columns" :key="col.props.columnKey||col.props.field||i" :style="col.props.bodyStyle || col.props.headerStyle" />
</colgroup> </colgroup>
<DTTableLoadingBody :columns="columns" :rows="rows" /> <DTTableLoadingBody :columns="columns" :rows="rows" />
</table> </table>
@ -35,7 +35,7 @@
<table class="p-datatable-scrollable-footer-table"> <table class="p-datatable-scrollable-footer-table">
<colgroup> <colgroup>
<template v-for="(col,i) of columns"> <template v-for="(col,i) of columns">
<col v-if="shouldRenderCol(col)" :key="col.columnKey||col.field||i" :style="col.footerStyle || col.headerStyle" /> <col v-if="shouldRenderCol(col)" :key="col.props.columnKey||col.props.field||i" :style="col.props.footerStyle || col.props.headerStyle" />
</template> </template>
</colgroup> </colgroup>
<slot name="footer"></slot> <slot name="footer"></slot>
@ -175,7 +175,7 @@ export default {
}, },
shouldRenderCol(column) { shouldRenderCol(column) {
if (this.rowGroupMode && this.rowGroupMode === 'subheader') { if (this.rowGroupMode && this.rowGroupMode === 'subheader') {
return this.groupRowsBy !== column.field; return this.groupRowsBy !== column.props.field;
} }
return true; return true;

View File

@ -7,7 +7,7 @@
<button class="p-row-toggler p-link" @click="onRowGroupToggle($event, rowData)" v-if="expandableRowGroups" type="button"> <button class="p-row-toggler p-link" @click="onRowGroupToggle($event, rowData)" v-if="expandableRowGroups" type="button">
<span :class="rowGroupTogglerIcon(rowData)"></span> <span :class="rowGroupTogglerIcon(rowData)"></span>
</button> </button>
<DTRowExpansionTemplate :template="templates['groupheader']" :data="rowData" :index="index" /> <component :is="templates['groupheader']" :data="rowData" :index="index" />
</td> </td>
</tr> </tr>
<tr :class="getRowClass(rowData)" :key="getRowKey(rowData, index)" <tr :class="getRowClass(rowData)" :key="getRowKey(rowData, index)"
@ -15,8 +15,8 @@
@click="onRowClick($event, rowData, index)" @contextmenu="onRowRightClick($event, rowData, index)" @touchend="onRowTouchEnd($event)" @keydown="onRowKeyDown($event, rowData, index)" :tabindex="selectionMode || contextMenu ? '0' : null" @click="onRowClick($event, rowData, index)" @contextmenu="onRowRightClick($event, rowData, index)" @touchend="onRowTouchEnd($event)" @keydown="onRowKeyDown($event, rowData, index)" :tabindex="selectionMode || contextMenu ? '0' : null"
@mousedown="onRowMouseDown($event)" @dragstart="onRowDragStart($event, index)" @dragover="onRowDragOver($event,index)" @dragleave="onRowDragLeave($event)" @dragend="onRowDragEnd($event)" @drop="onRowDrop($event)"> @mousedown="onRowMouseDown($event)" @dragstart="onRowDragStart($event, index)" @dragover="onRowDragOver($event,index)" @dragleave="onRowDragLeave($event)" @dragend="onRowDragEnd($event)" @drop="onRowDrop($event)">
<template v-for="(col,i) of columns"> <template v-for="(col,i) of columns">
<DTBodyCell v-if="shouldRenderBodyCell(value, col, index)" :key="col.columnKey||col.field||i" :rowData="rowData" :column="col" :index="index" :selected="isSelected(rowData)" <DTBodyCell v-if="shouldRenderBodyCell(value, col, index)" :key="col.props.columnKey||col.props.field||i" :rowData="rowData" :column="col" :index="index" :selected="isSelected(rowData)"
:rowTogglerIcon="col.expander ? rowTogglerIcon(rowData): null" :rowTogglerIcon="col.props.expander ? rowTogglerIcon(rowData): null"
:rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(value, col, index) : null" :rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(value, col, index) : null"
:editMode="editMode" :editing="editMode === 'row' && isRowEditing(rowData)" :editMode="editMode" :editing="editMode === 'row' && isRowEditing(rowData)"
@radio-change="onRadioChange($event)" @checkbox-change="onCheckboxChange($event)" @row-toggle="onRowToggle($event)" @radio-change="onRadioChange($event)" @checkbox-change="onCheckboxChange($event)" @row-toggle="onRowToggle($event)"
@ -26,18 +26,18 @@
</tr> </tr>
<tr class="p-datatable-row-expansion" v-if="templates['expansion'] && expandedRows && isRowExpanded(rowData)" :key="getRowKey(rowData, index) + '_expansion'"> <tr class="p-datatable-row-expansion" v-if="templates['expansion'] && expandedRows && isRowExpanded(rowData)" :key="getRowKey(rowData, index) + '_expansion'">
<td :colspan="columns.length"> <td :colspan="columns.length">
<DTRowExpansionTemplate :template="templates['expansion']" :data="rowData" :index="index" /> <component :is="templates['expansion']" :data="rowData" :index="index" />
</td> </td>
</tr> </tr>
<tr class="p-rowgroup-footer" v-if="templates['groupfooter'] && rowGroupMode === 'subheader' && shouldRenderRowGroupFooter(value, rowData, index)" :key="getRowKey(rowData, index) + '_subfooter'"> <tr class="p-rowgroup-footer" v-if="templates['groupfooter'] && rowGroupMode === 'subheader' && shouldRenderRowGroupFooter(value, rowData, index)" :key="getRowKey(rowData, index) + '_subfooter'">
<DTRowExpansionTemplate :template="templates['groupfooter']" :data="rowData" :index="index" /> <component :is="templates['groupfooter']" :data="rowData" :index="index" />
</tr> </tr>
</template> </template>
</template> </template>
<tr v-else class="p-datatable-emptymessage"> <tr v-else class="p-datatable-emptymessage">
<td :colspan="columns.length"> <td :colspan="columns.length">
<DTSlotTemplate :template="templates.empty" v-if="templates.empty && !loading"/> <component :is="templates.empty" v-if="templates.empty && !loading" />
<DTSlotTemplate :template="templates.loading" v-if="templates.loading && loading"/> <component :is="templates.loading" v-if="templates.loading && loading" />
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -47,49 +47,6 @@
import ObjectUtils from '../utils/ObjectUtils'; import ObjectUtils from '../utils/ObjectUtils';
import BodyCell from './BodyCell.vue'; import BodyCell from './BodyCell.vue';
const RowExpansionTemplate = {
functional: true,
props: {
name: {
type: String,
default: null
},
data: {
type: null,
default: null
},
index: {
type: Number,
default: null
},
template: {
type: null,
default: null
}
},
render(createElement, context) {
const content = context.props.template({
'data': context.props.data,
'index': context.props.index
});
return [content];
}
}
const SlotTemplate = {
functional: true,
props: {
template: {
type: null,
default: null
}
},
render(createElement, context) {
const content = context.props.template();
return [content];
}
}
export default { export default {
props: { props: {
value: { value: {
@ -446,9 +403,7 @@ export default {
} }
}, },
components: { components: {
'DTBodyCell': BodyCell, 'DTBodyCell': BodyCell
'DTRowExpansionTemplate': RowExpansionTemplate,
'DTSlotTemplate': SlotTemplate
} }
} }
</script> </script>

View File

@ -1,18 +1,18 @@
<template> <template>
<tfoot class="p-datatable-tfoot" v-if="hasFooter"> <tfoot class="p-datatable-tfoot" v-if="hasFooter">
<tr v-if="!columnGroup"> <tr v-if="!columnGroup">
<td v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.footerStyle" :class="col.footerClass" <td v-for="(col,i) of columns" :key="col.props.columnKey||col.props.field||i" :style="col.props.footerStyle" :class="col.props.footerClass"
:colspan="col.colspan" :rowspan="col.rowspan"> :colspan="col.props.colspan" :rowspan="col.props.rowspan">
<DTColumnSlot :column="col" type="footer" v-if="col.$scopedSlots.footer" /> <component :is="col.children.footer" :column="col" v-if="col.children && col.children.footer"/>
{{col.footer}} {{col.props.footer}}
</td> </td>
</tr> </tr>
<template v-else> <template v-else>
<tr v-for="(row,i) of columnGroup.rows" :key="i"> <tr v-for="(row,i) of columnGroup.children.default()" :key="i">
<td v-for="(col,i) of row.columns" :key="col.columnKey||col.field||i" :style="col.footerStyle" :class="col.footerClass" <td v-for="(col,i) of row.children.default()" :key="col.props.columnKey||col.props.field||i" :style="col.props.footerStyle" :class="col.props.footerClass"
:colspan="col.colspan" :rowspan="col.rowspan"> :colspan="col.props.colspan" :rowspan="col.props.rowspan">
<DTColumnSlot :column="col" type="footer" v-if="col.$scopedSlots.footer" /> <component :is="col.children.footer" :column="col" v-if="col.children && col.children.footer"/>
{{col.footer}} {{col.props.footer}}
</td> </td>
</tr> </tr>
</template> </template>
@ -20,8 +20,6 @@
</template> </template>
<script> <script>
import ColumnSlot from './ColumnSlot.vue';
export default { export default {
props: { props: {
columnGroup: { columnGroup: {
@ -42,7 +40,7 @@ export default {
} }
else { else {
for (let col of this.columns) { for (let col of this.columns) {
if (col.footer || col.$scopedSlots.footer) { if (col.props.footer || (col.children && col.children.footer)) {
hasFooter = true; hasFooter = true;
break; break;
} }
@ -51,9 +49,6 @@ export default {
return hasFooter; return hasFooter;
} }
},
components: {
'DTColumnSlot': ColumnSlot
} }
} }
</script> </script>

View File

@ -3,41 +3,41 @@
<template v-if="!columnGroup"> <template v-if="!columnGroup">
<tr> <tr>
<template v-for="(col,i) of columns"> <template v-for="(col,i) of columns">
<th v-if="rowGroupMode !== 'subheader' || (groupRowsBy !== col.field)" :tabindex="col.sortable ? '0' : null" @keydown="onColumnKeyDown($event, col)" <th v-if="rowGroupMode !== 'subheader' || (groupRowsBy !== col.props.field)" :tabindex="col.props.sortable ? '0' : null" @keydown="onColumnKeyDown($event, col)"
:key="col.columnKey||col.field||i" :style="col.headerStyle" :class="getColumnHeaderClass(col)" :key="col.props.columnKey||col.props.field||i" :style="col.props.headerStyle" :class="getColumnHeaderClass(col)"
@click="onColumnHeaderClick($event, col)" @mousedown="onColumnHeaderMouseDown($event, col)" @click="onColumnHeaderClick($event, col)" @mousedown="onColumnHeaderMouseDown($event, col)"
@dragstart="onColumnHeaderDragStart($event)" @dragover="onColumnHeaderDragOver($event)" @dragleave="onColumnHeaderDragLeave($event)" @drop="onColumnHeaderDrop($event)" @dragstart="onColumnHeaderDragStart($event)" @dragover="onColumnHeaderDragOver($event)" @dragleave="onColumnHeaderDragLeave($event)" @drop="onColumnHeaderDrop($event)"
:colspan="col.colspan" :rowspan="col.rowspan" :aria-sort="getAriaSort(col)"> :colspan="col.props.colspan" :rowspan="col.props.rowspan" :aria-sort="getAriaSort(col)">
<span class="p-column-resizer" @mousedown="onColumnResizeStart($event)" v-if="resizableColumns"></span> <span class="p-column-resizer" @mousedown="onColumnResizeStart($event)" v-if="resizableColumns"></span>
<DTColumnSlot :column="col" type="header" v-if="col.$scopedSlots.header" /> <component :is="col.children.header" :column="col" v-if="col.children && col.children.header"/>
<span class="p-column-title" v-if="col.header">{{col.header}}</span> <span class="p-column-title" v-if="col.props.header">{{col.props.header}}</span>
<span v-if="col.sortable" :class="getSortableColumnIcon(col)"></span> <span v-if="col.props.sortable" :class="getSortableColumnIcon(col)"></span>
<span v-if="isMultiSorted(col)" class="p-sortable-column-badge">{{getMultiSortMetaIndex(col) + 1}}</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="col.selectionMode ==='multiple' && !hasColumnFilter()" /> <DTHeaderCheckbox :checked="allRowsSelected" @change="onHeaderCheckboxChange($event)" :disabled="empty" v-if="col.props.selectionMode ==='multiple' && !hasColumnFilter()" />
</th> </th>
</template> </template>
</tr> </tr>
<tr v-if="hasColumnFilter()"> <tr v-if="hasColumnFilter()">
<template v-for="(col,i) of columns"> <template v-for="(col,i) of columns">
<th v-if="rowGroupMode !== 'subheader' || (groupRowsBy !== col.field)" :key="col.columnKey||col.field||i" <th v-if="rowGroupMode !== 'subheader' || (groupRowsBy !== col.props.field)" :key="col.props.columnKey||col.props.field||i"
:class="getFilterColumnHeaderClass(col)" :style="col.filterHeaderStyle"> :class="getFilterColumnHeaderClass(col)" :style="col.props.filterHeaderStyle">
<DTColumnSlot :column="col" type="filter" v-if="col.$scopedSlots.filter" /> <component :is="col.children.filter" :column="col" v-if="col.children && col.children.filter"/>
<DTHeaderCheckbox :checked="allRowsSelected" @change="onHeaderCheckboxChange($event)" :disabled="empty" v-if="col.selectionMode ==='multiple'" /> <DTHeaderCheckbox :checked="allRowsSelected" @change="onHeaderCheckboxChange($event)" :disabled="empty" v-if="col.props.selectionMode ==='multiple'" />
</th> </th>
</template> </template>
</tr> </tr>
</template> </template>
<template v-else> <template v-else>
<tr v-for="(row,i) of columnGroup.rows" :key="i"> <tr v-for="(row,i) of columnGroup.children.default()" :key="i">
<th v-for="(col,i) of row.columns" :key="col.columnKey||col.field||i" :style="col.headerStyle" :class="getColumnHeaderClass(col)" :tabindex="col.sortable ? '0' : null" <th v-for="(col,i) of row.children.default()" :key="col.props.columnKey||col.props.field||i" :style="col.props.headerStyle" :class="getColumnHeaderClass(col)" :tabindex="col.props.sortable ? '0' : null"
@click="onColumnHeaderClick($event, col)" @keydown="onColumnKeyDown($event, col)" @dragstart="onColumnHeaderDragStart($event)" @dragover="onColumnHeaderDragOver($event)" @dragleave="onColumnHeaderDragLeave($event)" @drop="onColumnHeaderDrop($event)" @click="onColumnHeaderClick($event, col)" @keydown="onColumnKeyDown($event, col)" @dragstart="onColumnHeaderDragStart($event)" @dragover="onColumnHeaderDragOver($event)" @dragleave="onColumnHeaderDragLeave($event)" @drop="onColumnHeaderDrop($event)"
:colspan="col.colspan" :rowspan="col.rowspan" :aria-sort="getAriaSort(col)"> :colspan="col.props.colspan" :rowspan="col.props.rowspan" :aria-sort="getAriaSort(col)">
<DTColumnSlot :column="col" type="header" v-if="col.$scopedSlots.header" /> <component :is="col.children.header" :column="col" v-if="col.children && col.children.header"/>
<span class="p-column-title" v-if="col.header">{{col.header}}</span> <span class="p-column-title" v-if="col.props.header">{{col.props.header}}</span>
<span v-if="col.sortable" :class="getSortableColumnIcon(col)"></span> <span v-if="col.props.sortable" :class="getSortableColumnIcon(col)"></span>
<span v-if="isMultiSorted(col)" class="p-sortable-column-badge">{{getMultiSortMetaIndex(col) + 1}}</span> <span v-if="isMultiSorted(col)" class="p-sortable-column-badge">{{getMultiSortMetaIndex(col) + 1}}</span>
<DTColumnSlot :column="col" type="filter" v-if="col.$scopedSlots.filter" /> <component :is="col.children.filter" :column="col" v-if="col.children && col.children.filter"/>
<DTHeaderCheckbox :checked="allRowsSelected" @change="onHeaderCheckboxChange($event)" :disabled="empty" v-if="col.selectionMode ==='multiple'" /> <DTHeaderCheckbox :checked="allRowsSelected" @change="onHeaderCheckboxChange($event)" :disabled="empty" v-if="col.props.selectionMode ==='multiple'" />
</th> </th>
</tr> </tr>
</template> </template>
@ -46,7 +46,6 @@
<script> <script>
import DomHandler from '../utils/DomHandler'; import DomHandler from '../utils/DomHandler';
import ColumnSlot from './ColumnSlot.vue';
import HeaderCheckbox from './HeaderCheckbox.vue'; import HeaderCheckbox from './HeaderCheckbox.vue';
export default { export default {
@ -98,27 +97,27 @@ export default {
}, },
methods: { methods: {
isMultiSorted(column) { isMultiSorted(column) {
return column.sortable && this.getMultiSortMetaIndex(column) > -1 return column.props.sortable && this.getMultiSortMetaIndex(column) > -1
}, },
isColumnSorted(column) { isColumnSorted(column) {
return this.sortMode === 'single' ? (this.sortField && (this.sortField === column.field || this.sortField === column.sortField)) : this.isMultiSorted(column); return this.sortMode === 'single' ? (this.sortField && (this.sortField === column.props.field || this.sortField === column.props.sortField)) : this.isMultiSorted(column);
}, },
getColumnHeaderClass(column) { getColumnHeaderClass(column) {
return [column.headerClass, return [column.props.headerClass,
{'p-sortable-column': column.sortable}, {'p-sortable-column': column.props.sortable},
{'p-resizable-column': this.resizableColumns}, {'p-resizable-column': this.resizableColumns},
{'p-highlight': this.isColumnSorted(column)} {'p-highlight': this.isColumnSorted(column)}
]; ];
}, },
getFilterColumnHeaderClass(column) { getFilterColumnHeaderClass(column) {
return ['p-filter-column', column.filterHeaderClass]; return ['p-filter-column', column.props.filterHeaderClass];
}, },
getSortableColumnIcon(column) { getSortableColumnIcon(column) {
let sorted = false; let sorted = false;
let sortOrder = null; let sortOrder = null;
if (this.sortMode === 'single') { if (this.sortMode === 'single') {
sorted = this.sortField && (this.sortField === column.field || this.sortField === column.sortField); sorted = this.sortField && (this.sortField === column.props.field || this.sortField === column.props.sortField);
sortOrder = sorted ? this.sortOrder: 0; sortOrder = sorted ? this.sortOrder: 0;
} }
else if (this.sortMode === 'multiple') { else if (this.sortMode === 'multiple') {
@ -142,7 +141,7 @@ export default {
for (let i = 0; i < this.multiSortMeta.length; i++) { for (let i = 0; i < this.multiSortMeta.length; i++) {
let meta = this.multiSortMeta[i]; let meta = this.multiSortMeta[i];
if (meta.field === column.field || meta.field === column.sortField) { if (meta.field === column.props.field || meta.field === column.props.sortField) {
index = i; index = i;
break; break;
} }
@ -180,7 +179,7 @@ export default {
} }
}, },
getAriaSort(column) { getAriaSort(column) {
if (column.sortable) { if (column.props.sortable) {
const sortIcon = this.getSortableColumnIcon(column); const sortIcon = this.getSortableColumnIcon(column);
if (sortIcon[1]['pi-sort-amount-down']) if (sortIcon[1]['pi-sort-amount-down'])
return 'descending'; return 'descending';
@ -196,7 +195,7 @@ export default {
hasColumnFilter() { hasColumnFilter() {
if (this.columns) { if (this.columns) {
for (let col of this.columns) { for (let col of this.columns) {
if (col.$scopedSlots.filter) { if (col.children && col.children.filter) {
return true; return true;
} }
} }
@ -206,7 +205,6 @@ export default {
} }
}, },
components: { components: {
'DTColumnSlot': ColumnSlot,
'DTHeaderCheckbox': HeaderCheckbox 'DTHeaderCheckbox': HeaderCheckbox
} }
} }

View File

@ -1,16 +1,14 @@
<template> <template>
<tbody class="p-datatable-tbody"> <tbody class="p-datatable-tbody">
<tr v-for="n in rows" :key="n"> <tr v-for="n in rows" :key="n">
<td v-for="(col,i) of columns" :key="col.columnKey||col.field||i"> <td v-for="(col,i) of columns" :key="col.props.columnKey||col.props.field||i">
<DTColumnSlot :column="col" :index="i" type="loading" /> <component :is="col.children.loading" :column="col" :index="i" v-if="col.children && col.children.loading" />
</td> </td>
</tr> </tr>
</tbody> </tbody>
</template> </template>
<script> <script>
import ColumnSlot from './ColumnSlot';
export default { export default {
props: { props: {
columns: { columns: {
@ -21,9 +19,6 @@ export default {
type: null, type: null,
default: null default: null
} }
},
components: {
'DTColumnSlot': ColumnSlot
} }
} }
</script> </script>

View File

@ -1,21 +1,8 @@
<template>
<div>
<slot></slot>
</div>
</template>
<script> <script>
export default { export default {
props: { name: 'row',
render() {
}, return null;
data() {
return {
columns: null
};
},
mounted() {
this.columns = this.$children;
} }
} }
</script> </script>

View File

@ -89,7 +89,7 @@
&lt;div class="card"&gt; &lt;div class="card"&gt;
&lt;h5&gt;Single&lt;/h5&gt; &lt;h5&gt;Single&lt;/h5&gt;
&lt;p&gt;In single mode, a row is selected on click event of a row. If the row is already selected then the row gets unselected.&lt;/p&gt; &lt;p&gt;In single mode, a row is selected on click event of a row. If the row is already selected then the row gets unselected.&lt;/p&gt;
&lt;DataTable :value="products" :selection.sync="selectedProduct1" selectionMode="single" dataKey="id"&gt; &lt;DataTable :value="products" v-model:selection="selectedProduct1" selectionMode="single" dataKey="id"&gt;
&lt;Column field="code" header="Code"&gt;&lt;/Column&gt; &lt;Column field="code" header="Code"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name"&gt;&lt;/Column&gt; &lt;Column field="name" header="Name"&gt;&lt;/Column&gt;
&lt;Column field="category" header="Category"&gt;&lt;/Column&gt; &lt;Column field="category" header="Category"&gt;&lt;/Column&gt;
@ -101,7 +101,7 @@
&lt;h5&gt;Multiple&lt;/h5&gt; &lt;h5&gt;Multiple&lt;/h5&gt;
&lt;p&gt;In multiple mode, selection binding should be an array. For touch enabled devices, selection is managed by tapping and for other devices metakey or shiftkey are required. &lt;p&gt;In multiple mode, selection binding should be an array. For touch enabled devices, selection is managed by tapping and for other devices metakey or shiftkey are required.
Setting metaKeySelection property as false enables multiple selection without meta key.&lt;/p&gt; Setting metaKeySelection property as false enables multiple selection without meta key.&lt;/p&gt;
&lt;DataTable :value="products" :selection.sync="selectedProducts1" selectionMode="multiple" dataKey="id"&gt; &lt;DataTable :value="products" v-model:selection="selectedProducts1" selectionMode="multiple" dataKey="id"&gt;
&lt;template #header&gt; &lt;template #header&gt;
Multiple Selection with MetaKey Multiple Selection with MetaKey
&lt;/template&gt; &lt;/template&gt;
@ -111,7 +111,7 @@
&lt;Column field="quantity" header="Quantity"&gt;&lt;/Column&gt; &lt;Column field="quantity" header="Quantity"&gt;&lt;/Column&gt;
&lt;/DataTable&gt; &lt;/DataTable&gt;
&lt;DataTable :value="products" :selection.sync="selectedProducts2" selectionMode="multiple" dataKey="id" :metaKeySelection="false" style="margin-top: 2em"&gt; &lt;DataTable :value="products" v-model:selection="selectedProducts2" selectionMode="multiple" dataKey="id" :metaKeySelection="false" style="margin-top: 2em"&gt;
&lt;template #header&gt; &lt;template #header&gt;
Multiple Selection without MetaKey Multiple Selection without MetaKey
&lt;/template&gt; &lt;/template&gt;
@ -125,7 +125,7 @@
&lt;div class="card"&gt; &lt;div class="card"&gt;
&lt;h5&gt;Events&lt;/h5&gt; &lt;h5&gt;Events&lt;/h5&gt;
&lt;p&gt;row-select and row-unselects are available as selection events.&lt;/p&gt; &lt;p&gt;row-select and row-unselects are available as selection events.&lt;/p&gt;
&lt;DataTable :value="products" :selection.sync="selectedProduct2" selectionMode="single" dataKey="id" &lt;DataTable :value="products" v-model:selection="selectedProduct2" selectionMode="single" dataKey="id"
@row-select="onRowSelect" @row-unselect="onRowUnselect"&gt; @row-select="onRowSelect" @row-unselect="onRowUnselect"&gt;
&lt;Column field="code" header="Code"&gt;&lt;/Column&gt; &lt;Column field="code" header="Code"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name"&gt;&lt;/Column&gt; &lt;Column field="name" header="Name"&gt;&lt;/Column&gt;
@ -137,7 +137,7 @@
&lt;div class="card"&gt; &lt;div class="card"&gt;
&lt;h5&gt;RadioButton&lt;/h5&gt; &lt;h5&gt;RadioButton&lt;/h5&gt;
&lt;p&gt;Single selection can also be handled using radio buttons by enabling the selectionMode property of column as "single".&lt;/p&gt; &lt;p&gt;Single selection can also be handled using radio buttons by enabling the selectionMode property of column as "single".&lt;/p&gt;
&lt;DataTable :value="products" :selection.sync="selectedProduct3" dataKey="id"&gt; &lt;DataTable :value="products" v-model:selection="selectedProduct3" dataKey="id"&gt;
&lt;Column selectionMode="single" headerStyle="width: 3em"&gt;&lt;/Column&gt; &lt;Column selectionMode="single" headerStyle="width: 3em"&gt;&lt;/Column&gt;
&lt;Column field="code" header="Code"&gt;&lt;/Column&gt; &lt;Column field="code" header="Code"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name"&gt;&lt;/Column&gt; &lt;Column field="name" header="Name"&gt;&lt;/Column&gt;
@ -149,7 +149,7 @@
&lt;div class="card"&gt; &lt;div class="card"&gt;
&lt;h5&gt;Checkbox&lt;/h5&gt; &lt;h5&gt;Checkbox&lt;/h5&gt;
&lt;p&gt;Multiple selection can also be handled using checkboxes by enabling the selectionMode property of column as "multiple".&lt;/p&gt; &lt;p&gt;Multiple selection can also be handled using checkboxes by enabling the selectionMode property of column as "multiple".&lt;/p&gt;
&lt;DataTable :value="products" :selection.sync="selectedProducts3" dataKey="id"&gt; &lt;DataTable :value="products" v-model:selection="selectedProducts3" dataKey="id"&gt;
&lt;Column selectionMode="multiple" headerStyle="width: 3em"&gt;&lt;/Column&gt; &lt;Column selectionMode="multiple" headerStyle="width: 3em"&gt;&lt;/Column&gt;
&lt;Column field="code" header="Code"&gt;&lt;/Column&gt; &lt;Column field="code" header="Code"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name"&gt;&lt;/Column&gt; &lt;Column field="name" header="Name"&gt;&lt;/Column&gt;

View File

@ -11,11 +11,11 @@
<div class="card"> <div class="card">
<h5>Single Column</h5> <h5>Single Column</h5>
<DataTable :value="products"> <DataTable :value="products">
<Column field="code" header="Code" sortable></Column> <Column field="code" header="Code" :sortable="true"></Column>
<Column field="name" header="Name" sortable></Column> <Column field="name" header="Name" :sortable="true"></Column>
<Column field="category" header="Category" sortable></Column> <Column field="category" header="Category" :sortable="true"></Column>
<Column field="quantity" header="Quantity" sortable></Column> <Column field="quantity" header="Quantity" :sortable="true"></Column>
<Column field="price" header="Price" sortable> <Column field="price" header="Price" :sortable="true">
<template #body="slotProps"> <template #body="slotProps">
{{formatCurrency(slotProps.data.price)}} {{formatCurrency(slotProps.data.price)}}
</template> </template>
@ -27,11 +27,11 @@
<h5>Multiple Columns</h5> <h5>Multiple Columns</h5>
<p>Use metakey to add a column to the sort selection.</p> <p>Use metakey to add a column to the sort selection.</p>
<DataTable :value="products" sortMode="multiple"> <DataTable :value="products" sortMode="multiple">
<Column field="code" header="Code" sortable></Column> <Column field="code" header="Code" :sortable="true"></Column>
<Column field="name" header="Name" sortable></Column> <Column field="name" header="Name" :sortable="true"></Column>
<Column field="category" header="Category" sortable></Column> <Column field="category" header="Category" :sortable="true"></Column>
<Column field="quantity" header="Quantity" sortable></Column> <Column field="quantity" header="Quantity" :sortable="true"></Column>
<Column field="price" header="Price" sortable> <Column field="price" header="Price" :sortable="true">
<template #body="slotProps"> <template #body="slotProps">
{{formatCurrency(slotProps.data.price)}} {{formatCurrency(slotProps.data.price)}}
</template> </template>
@ -42,11 +42,11 @@
<div class="card"> <div class="card">
<h5>Presort</h5> <h5>Presort</h5>
<DataTable :value="products" sortField="category" :sortOrder="-1"> <DataTable :value="products" sortField="category" :sortOrder="-1">
<Column field="code" header="Code" sortable></Column> <Column field="code" header="Code" :sortable="true"></Column>
<Column field="name" header="Name" sortable></Column> <Column field="name" header="Name" :sortable="true"></Column>
<Column field="category" header="Category" sortable></Column> <Column field="category" header="Category" :sortable="true"></Column>
<Column field="quantity" header="Quantity" sortable></Column> <Column field="quantity" header="Quantity" :sortable="true"></Column>
<Column field="price" header="Price" sortable> <Column field="price" header="Price" :sortable="true">
<template #body="slotProps"> <template #body="slotProps">
{{formatCurrency(slotProps.data.price)}} {{formatCurrency(slotProps.data.price)}}
</template> </template>
@ -57,11 +57,11 @@
<div class="card"> <div class="card">
<h5>Removable Sort</h5> <h5>Removable Sort</h5>
<DataTable :value="products" removableSort> <DataTable :value="products" removableSort>
<Column field="code" header="Code" sortable></Column> <Column field="code" header="Code" :sortable="true"></Column>
<Column field="name" header="Name" sortable></Column> <Column field="name" header="Name" :sortable="true"></Column>
<Column field="category" header="Category" sortable></Column> <Column field="category" header="Category" :sortable="true"></Column>
<Column field="quantity" header="Quantity" sortable></Column> <Column field="quantity" header="Quantity" :sortable="true"></Column>
<Column field="price" header="Price" sortable> <Column field="price" header="Price" :sortable="true">
<template #body="slotProps"> <template #body="slotProps">
{{formatCurrency(slotProps.data.price)}} {{formatCurrency(slotProps.data.price)}}
</template> </template>
@ -78,11 +78,11 @@
&lt;div class="card"&gt; &lt;div class="card"&gt;
&lt;h5&gt;Single Column&lt;/h5&gt; &lt;h5&gt;Single Column&lt;/h5&gt;
&lt;DataTable :value="products"&gt; &lt;DataTable :value="products"&gt;
&lt;Column field="code" header="Code" sortable&gt;&lt;/Column&gt; &lt;Column field="code" header="Code" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name" sortable&gt;&lt;/Column&gt; &lt;Column field="name" header="Name" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="category" header="Category" sortable&gt;&lt;/Column&gt; &lt;Column field="category" header="Category" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="quantity" header="Quantity" sortable&gt;&lt;/Column&gt; &lt;Column field="quantity" header="Quantity" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="price" header="Price" sortable&gt; &lt;Column field="price" header="Price" sortable="true"&gt;
&lt;template #body="slotProps"&gt; &lt;template #body="slotProps"&gt;
{{formatCurrency(slotProps.data.price)}} {{formatCurrency(slotProps.data.price)}}
&lt;/template&gt; &lt;/template&gt;
@ -94,11 +94,11 @@
&lt;h5&gt;Multiple Columns&lt;/h5&gt; &lt;h5&gt;Multiple Columns&lt;/h5&gt;
&lt;p&gt;Use metakey to add a column to the sort selection.&lt;/p&gt; &lt;p&gt;Use metakey to add a column to the sort selection.&lt;/p&gt;
&lt;DataTable :value="products" sortMode="multiple"&gt; &lt;DataTable :value="products" sortMode="multiple"&gt;
&lt;Column field="code" header="Code" sortable&gt;&lt;/Column&gt; &lt;Column field="code" header="Code" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name" sortable&gt;&lt;/Column&gt; &lt;Column field="name" header="Name" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="category" header="Category" sortable&gt;&lt;/Column&gt; &lt;Column field="category" header="Category" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="quantity" header="Quantity" sortable&gt;&lt;/Column&gt; &lt;Column field="quantity" header="Quantity" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="price" header="Price" sortable&gt; &lt;Column field="price" header="Price" sortable="true"&gt;
&lt;template #body="slotProps"&gt; &lt;template #body="slotProps"&gt;
{{formatCurrency(slotProps.data.price)}} {{formatCurrency(slotProps.data.price)}}
&lt;/template&gt; &lt;/template&gt;
@ -109,11 +109,11 @@
&lt;div class="card"&gt; &lt;div class="card"&gt;
&lt;h5&gt;Presort&lt;/h5&gt; &lt;h5&gt;Presort&lt;/h5&gt;
&lt;DataTable :value="products" sortField="category" :sortOrder="-1"&gt; &lt;DataTable :value="products" sortField="category" :sortOrder="-1"&gt;
&lt;Column field="code" header="Code" sortable&gt;&lt;/Column&gt; &lt;Column field="code" header="Code" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name" sortable&gt;&lt;/Column&gt; &lt;Column field="name" header="Name" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="category" header="Category" sortable&gt;&lt;/Column&gt; &lt;Column field="category" header="Category" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="quantity" header="Quantity" sortable&gt;&lt;/Column&gt; &lt;Column field="quantity" header="Quantity" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="price" header="Price" sortable&gt; &lt;Column field="price" header="Price" sortable="true"&gt;
&lt;template #body="slotProps"&gt; &lt;template #body="slotProps"&gt;
{{formatCurrency(slotProps.data.price)}} {{formatCurrency(slotProps.data.price)}}
&lt;/template&gt; &lt;/template&gt;
@ -124,11 +124,11 @@
&lt;div class="card"&gt; &lt;div class="card"&gt;
&lt;h5&gt;Removable Sort&lt;/h5&gt; &lt;h5&gt;Removable Sort&lt;/h5&gt;
&lt;DataTable :value="products" removableSort&gt; &lt;DataTable :value="products" removableSort&gt;
&lt;Column field="code" header="Code" sortable&gt;&lt;/Column&gt; &lt;Column field="code" header="Code" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name" sortable&gt;&lt;/Column&gt; &lt;Column field="name" header="Name" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="category" header="Category" sortable&gt;&lt;/Column&gt; &lt;Column field="category" header="Category" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="quantity" header="Quantity" sortable&gt;&lt;/Column&gt; &lt;Column field="quantity" header="Quantity" sortable="true"&gt;&lt;/Column&gt;
&lt;Column field="price" header="Price" sortable&gt; &lt;Column field="price" header="Price" sortable="true"&gt;
&lt;template #body="slotProps"&gt; &lt;template #body="slotProps"&gt;
{{formatCurrency(slotProps.data.price)}} {{formatCurrency(slotProps.data.price)}}
&lt;/template&gt; &lt;/template&gt;