Single column sorting for table
parent
012f8185f4
commit
ff20a00e8f
|
@ -17,8 +17,9 @@
|
||||||
<table>
|
<table>
|
||||||
<thead class="p-datatable-thead">
|
<thead class="p-datatable-thead">
|
||||||
<tr>
|
<tr>
|
||||||
<th v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.headerStyle" :class="col.headerClass">
|
<th v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.headerStyle" :class="getColumnHeaderClass(col)" @click="onColumnHeaderClick($event, col)">
|
||||||
<span class="p-column-title" v-if="col.header">{{col.header}}</span>
|
<span class="p-column-title" v-if="col.header">{{col.header}}</span>
|
||||||
|
<span v-if="col.sortable" :class="getSortableColumnIcon(col)"></span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -56,6 +57,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ObjectUtils from '../utils/ObjectUtils';
|
import ObjectUtils from '../utils/ObjectUtils';
|
||||||
|
import DomHandler from '../utils/DomHandler';
|
||||||
import Paginator from '../paginator/Paginator';
|
import Paginator from '../paginator/Paginator';
|
||||||
|
|
||||||
const ColumnSlot = {
|
const ColumnSlot = {
|
||||||
|
@ -144,13 +146,27 @@ export default {
|
||||||
loadingIcon: {
|
loadingIcon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'pi pi-spinner'
|
default: 'pi pi-spinner'
|
||||||
|
},
|
||||||
|
sortField: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
sortOrder: {
|
||||||
|
type: Number,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
defaultSortOrder: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
columns: [],
|
columns: [],
|
||||||
d_first: this.first,
|
d_first: this.first,
|
||||||
d_rows: this.rows
|
d_rows: this.rows,
|
||||||
|
d_sortField: this.sortField,
|
||||||
|
d_sortOrder: this.sortOrder
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -159,11 +175,16 @@ export default {
|
||||||
},
|
},
|
||||||
rows(newValue) {
|
rows(newValue) {
|
||||||
this.d_rows = newValue;
|
this.d_rows = newValue;
|
||||||
|
},
|
||||||
|
sortField(newValue) {
|
||||||
|
this.d_sortField = newValue;
|
||||||
|
},
|
||||||
|
sortOrder(newValue) {
|
||||||
|
this.d_sortOrder = newValue;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.columns = this.$children.filter(child => child.$options._propKeys.indexOf('columnKey') !== -1);
|
this.columns = this.$children.filter(child => child.$options._propKeys.indexOf('columnKey') !== -1);
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getRowKey(rowData, index) {
|
getRowKey(rowData, index) {
|
||||||
|
@ -179,6 +200,67 @@ export default {
|
||||||
this.$emit('update:first', this.d_first);
|
this.$emit('update:first', this.d_first);
|
||||||
this.$emit('update:rows', this.d_rows);
|
this.$emit('update:rows', this.d_rows);
|
||||||
this.$emit('page', event);
|
this.$emit('page', event);
|
||||||
|
},
|
||||||
|
onColumnHeaderClick($event, column) {
|
||||||
|
if (column.sortable) {
|
||||||
|
let targetNode = event.target;
|
||||||
|
let columnField = column.field || column.sortField;
|
||||||
|
|
||||||
|
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')) {
|
||||||
|
|
||||||
|
this.d_sortOrder = (this.d_sortField === columnField) ? this.d_sortOrder * -1 : this.defaultSortOrder;
|
||||||
|
this.d_sortField = columnField;
|
||||||
|
DomHandler.clearSelection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sort(value) {
|
||||||
|
if (value) {
|
||||||
|
let data = [...this.value];
|
||||||
|
|
||||||
|
data.sort((data1, data2) => {
|
||||||
|
let value1 = ObjectUtils.resolveFieldData(data1, this.d_sortField);
|
||||||
|
let value2 = ObjectUtils.resolveFieldData(data2, this.d_sortField);
|
||||||
|
let result = null;
|
||||||
|
|
||||||
|
if (value1 == null && value2 != null)
|
||||||
|
result = -1;
|
||||||
|
else if (value1 != null && value2 == null)
|
||||||
|
result = 1;
|
||||||
|
else if (value1 == null && value2 == null)
|
||||||
|
result = 0;
|
||||||
|
else if (typeof value1 === 'string' && typeof value2 === 'string')
|
||||||
|
result = value1.localeCompare(value2, undefined, { numeric: true });
|
||||||
|
else
|
||||||
|
result = (value1 < value2) ? -1 : (value1 > value2) ? 1 : 0;
|
||||||
|
|
||||||
|
return (this.d_sortOrder * result);
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getColumnHeaderClass(column) {
|
||||||
|
const sorted = this.d_sortField === (column.field || column.sortField);
|
||||||
|
|
||||||
|
return [column.headerClass,
|
||||||
|
{'p-sortable-column': column.sortable},
|
||||||
|
{'p-highlight': sorted}
|
||||||
|
];
|
||||||
|
},
|
||||||
|
getSortableColumnIcon(column) {
|
||||||
|
const sorted = this.d_sortField === (column.field || column.sortField);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'p-sortable-column-icon pi pi-fw',
|
||||||
|
{'pi-sort': !sorted},
|
||||||
|
{'pi-sort-up': sorted && this.d_sortOrder > 0},
|
||||||
|
{'pi-sort-down': sorted && this.d_sortOrder < 0},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -186,9 +268,9 @@ export default {
|
||||||
if (this.value && this.value.length) {
|
if (this.value && this.value.length) {
|
||||||
let data = this.value;
|
let data = this.value;
|
||||||
|
|
||||||
/*if (data && data.length && this.sortField) {
|
if (data && data.length && this.d_sortField) {
|
||||||
data = this.sort();
|
data = this.sort(data);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
if (this.paginator) {
|
if (this.paginator) {
|
||||||
const first = this.lazy ? 0 : this.d_first;
|
const first = this.lazy ? 0 : this.d_first;
|
||||||
|
|
|
@ -121,6 +121,11 @@ export default new Router({
|
||||||
name: 'datatablepaginator',
|
name: 'datatablepaginator',
|
||||||
component: () => import('./views/datatable/DataTablePaginatorDemo.vue')
|
component: () => import('./views/datatable/DataTablePaginatorDemo.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/datatable/sort',
|
||||||
|
name: 'datatablesort',
|
||||||
|
component: () => import('./views/datatable/DataTableSortDemo.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/dataview',
|
path: '/dataview',
|
||||||
name: 'dataview',
|
name: 'dataview',
|
||||||
|
|
|
@ -19,9 +19,11 @@
|
||||||
</DataTable>
|
</DataTable>
|
||||||
|
|
||||||
<h3>Dynamic Columns</h3>
|
<h3>Dynamic Columns</h3>
|
||||||
<DataTable :value="cars">
|
<DataTable :value="cars" :columns="columns">
|
||||||
<Column v-for="col of columns" :field="col.field" :header="col.header" :key="col.field"></Column>
|
<Column v-for="col of columns" :field="col.field" :header="col.header" :key="col.field"></Column>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
|
|
||||||
|
<button type="button" @click="add">Add</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DataTableDoc />
|
<DataTableDoc />
|
||||||
|
@ -37,7 +39,8 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
columns: null,
|
columns: null,
|
||||||
cars: null
|
cars: null,
|
||||||
|
i: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
carService: null,
|
carService: null,
|
||||||
|
@ -54,6 +57,13 @@ export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
this.carService.getCarsSmall().then(data => this.cars = data);
|
this.carService.getCarsSmall().then(data => this.cars = data);
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
add() {
|
||||||
|
this.i++;
|
||||||
|
this.columns.push({field: 'color' + this.i, header: 'Color' + this.i});
|
||||||
|
this.columns = [...this.columns];
|
||||||
|
}
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
'DataTableDoc': DataTableDoc,
|
'DataTableDoc': DataTableDoc,
|
||||||
'DataTableSubMenu': DataTableSubMenu
|
'DataTableSubMenu': DataTableSubMenu
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<DataTableSubMenu />
|
||||||
|
|
||||||
|
<div class="content-section introduction">
|
||||||
|
<div class="feature-intro">
|
||||||
|
<h1>DataTable - Sort</h1>
|
||||||
|
<p>Enabling sortable property on a column is enough to make a column sortable. Multiple column sorting is enabled using sortMode property and used with metaKey.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-section implementation">
|
||||||
|
<DataTable :value="cars">
|
||||||
|
<Column field="vin" header="Vin" :sortable="true"></Column>
|
||||||
|
<Column field="year" header="Year" :sortable="true"></Column>
|
||||||
|
<Column field="brand" header="Brand" :sortable="true"></Column>
|
||||||
|
<Column field="color" header="Color" :sortable="true"></Column>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CarService from '../../service/CarService';
|
||||||
|
import DataTableSubMenu from './DataTableSubMenu';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
cars: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
carService: null,
|
||||||
|
created() {
|
||||||
|
this.carService = new CarService();
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.carService.getCarsSmall().then(data => this.cars = data);
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'DataTableSubMenu': DataTableSubMenu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in New Issue