From f02d289992c26b15b45ebf787e27c6539ee28293 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Tue, 9 Nov 2021 21:01:21 +0530 Subject: [PATCH 1/4] feat: Editable grid/table pagination --- .../public/js/frappe/form/grid_pagination.js | 55 ++++++++++++++++++- frappe/public/scss/common/grid.scss | 12 ++++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/form/grid_pagination.js b/frappe/public/js/frappe/form/grid_pagination.js index 35daafe89d..8efdcb9001 100644 --- a/frappe/public/js/frappe/form/grid_pagination.js +++ b/frappe/public/js/frappe/form/grid_pagination.js @@ -46,8 +46,55 @@ export default class GridPagination { this.last_page_button.on('click', () => { this.go_to_page(this.total_pages); }); + + this.$page_number.on('keyup', (e) => { + e.currentTarget.style.width = ((e.currentTarget.value.length + 1) * 8) + 'px'; + }) + + this.$page_number.on('keydown', (e) => { + e = (e) ? e : window.event; + var charCode = (e.which) ? e.which : e.keyCode; + let arrow = { up: 38, down: 40 }; + + switch (charCode) { + case arrow.up: + this.inc_dec_number(true); + break; + case arrow.down: + this.inc_dec_number(false); + break; + } + + // only allow numbers from 0-9 and up, down, left, right arrow keys + if (charCode > 31 && (charCode < 48 || charCode > 57) && + ![37, 38, 39, 40].includes(charCode)) { + return false; + } + return true; + }) + + this.$page_number.on('focusout', (e) => { + if (this.page_index == e.currentTarget.value) return; + this.page_index = e.currentTarget.value; + + if(this.page_index < 1) { + this.page_index = 1; + } else if(this.page_index > this.total_pages) { + this.page_index = this.total_pages; + } + + this.go_to_page(); + }) } + inc_dec_number(increment) { + let new_value = parseInt(this.$page_number.val()) + increment ? new_value++ : new_value--; + + if (new_value < 1 || new_value > this.total_pages) return; + + this.$page_number.val(new_value); + } update_page_numbers() { let total_pages = Math.ceil(this.grid.data.length/this.page_length); @@ -64,8 +111,9 @@ export default class GridPagination { } get_pagination_html() { - let page_text_html = `
- ${__(this.page_index)} + let page_text_html = ` +
+ ${__('of')} ${__(this.total_pages)}
`; @@ -104,7 +152,8 @@ export default class GridPagination { let $rows = $(this.grid.parent).find(".rows").empty(); this.grid.render_result_rows($rows, true); if (this.$page_number) { - this.$page_number.text(index); + this.$page_number.val(index); + this.$page_number.css('width', ((index.toString().length + 1) * 8) + 'px'); } this.update_page_numbers(); diff --git a/frappe/public/scss/common/grid.scss b/frappe/public/scss/common/grid.scss index 57d0583b35..3014211222 100644 --- a/frappe/public/scss/common/grid.scss +++ b/frappe/public/scss/common/grid.scss @@ -373,6 +373,18 @@ .page-text { display: inline-block; + cursor: default; +} + +.current-page-number { + width: 16px; + text-align: center; + border: none; + cursor: text; + + &:focus { + outline: none; + } } .prev-page, From 8778128109984e37bc9b85f65a5cc08145055086 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Tue, 9 Nov 2021 22:16:45 +0530 Subject: [PATCH 2/4] fix: sider fix --- frappe/public/js/frappe/form/grid_pagination.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/frappe/public/js/frappe/form/grid_pagination.js b/frappe/public/js/frappe/form/grid_pagination.js index 8efdcb9001..76a5f7b50b 100644 --- a/frappe/public/js/frappe/form/grid_pagination.js +++ b/frappe/public/js/frappe/form/grid_pagination.js @@ -49,13 +49,13 @@ export default class GridPagination { this.$page_number.on('keyup', (e) => { e.currentTarget.style.width = ((e.currentTarget.value.length + 1) * 8) + 'px'; - }) + }); this.$page_number.on('keydown', (e) => { e = (e) ? e : window.event; var charCode = (e.which) ? e.which : e.keyCode; let arrow = { up: 38, down: 40 }; - + switch (charCode) { case arrow.up: this.inc_dec_number(true); @@ -71,24 +71,24 @@ export default class GridPagination { return false; } return true; - }) + }); this.$page_number.on('focusout', (e) => { if (this.page_index == e.currentTarget.value) return; this.page_index = e.currentTarget.value; - if(this.page_index < 1) { + if (this.page_index < 1) { this.page_index = 1; - } else if(this.page_index > this.total_pages) { + } else if (this.page_index > this.total_pages) { this.page_index = this.total_pages; } this.go_to_page(); - }) + }); } inc_dec_number(increment) { - let new_value = parseInt(this.$page_number.val()) + let new_value = parseInt(this.$page_number.val()); increment ? new_value++ : new_value--; if (new_value < 1 || new_value > this.total_pages) return; @@ -111,8 +111,7 @@ export default class GridPagination { } get_pagination_html() { - let page_text_html = ` -
+ let page_text_html = `
${__('of')} ${__(this.total_pages)} From 0441059d2c0794d242bbb2a26ece3557f68de096 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Wed, 10 Nov 2021 11:32:53 +0530 Subject: [PATCH 3/4] test: Updated grid_pagination UI Test --- cypress/integration/grid_pagination.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cypress/integration/grid_pagination.js b/cypress/integration/grid_pagination.js index c07230d2b8..0ec280d63e 100644 --- a/cypress/integration/grid_pagination.js +++ b/cypress/integration/grid_pagination.js @@ -13,7 +13,7 @@ context('Grid Pagination', () => { it('creates pages for child table', () => { cy.visit('/app/contact/Test Contact'); cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table'); - cy.get('@table').find('.current-page-number').should('contain', '1'); + cy.get('@table').find('.current-page-number').should('have.value', '1'); cy.get('@table').find('.total-page-number').should('contain', '20'); cy.get('@table').find('.grid-body .grid-row').should('have.length', 50); }); @@ -21,10 +21,10 @@ context('Grid Pagination', () => { cy.visit('/app/contact/Test Contact'); cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table'); cy.get('@table').find('.next-page').click(); - cy.get('@table').find('.current-page-number').should('contain', '2'); + cy.get('@table').find('.current-page-number').should('have.value', '2'); cy.get('@table').find('.grid-body .grid-row').first().should('have.attr', 'data-idx', '51'); cy.get('@table').find('.prev-page').click(); - cy.get('@table').find('.current-page-number').should('contain', '1'); + cy.get('@table').find('.current-page-number').should('have.value', '1'); cy.get('@table').find('.grid-body .grid-row').first().should('have.attr', 'data-idx', '1'); }); it('adds and deletes rows and changes page', () => { @@ -32,12 +32,12 @@ context('Grid Pagination', () => { cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table'); cy.get('@table').findByRole('button', {name: 'Add Row'}).click(); cy.get('@table').find('.grid-body .row-index').should('contain', 1001); - cy.get('@table').find('.current-page-number').should('contain', '21'); + cy.get('@table').find('.current-page-number').should('have.value', '21'); cy.get('@table').find('.total-page-number').should('contain', '21'); cy.get('@table').find('.grid-body .grid-row .grid-row-check').click({ force: true }); cy.get('@table').findByRole('button', {name: 'Delete'}).click(); cy.get('@table').find('.grid-body .row-index').last().should('contain', 1000); - cy.get('@table').find('.current-page-number').should('contain', '20'); + cy.get('@table').find('.current-page-number').should('have.value', '20'); cy.get('@table').find('.total-page-number').should('contain', '20'); }); // it('deletes all rows', ()=> { From ede1c41f678cb09b7e954a02b6097c235b12e365 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Wed, 10 Nov 2021 12:14:47 +0530 Subject: [PATCH 4/4] test: UI test for editable grid pagination --- cypress/integration/grid_pagination.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/cypress/integration/grid_pagination.js b/cypress/integration/grid_pagination.js index 0ec280d63e..84b3320282 100644 --- a/cypress/integration/grid_pagination.js +++ b/cypress/integration/grid_pagination.js @@ -40,6 +40,27 @@ context('Grid Pagination', () => { cy.get('@table').find('.current-page-number').should('have.value', '20'); cy.get('@table').find('.total-page-number').should('contain', '20'); }); + it('go to specific page, use up and down arrow, type characters, 0 page and more than existing page', () => { + cy.visit('/app/contact/Test Contact'); + cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table'); + cy.get('@table').find('.current-page-number').focus().clear().type('17').blur(); + cy.get('@table').find('.grid-body .row-index').should('contain', 801); + + cy.get('@table').find('.current-page-number').focus().type('{uparrow}{uparrow}'); + cy.get('@table').find('.current-page-number').should('have.value', '19'); + + cy.get('@table').find('.current-page-number').focus().type('{downarrow}{downarrow}'); + cy.get('@table').find('.current-page-number').should('have.value', '17'); + + cy.get('@table').find('.current-page-number').focus().clear().type('700').blur(); + cy.get('@table').find('.current-page-number').should('have.value', '20'); + + cy.get('@table').find('.current-page-number').focus().clear().type('0').blur(); + cy.get('@table').find('.current-page-number').should('have.value', '1'); + + cy.get('@table').find('.current-page-number').focus().clear().type('abc').blur(); + cy.get('@table').find('.current-page-number').should('have.value', '1'); + }); // it('deletes all rows', ()=> { // cy.visit('/app/contact/Test Contact'); // cy.get('.frappe-control[data-fieldname="phone_nos"]').as('table');