Pagination for TreeTable

pull/41/head
cagataycivici 2019-08-06 12:23:39 +03:00
parent dfe2943280
commit ce2186fe30
4 changed files with 173 additions and 2 deletions

View File

@ -4,6 +4,15 @@
<div class="p-treetable-header" v-if="$scopedSlots.header"> <div class="p-treetable-header" v-if="$scopedSlots.header">
<slot name="header"></slot> <slot name="header"></slot>
</div> </div>
<TTPaginator v-if="paginatorTop" :rows="d_rows" :first="d_first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
:currentPageReportTemplate="currentPageReportTemplate" class="p-paginator-top" @page="onPage($event)" :alwaysShow="alwaysShowPaginator">
<template #left v-if="$scopedSlots.paginatorLeft">
<slot name="paginatorLeft"></slot>
</template>
<template #right v-if="$scopedSlots.paginatorRight">
<slot name="paginatorRight"></slot>
</template>
</TTPaginator>
<div class="p-treetable-wrapper"> <div class="p-treetable-wrapper">
<table> <table>
<thead class="p-treetable-thead"> <thead class="p-treetable-thead">
@ -26,7 +35,7 @@
</tfoot> </tfoot>
<tbody class="p-treetable-tbody"> <tbody class="p-treetable-tbody">
<template v-if="!empty"> <template v-if="!empty">
<TTRow v-for="node of value" :key="node.key" :columns="columns" :node="node" :level="0" <TTRow v-for="node of dataToRender" :key="node.key" :columns="columns" :node="node" :level="0"
:expandedKeys="d_expandedKeys" @node-toggle="onNodeToggle" :expandedKeys="d_expandedKeys" @node-toggle="onNodeToggle"
:selectionMode="selectionMode" :selectionKeys="selectionKeys"></TTRow> :selectionMode="selectionMode" :selectionKeys="selectionKeys"></TTRow>
</template> </template>
@ -38,6 +47,15 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<TTPaginator v-if="paginatorBottom" :rows="d_rows" :first="d_first" :totalRecords="totalRecordsLength" :pageLinkSize="pageLinkSize" :template="paginatorTemplate" :rowsPerPageOptions="rowsPerPageOptions"
:currentPageReportTemplate="currentPageReportTemplate" class="p-paginator-bottom" @page="onPage($event)" :alwaysShow="alwaysShowPaginator">
<template #left v-if="$scopedSlots.paginatorLeft">
<slot name="paginatorLeft"></slot>
</template>
<template #right v-if="$scopedSlots.paginatorRight">
<slot name="paginatorRight"></slot>
</template>
</TTPaginator>
<div class="p-treetable-footer" v-if="$scopedSlots.header"> <div class="p-treetable-footer" v-if="$scopedSlots.header">
<slot name="footer"></slot> <slot name="footer"></slot>
</div> </div>
@ -47,6 +65,7 @@
<script> <script>
import TreeTableColumnSlot from './TreeTableColumnSlot'; import TreeTableColumnSlot from './TreeTableColumnSlot';
import TreeTableRowLoader from './TreeTableRowLoader'; import TreeTableRowLoader from './TreeTableRowLoader';
import Paginator from '../paginator/Paginator';
export default { export default {
props: { props: {
@ -70,6 +89,50 @@ export default {
type: Boolean, type: Boolean,
default: true 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: { loading: {
type: Boolean, type: Boolean,
default: false default: false
@ -157,6 +220,18 @@ export default {
this.d_expandedKeys = {...this.d_expandedKeys}; this.d_expandedKeys = {...this.d_expandedKeys};
this.$emit('update:expandedKeys', this.d_expandedKeys); this.$emit('update:expandedKeys', this.d_expandedKeys);
}, },
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);
},
resetPage() {
this.d_first = 0;
this.$emit('update:first', this.d_first);
},
getColumnHeaderClass(column) { getColumnHeaderClass(column) {
const sorted = this.sortMode === 'single' ? (this.d_sortField === (column.field || column.sortField)) : this.getMultiSortMetaIndex(column) > -1; const sorted = this.sortMode === 'single' ? (this.d_sortField === (column.field || column.sortField)) : this.getMultiSortMetaIndex(column) > -1;
@ -224,6 +299,17 @@ export default {
processedData() { processedData() {
return this.value; return this.value;
}, },
dataToRender() {
const data = this.processedData;
if (this.paginator) {
const first = this.lazy ? 0 : this.d_first;
return data.slice(first, first + this.d_rows);
}
else {
return data;
}
},
empty() { empty() {
const data = this.processedData; const data = this.processedData;
return (!data || data.length === 0); return (!data || data.length === 0);
@ -239,11 +325,27 @@ export default {
} }
return hasFooter; return hasFooter;
},
paginatorTop() {
return this.paginator && (this.paginatorPosition !== 'bottom' || this.paginatorPosition === 'both');
},
paginatorBottom() {
return this.paginator && (this.paginatorPosition !== 'top' || this.paginatorPosition === 'both');
},
totalRecordsLength() {
if (this.lazy) {
return this.totalRecords;
}
else {
const data = this.processedData;
return data ? data.length : 0;
}
} }
}, },
components: { components: {
'TTColumnSlot': TreeTableColumnSlot, 'TTColumnSlot': TreeTableColumnSlot,
'TTRow': TreeTableRowLoader 'TTRow': TreeTableRowLoader,
'TTPaginator': Paginator,
} }
} }
</script> </script>

View File

@ -390,6 +390,11 @@ export default new Router({
path: '/treetable/templating', path: '/treetable/templating',
name: 'treetabletemplating', name: 'treetabletemplating',
component: () => import('./views/treetable/TreeTableTemplatingDemo.vue') component: () => import('./views/treetable/TreeTableTemplatingDemo.vue')
},
{
path: '/treetable/paginator',
name: 'treetablepaginator',
component: () => import('./views/treetable/TreeTablePaginatorDemo.vue')
}, },
{ {
path: '/tristatecheckbox', path: '/tristatecheckbox',

View File

@ -0,0 +1,63 @@
<template>
<div>
<TreeTableSubMenu />
<div class="content-section introduction">
<div class="feature-intro">
<h1>TreeTable - Paginator</h1>
<p>Pagination is enabled by setting paginator property to true and defining the rows attribute as the number of root level nodes per page.</p>
</div>
</div>
<div class="content-section implementation">
<TreeTable :value="nodes" :paginator="true" :rows="10">
<Column field="name" header="Name" :expander="true"></Column>
<Column field="size" header="Size"></Column>
<Column field="type" header="Type"></Column>
</TreeTable>
</div>
</div>
</template>
<script>
import TreeTableSubMenu from './TreeTableSubMenu';
export default {
data() {
return {
nodes: null
}
},
nodeService: null,
created() {
let files = [];
for(let i = 0; i < 50; i++) {
let node = {
key: i,
data: {
name: 'Item ' + i,
size: Math.floor(Math.random() * 1000) + 1 + 'kb',
type: 'Type ' + i
},
children: [
{
key: i + ' - 0',
data: {
name: 'Item ' + i + ' - 0',
size: Math.floor(Math.random() * 1000) + 1 + 'kb',
type: 'Type ' + i
}
}
]
};
files.push(node);
}
this.nodes = files;
},
components: {
'TreeTableSubMenu': TreeTableSubMenu
}
}
</script>

View File

@ -3,6 +3,7 @@
<ul> <ul>
<li><router-link to="/treetable">&#9679; Documentation</router-link></li> <li><router-link to="/treetable">&#9679; Documentation</router-link></li>
<li><router-link to="/treetable/templating">&#9679; Templating</router-link></li> <li><router-link to="/treetable/templating">&#9679; Templating</router-link></li>
<li><router-link to="/treetable/paginator">&#9679; Paginator</router-link></li>
</ul> </ul>
</div> </div>
</template> </template>