From 1a71444c220ade2a60d6c89fe7d3ddb434daa2dd Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Sun, 15 Oct 2017 15:49:23 +0200 Subject: [PATCH] Added table pagination support. --- .../_application_controller_table.coffee | 52 +++- .../app/views/generic/table.jst.eco | 4 +- .../app/views/generic/table_pager.jst.eco | 5 + public/assets/tests/table_extended.js | 277 ++++++++++++++++++ 4 files changed, 331 insertions(+), 7 deletions(-) create mode 100644 app/assets/javascripts/app/views/generic/table_pager.jst.eco diff --git a/app/assets/javascripts/app/controllers/_application_controller_table.coffee b/app/assets/javascripts/app/controllers/_application_controller_table.coffee index b1db59e9f..40725e035 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_table.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_table.coffee @@ -112,12 +112,14 @@ class App.ControllerTable extends App.Controller renderState: undefined groupBy: undefined + shownPerPage: 150 + shownPage: 0 + destroy: false columnsLength: undefined headers: undefined headerWidth: {} - maxShown: 150 currentRows: [] @@ -142,8 +144,7 @@ class App.ControllerTable extends App.Controller @overviewAttributes ||= @overview || @model.configure_overview || [] @attributesListRaw ||= @attribute_list || @model.configure_attributes || {} @attributesList = App.Model.attributesGet(false, @attributesListRaw) - #@setHeaderWidths = App.Model.setHeaderWidthsGet(false, @attributesList) - @destroy = @model.configure_delete + @destroy = @model.configure_delete throw 'overviewAttributes needed' if _.isEmpty(@overviewAttributes) throw 'attributesList needed' if _.isEmpty(@attributesList) @@ -182,7 +183,25 @@ class App.ControllerTable extends App.Controller App.QueueManager.add('tableRender', localeRender) App.QueueManager.run('tableRender') + renderPager: (el, find = false) => + pages = parseInt(((@objects.length - 1) / @shownPerPage)) + if pages < 1 + if find + el.find('.js-pager').html('') + else + el.filter('.js-pager').html('') + return + pager = App.view('generic/table_pager')( + page: @shownPage + pages: pages + ) + if find + el.find('.js-pager').html(pager) + else + el.filter('.js-pager').html(pager) + render: => + @setMaxPage() if @renderState is undefined # check if table is empty @@ -246,6 +265,7 @@ class App.ControllerTable extends App.Controller @$("tbody > tr:nth-child(#{position})").after(newCurrentRows[position]) @currentRows = newCurrentRows console.log('fullRender.contentRemoved', removePositions, addPositions) + @renderPager(@el, true) return ['fullRender.contentRemoved', removePositions, addPositions] if newRows.length isnt @currentRows.length @@ -282,6 +302,8 @@ class App.ControllerTable extends App.Controller @currentRows = clone(rows) container.find('.js-tableBody').html(rows) + @renderPager(container) + cursorMap = click: 'pointer' dblclick: 'pointer' @@ -402,6 +424,17 @@ class App.ControllerTable extends App.Controller update: @dndCallback container.find('tbody').sortable(dndOptions) + # click on pager + container.delegate('.js-page', 'click', (e) => + e.stopPropagation() + page = $(e.currentTarget).attr 'data-page' + render = => + @shownPage = page + @renderTableFull() + App.QueueManager.add('tableRender', render) + App.QueueManager.run('tableRender') + ) + @el.html(container) @setBulkSelected(bulkIds) @@ -424,7 +457,7 @@ class App.ControllerTable extends App.Controller columnsLength++ groupLast = '' tableBody = [] - objectsToShow = @objects.slice(0, @maxShown) + objectsToShow = @objectsOfPage(@shownPage) for object in objectsToShow if object position++ @@ -549,6 +582,15 @@ class App.ControllerTable extends App.Controller console.log('tableHeaders: new headers', @headers) ['new headers', @headers] + setMaxPage: => + pages = parseInt(((@objects.length - 1) / @shownPerPage)) + if parseInt(@shownPage) > pages + @shownPage = pages + + objectsOfPage: (page = 0) => + page = parseInt(page) + @objects.slice(page * @shownPerPage, (page + 1) * @shownPerPage) + sortList: => return if _.isEmpty(@objects) @@ -680,8 +722,6 @@ class App.ControllerTable extends App.Controller @objects = localObjects @lastSortedobjects = localObjects - localObjects - # bind on delete dialog deleteRow: (id, e) => e.stopPropagation() diff --git a/app/assets/javascripts/app/views/generic/table.jst.eco b/app/assets/javascripts/app/views/generic/table.jst.eco index a9aa675ec..5e0bbc2c2 100644 --- a/app/assets/javascripts/app/views/generic/table.jst.eco +++ b/app/assets/javascripts/app/views/generic/table.jst.eco @@ -1,3 +1,4 @@ +
"> @@ -35,4 +36,5 @@ <%- @tableBody %> -
\ No newline at end of file + +
diff --git a/app/assets/javascripts/app/views/generic/table_pager.jst.eco b/app/assets/javascripts/app/views/generic/table_pager.jst.eco new file mode 100644 index 000000000..9d75606ae --- /dev/null +++ b/app/assets/javascripts/app/views/generic/table_pager.jst.eco @@ -0,0 +1,5 @@ +
+ <% for page in [0..@pages]: %> +
<%= page + 1 %>
+ <% end %> +
diff --git a/public/assets/tests/table_extended.js b/public/assets/tests/table_extended.js index d3be554a6..e2ee6c6b9 100644 --- a/public/assets/tests/table_extended.js +++ b/public/assets/tests/table_extended.js @@ -1044,4 +1044,281 @@ test('table new - initial list', function() { equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '10.06.2014') equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true') equal(el.find('tbody > tr:nth-child(2) > td').length, 0) + + $('#table').append('

table with large data and pager

') + var el = $('#table-new5') + + var objects = []; + var created_at = Date.parse('2014-06-10T11:17:34.000Z') + + for (i = 0; i < 151; i++) { + local_created_at = new Date(created_at - (1000 * 60 * 60 * 24 * i)).toISOString() + item = { + id: i, + name: i + ' prio', + note: 'some note', + active: true, + created_at: local_created_at, + } + objects.push(item) + } + + App.TicketPriority.refresh(objects, {clear: true}) + + var table = new App.ControllerTable({ + tableId: 'large_table_test_pager', + el: el, + overviewAttributes: ['name', 'created_at', 'active'], + model: App.TicketPriority, + objects: App.TicketPriority.all(), + checkbox: false, + radio: false, + ttt: true + }) + + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '0 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '1 prio', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '09.06.2014', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(3)').text().trim(), 'true', 'check row 2') + equal(el.find('tbody > tr:nth-child(3) > td').length, 3, 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:first').text().trim(), '2 prio', 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '08.06.2014', 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:nth-child(3)').text().trim(), 'true', 'check row 3') + equal(el.find('tbody > tr').length, 150) + equal(el.find('tbody > tr:nth-child(151) > td').length, 0) + + equal(el.find('.js-pager').first().find('.js-page').length, 2) + equal(el.find('.js-pager').first().find('.js-page.is-selected').length, 1) + equal(el.find('.js-pager').first().find('.js-page.is-selected').text(), '1') + el.find('.js-pager').first().find('.js-page:nth-child(2)').click() + + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '150 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '11.01.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr').length, 1) + equal(el.find('tbody > tr:nth-child(2) > td').length, 0) + + objects = [ + { + id: 500, + name: '500 prio', + note: 'some note', + active: true, + created_at: '2014-06-10T10:17:30.000Z', + }, + ] + + App.TicketPriority.refresh(objects) + + result = table.update({sync: true, objects: App.TicketPriority.all()}) + equal(result[0], 'fullRender.contentRemoved') + equal(result[1][0], undefined) + equal(result[2][0], 1) + equal(result[2][1], undefined) + + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '150 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '11.01.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '500 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr').length, 2) + equal(el.find('tbody > tr:nth-child(3) > td').length, 0) + + objects = App.TicketPriority.all() + objects.splice(2,1) + result = table.update({sync: true, objects: objects}) + equal(result[0], 'fullRender.lenghtChanged') + //equal(result[1][0], 1) + //equal(result[1][1], undefined) + //equal(result[2][0], undefined) + + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '500 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr').length, 1) + equal(el.find('tbody > tr:nth-child(2) > td').length, 0) + + objects.splice(2,1) + result = table.update({sync: true, objects: objects}) + + equal(result[0], 'fullRender.lenghtChanged') + //equal(result[0], 'fullRender.contentRemoved') + //equal(result[1][0], 1) + //equal(result[1][1], undefined) + //equal(result[2][0], undefined) + + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '0 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '1 prio', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '09.06.2014', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(3)').text().trim(), 'true', 'check row 2') + equal(el.find('tbody > tr:nth-child(3) > td').length, 3, 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:first').text().trim(), '4 prio', 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '06.06.2014', 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:nth-child(3)').text().trim(), 'true', 'check row 3') + equal(el.find('tbody > tr').length, 150) + equal(el.find('tbody > tr:nth-child(151) > td').length, 0) + + equal(el.find('.js-pager').first().find('.js-page').length, 0) + + objects = [ + { + id: 500, + name: '500 prio', + note: 'some note', + active: true, + created_at: '2014-06-10T10:17:30.000Z', + }, + ] + App.TicketPriority.refresh(objects) + + objects = App.TicketPriority.all() + + result = table.update({sync: true, objects: objects}) + equal(result[0], 'fullRender.contentRemoved') + + equal(el.find('.js-pager').first().find('.js-page').length, 2) + equal(el.find('.js-pager').first().find('.js-page.is-selected').length, 1) + equal(el.find('.js-pager').first().find('.js-page.is-selected').text(), '1') + el.find('.js-pager').first().find('.js-page:nth-child(2)').click() + + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '150 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '11.01.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '500 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr').length, 2) + equal(el.find('tbody > tr:nth-child(3) > td').length, 0) + + equal(el.find('.js-pager').first().find('.js-page').length, 2) + equal(el.find('.js-pager').first().find('.js-page.is-selected').length, 1) + equal(el.find('.js-pager').first().find('.js-page.is-selected').text(), '2') + el.find('.js-pager').first().find('.js-page:nth-child(1)').click() + + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '0 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '1 prio', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '09.06.2014', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(3)').text().trim(), 'true', 'check row 2') + equal(el.find('tbody > tr:nth-child(3) > td').length, 3, 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:first').text().trim(), '2 prio', 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '08.06.2014', 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:nth-child(3)').text().trim(), 'true', 'check row 3') + equal(el.find('tbody > tr').length, 150) + equal(el.find('tbody > tr:nth-child(151) > td').length, 0) + + equal(el.find('.js-pager').first().find('.js-page').length, 2) + equal(el.find('.js-pager').first().find('.js-page.is-selected').length, 1) + equal(el.find('.js-pager').first().find('.js-page.is-selected').text(), '1') + + objects.splice(2,2) + + result = table.update({sync: true, objects: objects}) + equal(result[0], 'fullRender.contentRemoved') + + equal(el.find('.js-pager').first().find('.js-page').length, 0) + + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '0 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '1 prio', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '09.06.2014', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(3)').text().trim(), 'true', 'check row 2') + equal(el.find('tbody > tr:nth-child(3) > td').length, 3, 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:first').text().trim(), '4 prio', 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '06.06.2014', 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:nth-child(3)').text().trim(), 'true', 'check row 3') + equal(el.find('tbody > tr').length, 150) + equal(el.find('tbody > tr:nth-child(151) > td').length, 0) + + objects = [ + { + id: 501, + name: '501 prio', + note: 'some note', + active: true, + created_at: '2014-06-10T10:17:30.000Z', + }, + ] + App.TicketPriority.refresh(objects) + objects = App.TicketPriority.all() + + result = table.update({sync: true, objects: objects}) + equal(result[0], 'fullRender.contentRemoved') + + equal(el.find('table > thead > tr').length, 1, 'row count') + equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header') + equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header') + equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header') + equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '0 prio', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 1') + equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1') + equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '1 prio', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '09.06.2014', 'check row 2') + equal(el.find('tbody > tr:nth-child(2) > td:nth-child(3)').text().trim(), 'true', 'check row 2') + equal(el.find('tbody > tr:nth-child(3) > td').length, 3, 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:first').text().trim(), '2 prio', 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '08.06.2014', 'check row 3') + equal(el.find('tbody > tr:nth-child(3) > td:nth-child(3)').text().trim(), 'true', 'check row 3') + equal(el.find('tbody > tr').length, 150) + equal(el.find('tbody > tr:nth-child(151) > td').length, 0) + + equal(el.find('.js-pager').first().find('.js-page').length, 2) + equal(el.find('.js-pager').first().find('.js-page.is-selected').length, 1) + equal(el.find('.js-pager').first().find('.js-page.is-selected').text(), '1') + })