Sorting for TreeTable
parent
ce2186fe30
commit
0bf570cce3
|
@ -963,6 +963,10 @@ export default {
|
||||||
padding: .25em .5em;
|
padding: .25em .5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-datatable .p-column-title {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
.p-datatable .p-sortable-column {
|
.p-datatable .p-sortable-column {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import ObjectUtils from '../utils/ObjectUtils';
|
||||||
|
import DomHandler from '../utils/DomHandler';
|
||||||
import TreeTableColumnSlot from './TreeTableColumnSlot';
|
import TreeTableColumnSlot from './TreeTableColumnSlot';
|
||||||
import TreeTableRowLoader from './TreeTableRowLoader';
|
import TreeTableRowLoader from './TreeTableRowLoader';
|
||||||
import Paginator from '../paginator/Paginator';
|
import Paginator from '../paginator/Paginator';
|
||||||
|
@ -276,8 +278,131 @@ export default {
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
},
|
},
|
||||||
onColumnHeaderClick() {
|
onColumnHeaderClick(event, column) {
|
||||||
|
if (column.sortable) {
|
||||||
|
this.resetPage();
|
||||||
|
const targetNode = event.target;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
const columnField = column.field || column.sortField;
|
||||||
|
this.d_sortOrder = (this.d_sortField === columnField) ? this.d_sortOrder * -1 : this.defaultSortOrder;
|
||||||
|
this.d_sortField = columnField;
|
||||||
|
|
||||||
|
if(this.sortMode === 'multiple') {
|
||||||
|
let metaKey = event.metaKey || event.ctrlKey;
|
||||||
|
if (!metaKey) {
|
||||||
|
this.d_multiSortMeta = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addSortMeta({field: this.d_sortField, order: this.d_sortOrder});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('update:sortField', this.d_sortFied);
|
||||||
|
this.$emit('update:sortOrder', this.d_sortOrder);
|
||||||
|
this.$emit('update:multiSortMeta', this.d_multiSortMeta);
|
||||||
|
|
||||||
|
this.$emit('sort', {
|
||||||
|
originalEvent: event,
|
||||||
|
sortField: this.d_sortField,
|
||||||
|
sortOrder: this.d_sortOrder,
|
||||||
|
multiSortMeta: this.d_multiSortMeta
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addSortMeta(meta) {
|
||||||
|
let index = -1;
|
||||||
|
for (let i = 0; i < this.d_multiSortMeta.length; i++) {
|
||||||
|
if (this.d_multiSortMeta[i].field === meta.field) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(index >= 0)
|
||||||
|
this.d_multiSortMeta[index] = meta;
|
||||||
|
else
|
||||||
|
this.d_multiSortMeta.push(meta);
|
||||||
|
|
||||||
|
this.d_multiSortMeta = [...this.d_multiSortMeta];
|
||||||
|
},
|
||||||
|
sortSingle(nodes) {
|
||||||
|
return this.sortNodes(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);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i = 0; i < _nodes.length; i++) {
|
||||||
|
if (_nodes[i].children && _nodes[i].children.length) {
|
||||||
|
_nodes[i].children = this.sortNodesSingle(_nodes[i].children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _nodes;
|
||||||
|
},
|
||||||
|
sortMultiple(nodes) {
|
||||||
|
return this.sortNodesMultiple(nodes);
|
||||||
|
},
|
||||||
|
sortNodesMultiple(nodes) {
|
||||||
|
let _nodes = [...nodes];
|
||||||
|
_nodes.sort((node1, node2) => {
|
||||||
|
return this.multisortField(node1, node2, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i = 0; i < _nodes.length; i++) {
|
||||||
|
if (_nodes[i].children && _nodes[i].children.length) {
|
||||||
|
_nodes[i].children = this.sortNodesMultiple(_nodes[i].children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
},
|
},
|
||||||
isNodeSelected() {
|
isNodeSelected() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -297,7 +422,30 @@ export default {
|
||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
processedData() {
|
processedData() {
|
||||||
return this.value;
|
if (this.lazy) {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.value && this.value.length) {
|
||||||
|
let data = this.value;
|
||||||
|
|
||||||
|
if (this.sorted) {
|
||||||
|
if(this.sortMode === 'single')
|
||||||
|
data = this.sortSingle(data);
|
||||||
|
else if(this.sortMode === 'multiple')
|
||||||
|
data = this.sortMultiple(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (this.hasFilters) {
|
||||||
|
data = this.filter(data);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
dataToRender() {
|
dataToRender() {
|
||||||
const data = this.processedData;
|
const data = this.processedData;
|
||||||
|
@ -314,6 +462,9 @@ export default {
|
||||||
const data = this.processedData;
|
const data = this.processedData;
|
||||||
return (!data || data.length === 0);
|
return (!data || data.length === 0);
|
||||||
},
|
},
|
||||||
|
sorted() {
|
||||||
|
return this.d_sortField || (this.d_multiSortMeta && this.d_multiSortMeta.length > 0);
|
||||||
|
},
|
||||||
hasFooter() {
|
hasFooter() {
|
||||||
let hasFooter = false;
|
let hasFooter = false;
|
||||||
|
|
||||||
|
@ -374,6 +525,7 @@ export default {
|
||||||
|
|
||||||
.p-treetable .p-treetable-thead > tr > th .p-column-title {
|
.p-treetable .p-treetable-thead > tr > th .p-column-title {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-treetable .p-sortable-column {
|
.p-treetable .p-sortable-column {
|
||||||
|
|
|
@ -395,6 +395,11 @@ export default new Router({
|
||||||
path: '/treetable/paginator',
|
path: '/treetable/paginator',
|
||||||
name: 'treetablepaginator',
|
name: 'treetablepaginator',
|
||||||
component: () => import('./views/treetable/TreeTablePaginatorDemo.vue')
|
component: () => import('./views/treetable/TreeTablePaginatorDemo.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/treetable/sort',
|
||||||
|
name: 'treetablesort',
|
||||||
|
component: () => import('./views/treetable/TreeTableSortDemo.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/tristatecheckbox',
|
path: '/tristatecheckbox',
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<TreeTableSubMenu />
|
||||||
|
|
||||||
|
<div class="content-section introduction">
|
||||||
|
<div class="feature-intro">
|
||||||
|
<h1>TreeTable - Sort</h1>
|
||||||
|
<p>TreeTable supports both single column and multiple column sorting..</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-section implementation">
|
||||||
|
<h3>Single Column Sorting</h3>
|
||||||
|
<TreeTable :value="nodes" sortMode="single">
|
||||||
|
<Column field="name" header="Name" :expander="true" :sortable="true"></Column>
|
||||||
|
<Column field="size" header="Size" :sortable="true"></Column>
|
||||||
|
<Column field="type" header="Type" :sortable="true"></Column>
|
||||||
|
</TreeTable>
|
||||||
|
|
||||||
|
<h3>Multiple Column Sorting</h3>
|
||||||
|
<TreeTable :value="nodes" sortMode="multiple">
|
||||||
|
<Column field="name" header="Name" :expander="true" :sortable="true"></Column>
|
||||||
|
<Column field="size" header="Size" :sortable="true"></Column>
|
||||||
|
<Column field="type" header="Type" :sortable="true"></Column>
|
||||||
|
</TreeTable>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import NodeService from '../../service/NodeService';
|
||||||
|
import TreeTableSubMenu from './TreeTableSubMenu';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
nodes: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nodeService: null,
|
||||||
|
created() {
|
||||||
|
this.nodeService = new NodeService();
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.nodeService.getTreeTableNodes().then(data => this.nodes = data);
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'TreeTableSubMenu': TreeTableSubMenu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -4,6 +4,7 @@
|
||||||
<li><router-link to="/treetable">● Documentation</router-link></li>
|
<li><router-link to="/treetable">● Documentation</router-link></li>
|
||||||
<li><router-link to="/treetable/templating">● Templating</router-link></li>
|
<li><router-link to="/treetable/templating">● Templating</router-link></li>
|
||||||
<li><router-link to="/treetable/paginator">● Paginator</router-link></li>
|
<li><router-link to="/treetable/paginator">● Paginator</router-link></li>
|
||||||
|
<li><router-link to="/treetable/sort">● Sort</router-link></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue