From 05ed8a8c60c9086359c981f06ec7b9cebab23000 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 13 Jul 2020 17:44:34 +0100 Subject: [PATCH] Improved track method to push the date picker above the input field if below will push it off screen --- module/date-picker.js | 25 ++++++++++++++++++---- package.json | 2 +- scss/date_picker.scss | 1 - spec/date-picker.spec.js | 45 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 66 insertions(+), 7 deletions(-) diff --git a/module/date-picker.js b/module/date-picker.js index 5f8f01f..78f559c 100644 --- a/module/date-picker.js +++ b/module/date-picker.js @@ -102,6 +102,12 @@ export class DatePicker { */ 'stayOpenOnPick': false, + /** + * The vertical offset applied when tracking the date picker + * to a field. + */ + 'trackOffset': 10, + /** * A list of weekday names used by the date picker. */ @@ -412,12 +418,12 @@ export class DatePicker { this.calendar.date = date } - // Update the position of the picker inline with the associated input - this._track() - // Show the date picker this.picker.classList.add(this.constructor.css['open']) + // Update the position of the picker inline with the associated input + this._track() + // Flag the date picker as open this._open = true @@ -450,10 +456,21 @@ export class DatePicker { * Position the date picker inline with the associated input element. */ _track() { + const offset = this._options.trackOffset + const rect = this.input.getBoundingClientRect() const top = rect.top + window.pageYOffset const left = rect.left + window.pageXOffset - this.picker.style.top = `${top + rect.height}px` + + const pickerRect = this.picker.getBoundingClientRect() + const pickerBottom = top + pickerRect.height + + if (pickerBottom > document.body.scrollHeight) { + console.log(top, pickerRect.height, offset) + this.picker.style.top = `${top - pickerRect.height - offset}px` + } else { + this.picker.style.top = `${top + rect.height + offset}px` + } this.picker.style.left = `${left}px` } } diff --git a/package.json b/package.json index 130b68a..ce81d32 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "manhattan-date-picker", - "version": "1.0.4", + "version": "1.0.5", "description": "Date parsing and picking for form fields.", "engines": { "node": ">=8.9.4" diff --git a/scss/date_picker.scss b/scss/date_picker.scss index 37240ef..a161f2f 100644 --- a/scss/date_picker.scss +++ b/scss/date_picker.scss @@ -5,7 +5,6 @@ border: 1px solid #d4dce0; border-radius: 3px; display: none; - margin-top: 10px; position: absolute; width: 300px; z-index: 4; diff --git a/spec/date-picker.spec.js b/spec/date-picker.spec.js index cb333fa..420941f 100644 --- a/spec/date-picker.spec.js +++ b/spec/date-picker.spec.js @@ -568,7 +568,18 @@ describe('DatePicker', () => { 'height': 20, 'left': 30, 'right': 130, - 'top': 20, + 'top': 100, + 'width': 100 + } + } + + datePicker.picker.getBoundingClientRect = () => { + return { + 'bottom': 50, + 'height': 50, + 'left': 0, + 'right': 100, + 'top': 0, 'width': 100 } } @@ -579,11 +590,43 @@ describe('DatePicker', () => { afterEach(() => { datePicker.destroy() + + Object.defineProperty( + document.body, + 'scrollHeight', + { + 'configurable': true, + 'value': 0 + } + ) }) describe('track', () => { it('should position the picker inline with the input', () => { + + Object.defineProperty( + document.body, + 'scrollHeight', + { + 'configurable': true, + 'value': 1000 + } + ) + + datePicker._track() + datePicker.picker.style.top.should.equal('140px') + datePicker.picker.style.left.should.equal('40px') + + Object.defineProperty( + document.body, + 'scrollHeight', + { + 'configurable': true, + 'value': 120 + } + ) + datePicker._track() datePicker.picker.style.top.should.equal('50px') datePicker.picker.style.left.should.equal('40px')