From 6410ce1b5a91d9e0bf1ece98fb974955692bbd90 Mon Sep 17 00:00:00 2001 From: Bing Sun Date: Sun, 26 Apr 2020 15:27:09 +0800 Subject: [PATCH] Table: support simple pagination --- src/components/Table.js | 155 ++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 102 deletions(-) diff --git a/src/components/Table.js b/src/components/Table.js index 8eb2b1e..89fa595 100644 --- a/src/components/Table.js +++ b/src/components/Table.js @@ -8,6 +8,7 @@ export default initial_vnode => { // component state let model = initial_vnode.attrs.model + // displayed columns let columns = initial_vnode.attrs.columns if (!columns) { if (model.configs().selects) { @@ -17,16 +18,57 @@ export default initial_vnode => { } } + // pagination let offset = 0 - let limit = initial_vnode.attrs.pagination && initial_vnode.attrs.pagination.size - console.log(limit) + let limit = initial_vnode.attrs.pagination && initial_vnode.attrs.pagination.size || Infinity + let pages = [] // [{activie: boolean, show: boolean}] + + function generate_pages() { + if (limit > 0 && limit < Infinity && model.cache().count) { + let active_page = offset / limit + + pages = Array.from(Array(Math.floor(model.cache().count / limit) + 1)) + .map((_,i) => active_page == i ? {active: true} : {active: false}) + + if (pages.length <= 10) { + pages.forEach((_, i, pages) => pages[i].show = true) + } else { + // some wicked calculation + let _showed_pages = new Set([0, active_page, pages.length -1]) + let l = active_page, r = active_page + while (_showed_pages.size < 10) { + l -= 1 + if (l < 0) { + _showed_pages.add(r+1) + r += 1 + } else { + _showed_pages.add(l) + } + if (_showed_pages.size < 10) { + r += 1 + if (r >= pages.length) { + _showed_pages.add(l-1) + l -= 1 + } else { + _showed_pages.add(r) + } + } + } + _showed_pages.forEach(v => pages[v].show = true) + } + } + } + return { view: vnode => { - // try to generate columns if it is still undefined + // try to generate columns if it is still uninitialized if (typeof columns == 'undefined' || columns.length == 0) { - columns = model.data() && model.data().length && Object.keys(model.data()[0]).map(key => ({label: key})) || [] + columns = model.data(offset, limit) && model.data(offset, limit).length && Object.keys(model.data(offset, limit)[0]).map(key => ({label: key})) || [] } + // refresh paginations + generate_pages() + return [ m('table', [ // always show table header @@ -34,7 +76,7 @@ export default initial_vnode => { vnode.attrs.serial ? m('th.centered', '序号') : undefined, ...columns.map(column => m('th.centered', column.label)) ])), - model.data(offset).length ? m('tbody', model.data(offset).map((row, i) => m('tr', [ + model.data(offset, limit).length ? m('tbody', model.data(offset, limit).map((row, i) => m('tr', [ vnode.attrs.serial ? m('td.centered', offset+i+1) : undefined, ...columns.map(column => { let v = row[column.label] || '' @@ -46,107 +88,16 @@ export default initial_vnode => { }) ]))) : m('', 'Empty') ]), - /* _pages.length > 1 ? - m('.centered', - m('.pagination.centered', _pages.map((page, i) => page.show ? m('a', { - class: page.active ? 'active' : '', - onclick: e => { - _offset = i * vnode.attrs.options.paging.size - vnode.attrs.options.model.load({begin: i * vnode.attrs.options.paging.size, end: (i+1) * vnode.attrs.options.paging.size}) - } - }, i + 1) : undefined)) - ) - : undefined*/ - ] - } - } -} - -export const default1 = _ => { - let _columns = [] - let _offset= 0 - let _pages = [] - let _model_slice = [] - - return { - view: vnode => { - // prepare columns by merging model.selects and columns config - _columns = Array.from(vnode.attrs.options.model.configs().selects, ([label, select]) => ({ - label: select.alias || label, - tag: vnode.attrs.options.columns[label] && vnode.attrs.options.columns[label].tag - })) - - if (vnode.attrs.options.model.ambient_changed()) - _offset = 0 - - // prepare pages - if (vnode.attrs.options.paging && vnode.attrs.options.model.count) { - _offset = ~~_offset - let _active_page = _offset / vnode.attrs.options.paging.size - _pages = Array.from(Array(vnode.attrs.options.paging.size ? Math.floor(~~vnode.attrs.options.model.count / vnode.attrs.options.paging.size) + 1 : 0)).map((_,i) => _active_page == i ? {active: true} : {active: false}) - - if (_pages.length <= 10) { - _pages.forEach((page, i, pages) => pages[i].show = true) - } else { - let _showed_pages = new Set([0, _active_page, _pages.length -1]) - let l = _active_page, r = _active_page - while (_showed_pages.size < 10) { - l -= 1 - if (l < 0) { - _showed_pages.add(r+1) - r += 1 - } else { - _showed_pages.add(l) - } - if (_showed_pages.size < 10) { - r += 1 - if (r >= _pages.length) { - _showed_pages.add(l-1) - l -= 1 - } else { - _showed_pages.add(r) - } - } - } - _showed_pages.forEach(v => _pages[v].show = true) - } - } - - // visible model - function get_model_slice() { - return vnode.attrs.options.model.list.slice(_offset, _offset + ~~(vnode.attrs.options.paging && vnode.attrs.options.paging.size || 200)) - } - - return [ - m('table', [ - // always show table header - m('thead', m('tr', [ - vnode.attrs.options.prepend_serial ? m('th.centered', '序号') : undefined, - ..._columns.map(col => m('th.centered', col.label)) - ])), - get_model_slice().length ? m('tbody', get_model_slice().map((row, i) => m('tr', [ - vnode.attrs.options.prepend_serial ? m('td.centered', _offset+i+1) : undefined, - ..._columns.map(col => { - let v = row[col.label] || '' - - if (typeof col.tag != 'undefined') - v = m(col.tag, v) - - return m(`td${col.class || ''}`, v) - }) - ]))) : m('', 'Empty') - ]), - _pages.length > 1 ? + pages.length > 1 ? m('.centered', - m('.pagination.centered', _pages.map((page, i) => page.show ? m('a', { + m('.pagination.centered', pages.map((page, i) => page.show ? m('a', { class: page.active ? 'active' : '', onclick: e => { - _offset = i * vnode.attrs.options.paging.size - vnode.attrs.options.model.load({begin: i * vnode.attrs.options.paging.size, end: (i+1) * vnode.attrs.options.paging.size}) + offset = i*limit + model.select(offset, limit) } - }, i + 1) : undefined)) - ) - : undefined + }, i+1) : undefined)) + ) : undefined ] } }