diff --git a/src/components/Table.js b/src/components/Table.js new file mode 100644 index 0000000..8eb2b1e --- /dev/null +++ b/src/components/Table.js @@ -0,0 +1,153 @@ +/* + columns: , + serial: true/false, + model_options: +*/ + +export default initial_vnode => { + // component state + let model = initial_vnode.attrs.model + + let columns = initial_vnode.attrs.columns + if (!columns) { + if (model.configs().selects) { + _columns = model.configs().selects.map(select => ({ + label: select.alias || select.label + })) + } + } + + let offset = 0 + let limit = initial_vnode.attrs.pagination && initial_vnode.attrs.pagination.size + console.log(limit) + return { + view: vnode => { + // try to generate columns if it is still undefined + if (typeof columns == 'undefined' || columns.length == 0) { + columns = model.data() && model.data().length && Object.keys(model.data()[0]).map(key => ({label: key})) || [] + } + + return [ + m('table', [ + // always show table header + m('thead', m('tr', [ + 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', [ + vnode.attrs.serial ? m('td.centered', offset+i+1) : undefined, + ...columns.map(column => { + let v = row[column.label] || '' + + if (typeof column.tag != 'undefined') + v = m(column.tag, v) + + return m(`td${column.class || ''}`, v) + }) + ]))) : 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 ? + 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 + ] + } + } +}