Paginator for DataTable
parent
793b2276af
commit
6f20655a74
|
@ -2,9 +2,18 @@
|
|||
<div class="p-datatable p-component">
|
||||
<slot></slot>
|
||||
<div class="p-datatable-wrapper">
|
||||
<div class="p-datatable-header" v-if="$scopedSlots.header">
|
||||
<div class="p-datatable-header" v-if="$slots.header">
|
||||
<slot name="header"></slot>
|
||||
</div>
|
||||
<DTPaginator v-if="paginatorTop" :rows="rows" :first="first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
||||
:currentPageReportTemplate="currentPageReportTemplate" :class="{'p-paginator-top': paginatorTop}" @page="onPage($event)">
|
||||
<template #left v-if="$scopedSlots.paginatorLeft">
|
||||
<slot name="paginatorLeft"></slot>
|
||||
</template>
|
||||
<template #right v-if="$scopedSlots.paginatorRight">
|
||||
<slot name="paginatorRight"></slot>
|
||||
</template>
|
||||
</DTPaginator>
|
||||
<table>
|
||||
<thead class="p-datatable-thead">
|
||||
<tr>
|
||||
|
@ -14,7 +23,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody class="p-datatable-tbody">
|
||||
<tr class="p-datatable-row" v-for="(rowData, index) of value" :key="getRowKey(rowData, index)">
|
||||
<tr class="p-datatable-row" v-for="(rowData, index) of data" :key="getRowKey(rowData, index)">
|
||||
<td v-for="(col,i) of columns" :key="col.columnKey||col.field||i" :style="col.bodyStyle" :class="col.bodyClass">
|
||||
<ColumnSlot :data="rowData" :column="col" type="body" v-if="col.$scopedSlots.body" />
|
||||
<template v-else>{{resolveFieldData(rowData, col.field)}}</template>
|
||||
|
@ -22,12 +31,25 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<DTPaginator v-if="paginatorBottom" :rows="rows" :first="first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
||||
:currentPageReportTemplate="currentPageReportTemplate" :class="{'p-paginator-bottom': paginatorBottom}" @page="onPage($event)">
|
||||
<template #left v-if="$scopedSlots.paginatorLeft">
|
||||
<slot name="paginatorLeft"></slot>
|
||||
</template>
|
||||
<template #right v-if="$scopedSlots.paginatorRight">
|
||||
<slot name="paginatorRight"></slot>
|
||||
</template>
|
||||
</DTPaginator>
|
||||
<div class="p-datatable-footer" v-if="$slots.footer">
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ObjectUtils from '../utils/ObjectUtils';
|
||||
import Paginator from '../paginator/Paginator';
|
||||
|
||||
const ColumnSlot = {
|
||||
functional: true,
|
||||
|
@ -63,13 +85,67 @@ export default {
|
|||
dataKey: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
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
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
columns: []
|
||||
columns: [],
|
||||
d_first: this.first,
|
||||
d_rows: this.rows
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
first(newValue) {
|
||||
this.d_first = newValue;
|
||||
},
|
||||
rows(newValue) {
|
||||
this.d_rows = newValue;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.columns = [...this.$children];
|
||||
},
|
||||
|
@ -79,10 +155,65 @@ export default {
|
|||
},
|
||||
resolveFieldData(rowData, field) {
|
||||
return ObjectUtils.resolveFieldData(rowData, field);
|
||||
},
|
||||
onPage(event) {
|
||||
this.d_first = event.first;
|
||||
this.d_rows = event.rows;
|
||||
|
||||
this.$emit('update:first', this.d_first);
|
||||
this.$emit('update:rows', this.d_rows);
|
||||
this.$emit('page', event);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
data() {
|
||||
if (this.value && this.value.length) {
|
||||
let data = this.value;
|
||||
|
||||
/*if (data && data.length && this.sortField) {
|
||||
data = this.sort();
|
||||
}*/
|
||||
|
||||
if (this.paginator) {
|
||||
const first = this.lazy ? 0 : this.d_first;
|
||||
return data.slice(first, first + this.d_rows);
|
||||
}
|
||||
else {
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
totalRecordsLength() {
|
||||
if (this.totalRecords)
|
||||
return this.totalRecords;
|
||||
else
|
||||
return this.value ? this.value.length : 0;
|
||||
},
|
||||
empty() {
|
||||
return (!this.value || this.value.length === 0);
|
||||
},
|
||||
paginatorTop() {
|
||||
if (this.paginatorPosition && (this.paginatorPosition !== 'bottom' || this.paginatorPosition === 'both')) {
|
||||
return true
|
||||
}
|
||||
else
|
||||
return null;
|
||||
},
|
||||
paginatorBottom() {
|
||||
if (this.paginatorPosition && (this.paginatorPosition !== 'top' || this.paginatorPosition === 'both')) {
|
||||
return true
|
||||
}
|
||||
else
|
||||
return null;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
'ColumnSlot': ColumnSlot
|
||||
'ColumnSlot': ColumnSlot,
|
||||
'DTPaginator': Paginator
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class="p-dataview-header" v-if="$scopedSlots.header">
|
||||
<slot name="header"></slot>
|
||||
</div>
|
||||
<Paginator v-if="paginatorTop" :rows="rows" :first="first" :totalRecords="getTotalRecords" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
||||
<DVPaginator v-if="paginatorTop" :rows="rows" :first="first" :totalRecords="getTotalRecords" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
||||
:currentPageReportTemplate="currentPageReportTemplate" :class="{'p-paginator-top': paginatorTop}" @page="onPage($event)">
|
||||
<template #left v-if="$scopedSlots.paginatorLeft">
|
||||
<slot name="paginatorLeft"></slot>
|
||||
|
@ -11,7 +11,7 @@
|
|||
<template #right v-if="$scopedSlots.paginatorRight">
|
||||
<slot name="paginatorRight"></slot>
|
||||
</template>
|
||||
</Paginator>
|
||||
</DVPaginator>
|
||||
<div class="p-dataview-content">
|
||||
<div class="p-grid">
|
||||
<template v-for="(item,index) of items">
|
||||
|
@ -21,7 +21,7 @@
|
|||
<div v-if="isEmpty" class="p-col-12">{{emptyMessage}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<Paginator v-if="paginatorBottom" :rows="rows" :first="first" :totalRecords="getTotalRecords" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
||||
<DVPaginator v-if="paginatorBottom" :rows="rows" :first="first" :totalRecords="getTotalRecords" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
|
||||
:currentPageReportTemplate="currentPageReportTemplate" :class="{'p-paginator-bottom': paginatorBottom}" @page="onPage($event)">
|
||||
<template #left v-if="$scopedSlots.paginatorLeft">
|
||||
<slot name="paginatorLeft"></slot>
|
||||
|
@ -29,188 +29,193 @@
|
|||
<template #right v-if="$scopedSlots.paginatorRight">
|
||||
<slot name="paginatorRight"></slot>
|
||||
</template>
|
||||
</Paginator>
|
||||
</DVPaginator>
|
||||
<div class="p-dataview-footer" v-if="$scopedSlots.footer">
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import ObjectUtils from '../utils/ObjectUtils';
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'list'
|
||||
},
|
||||
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})'
|
||||
},
|
||||
emptyMessage: {
|
||||
type: String,
|
||||
default: 'No records found'
|
||||
},
|
||||
sortField: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
sortOrder: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
lazy: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
import ObjectUtils from '../utils/ObjectUtils';
|
||||
import Paginator from '../paginator/Paginator';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
d_first: this.first,
|
||||
d_rows: this.rows
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'list'
|
||||
},
|
||||
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})'
|
||||
},
|
||||
emptyMessage: {
|
||||
type: String,
|
||||
default: 'No records found'
|
||||
},
|
||||
sortField: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
sortOrder: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
lazy: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
d_first: this.first,
|
||||
d_rows: this.rows
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
first(newValue) {
|
||||
this.d_first = newValue;
|
||||
},
|
||||
rows(newValue) {
|
||||
this.d_rows = newValue;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onPage(event) {
|
||||
this.d_first = event.first;
|
||||
this.d_rows = event.rows;
|
||||
|
||||
this.$emit('update:first', this.d_first);
|
||||
this.$emit('update:rows', this.d_rows);
|
||||
this.$emit('page', event);
|
||||
},
|
||||
sort() {
|
||||
if (this.value) {
|
||||
const value = [...this.value];
|
||||
|
||||
value.sort((data1, data2) => {
|
||||
let value1 = ObjectUtils.resolveFieldData(data1, this.sortField);
|
||||
let value2 = ObjectUtils.resolveFieldData(data2, this.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.sortOrder * result);
|
||||
});
|
||||
|
||||
return value;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
first(newValue) {
|
||||
this.d_first = newValue;
|
||||
},
|
||||
rows(newValue) {
|
||||
this.d_rows = newValue;
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
containerClass() {
|
||||
return ['p-dataview p-component', {
|
||||
'p-dataview-list': (this.layout === 'list'),
|
||||
'p-dataview-grid': (this.layout === 'grid')
|
||||
}
|
||||
]
|
||||
},
|
||||
methods: {
|
||||
onPage(event) {
|
||||
this.d_first = event.first;
|
||||
this.d_rows = event.rows;
|
||||
getTotalRecords() {
|
||||
if (this.totalRecords)
|
||||
return this.totalRecords;
|
||||
else
|
||||
return this.value ? this.value.length : 0;
|
||||
},
|
||||
isEmpty() {
|
||||
return (!this.value || this.value.length === 0);
|
||||
},
|
||||
paginatorTop() {
|
||||
if (this.paginatorPosition && (this.paginatorPosition !== 'bottom' || this.paginatorPosition === 'both')) {
|
||||
return true
|
||||
}
|
||||
else
|
||||
return null;
|
||||
},
|
||||
paginatorBottom() {
|
||||
if (this.paginatorPosition && (this.paginatorPosition !== 'top' || this.paginatorPosition === 'both')) {
|
||||
return true
|
||||
}
|
||||
else
|
||||
return null;
|
||||
},
|
||||
items() {
|
||||
if (this.value && this.value.length) {
|
||||
let data = this.value;
|
||||
|
||||
this.$emit('update:first', this.d_first);
|
||||
this.$emit('update:rows', this.d_rows);
|
||||
this.$emit('page', event);
|
||||
},
|
||||
sort() {
|
||||
if (this.value) {
|
||||
const value = [...this.value];
|
||||
|
||||
value.sort((data1, data2) => {
|
||||
let value1 = ObjectUtils.resolveFieldData(data1, this.sortField);
|
||||
let value2 = ObjectUtils.resolveFieldData(data2, this.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.sortOrder * result);
|
||||
});
|
||||
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
containerClass() {
|
||||
return ['p-dataview p-component', {
|
||||
'p-dataview-list': (this.layout === 'list'),
|
||||
'p-dataview-grid': (this.layout === 'grid')
|
||||
}
|
||||
]
|
||||
},
|
||||
getTotalRecords() {
|
||||
if (this.totalRecords)
|
||||
return this.totalRecords;
|
||||
else
|
||||
return this.value ? this.value.length : 0;
|
||||
},
|
||||
isEmpty() {
|
||||
return (!this.value || this.value.length === 0);
|
||||
},
|
||||
paginatorTop() {
|
||||
if (this.paginatorPosition && (this.paginatorPosition !== 'bottom' || this.paginatorPosition === 'both')) {
|
||||
return true
|
||||
}
|
||||
else
|
||||
return null;
|
||||
},
|
||||
paginatorBottom() {
|
||||
if (this.paginatorPosition && (this.paginatorPosition !== 'top' || this.paginatorPosition === 'both')) {
|
||||
return true
|
||||
}
|
||||
else
|
||||
return null;
|
||||
},
|
||||
items() {
|
||||
if (this.value && this.value.length) {
|
||||
let data = this.value;
|
||||
|
||||
if (data && data.length && this.sortField) {
|
||||
data = this.sort();
|
||||
}
|
||||
|
||||
if (this.paginator) {
|
||||
const first = this.lazy ? 0 : this.d_first;
|
||||
return data.slice(first, first + this.d_rows);
|
||||
}
|
||||
else {
|
||||
return data;
|
||||
}
|
||||
|
||||
if (data && data.length && this.sortField) {
|
||||
data = this.sort();
|
||||
}
|
||||
|
||||
if (this.paginator) {
|
||||
const first = this.lazy ? 0 : this.d_first;
|
||||
return data.slice(first, first + this.d_rows);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'DVPaginator': Paginator
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -115,6 +115,11 @@ export default new Router({
|
|||
path: '/datatable/templating',
|
||||
name: 'datatabletemplating',
|
||||
component: () => import('./views/datatable/DataTableTemplatingDemo.vue')
|
||||
},
|
||||
{
|
||||
path: '/datatable/paginator',
|
||||
name: 'datatablepaginator',
|
||||
component: () => import('./views/datatable/DataTablePaginatorDemo.vue')
|
||||
},
|
||||
{
|
||||
path: '/dataview',
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<div>
|
||||
<DataTableSubMenu />
|
||||
|
||||
<div class="content-section introduction">
|
||||
<div class="feature-intro">
|
||||
<h1>DataTable - Paginator</h1>
|
||||
<p>Pagination is enabled by setting paginator property to true and defining the rows attribute as the number of rows per page.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-section implementation">
|
||||
<DataTable :value="cars" :paginator="true" :rows="10">
|
||||
<Column field="vin" header="Vin"></Column>
|
||||
<Column field="year" header="Year"></Column>
|
||||
<Column field="brand" header="Brand"></Column>
|
||||
<Column field="color" header="Color"></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.getCarsLarge().then(data => this.cars = data);
|
||||
},
|
||||
components: {
|
||||
'DataTableSubMenu': DataTableSubMenu
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -11,6 +11,12 @@
|
|||
|
||||
<div class="content-section implementation">
|
||||
<DataTable :value="cars">
|
||||
<template #header>
|
||||
<div style="line-height:1.87em" class="clearfix">
|
||||
<Button icon="pi pi-refresh" style="float: right"/>
|
||||
List of Cars
|
||||
</div>
|
||||
</template>
|
||||
<Column field="vin" header="Vin"></Column>
|
||||
<Column field="year" header="Year"></Column>
|
||||
<Column field="brand" header="Brand">
|
||||
|
@ -25,6 +31,9 @@
|
|||
<Button type="button" icon="pi pi-pencil" class="p-button-warning"></Button>
|
||||
</template>
|
||||
</Column>
|
||||
<template #footer>
|
||||
In total there are {{cars.length}} cars.
|
||||
</template>
|
||||
</DataTable>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -37,7 +46,6 @@ import DataTableSubMenu from './DataTableSubMenu';
|
|||
export default {
|
||||
data() {
|
||||
return {
|
||||
columns: null,
|
||||
cars: null
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue