diff --git a/src/vaadin-date-picker-mixin.html b/src/vaadin-date-picker-mixin.html index dfe416da..a6a02da0 100644 --- a/src/vaadin-date-picker-mixin.html +++ b/src/vaadin-date-picker-mixin.html @@ -303,7 +303,6 @@ static get observers() { return [ '_updateHasValue(value)', - '_validateInput(_selectedDate, _minDate, _maxDate)', '_selectedDateChanged(_selectedDate, i18n.formatDate)', '_focusedDateChanged(_focusedDate, i18n.formatDate)', '_announceFocusedDate(_focusedDate, opened, _ignoreAnnounce)' @@ -478,8 +477,9 @@ } const inputValue = selectedDate && formatDate(Vaadin.DatePickerHelper._extractDateParts(selectedDate)); const value = this._formatISO(selectedDate); + this._inputValue = selectedDate ? inputValue : ''; if (value !== this.value) { - this.validate(inputValue); + this.validate(); this.value = value; } this.__userInputOccurred = false; @@ -487,7 +487,6 @@ this._ignoreFocusedDateChange = true; this._focusedDate = selectedDate; this._ignoreFocusedDateChange = false; - this._inputValue = selectedDate ? inputValue : ''; } _focusedDateChanged(focusedDate, formatDate) { @@ -528,6 +527,7 @@ } if (!Vaadin.DatePickerHelper._dateEquals(this[property], date)) { this[property] = date; + this.value && this.validate(); } } @@ -690,7 +690,9 @@ if (this._nativeInput && this._nativeInput.selectionStart) { this._nativeInput.selectionStart = this._nativeInput.selectionEnd; } - this.validate(); + // No need to revalidate the value after `_selectedDateChanged` + // Needed in case the value was not changed: open and close dropdown. + !this.value && this.validate(); } /** @@ -699,11 +701,11 @@ * @param {string} value Value to validate. Optional, defaults to user's input value. * @return {boolean} True if the value is valid and sets the `invalid` flag appropriately */ - validate(value) { - // reset invalid state on the underlying text field - this.invalid = false; - value = value !== undefined ? value : this._inputValue; - return !(this.invalid = !this.checkValidity(value)); + validate() { + // Note (Yuriy): Workaround `this._inputValue` is used in order + // to avoid breaking change on custom `checkValidity`. + // Can be removed with next major. + return !(this.invalid = !this.checkValidity(this._inputValue)); } /** @@ -714,20 +716,22 @@ * @param {string} value Value to validate. Optional, defaults to the selected date. * @return {boolean} True if the value is valid */ - checkValidity(value) { - var inputValid = !value || - (this._selectedDate && value === this.i18n.formatDate(Vaadin.DatePickerHelper._extractDateParts(this._selectedDate))); - var minMaxValid = !this._selectedDate || + checkValidity() { + const inputValid = !this._inputValue || + (this._selectedDate && this._inputValue === this.i18n.formatDate(Vaadin.DatePickerHelper._extractDateParts(this._selectedDate))); + const minMaxValid = !this._selectedDate || Vaadin.DatePickerHelper._dateAllowed(this._selectedDate, this._minDate, this._maxDate); - var inputValidity = true; + let inputValidity = true; if (this._inputElement) { if (this._inputElement.checkValidity) { // vaadin native input elements have the checkValidity method - inputValidity = this._inputElement.checkValidity(value); + this._inputElement.__forceCheckValidity = true; + inputValidity = this._inputElement.checkValidity(); + this._inputElement.__forceCheckValidity = false; } else if (this._inputElement.validate) { // iron-form-elements have the validate API - inputValidity = this._inputElement.validate(value); + inputValidity = this._inputElement.validate(); } } @@ -837,12 +841,6 @@ } } - _validateInput(date, min, max) { - if (date && (min || max)) { - this.invalid = !Vaadin.DatePickerHelper._dateAllowed(date, min, max); - } - } - _onUserInput(e) { if (!this.opened && this._inputElement.value) { this.open(); diff --git a/test/basic.html b/test/basic.html index b1cc3013..2ff39f11 100644 --- a/test/basic.html +++ b/test/basic.html @@ -540,6 +540,18 @@ getOverlayContent(datepicker).selectedDate = new Date('2017-01-01'); // invalid }); + it('should change invalid state only once', done => { + datepicker.addEventListener('value-changed', () => { + expect(invalidChangedSpy.calledOnce).to.be.true; + done(); + }); + + var invalidChangedSpy = sinon.spy(); + datepicker.addEventListener('invalid-changed', invalidChangedSpy); + datepicker.open(); + getOverlayContent(datepicker).selectedDate = new Date('2017-01-01'); + }); + it('should scroll to min date when today is not allowed', done => { datepicker.max = null; datepicker.min = '2100-01-01'; diff --git a/test/visual/screens/vaadin-date-picker/dropdown-lumo/date-limit/chrome.png b/test/visual/screens/vaadin-date-picker/dropdown-lumo/date-limit/chrome.png index 2b1b97c7..ecf58883 100644 Binary files a/test/visual/screens/vaadin-date-picker/dropdown-lumo/date-limit/chrome.png and b/test/visual/screens/vaadin-date-picker/dropdown-lumo/date-limit/chrome.png differ diff --git a/test/visual/screens/vaadin-date-picker/dropdown-lumo/date-limit/firefox.png b/test/visual/screens/vaadin-date-picker/dropdown-lumo/date-limit/firefox.png index 5cdf6a2c..521690a0 100644 Binary files a/test/visual/screens/vaadin-date-picker/dropdown-lumo/date-limit/firefox.png and b/test/visual/screens/vaadin-date-picker/dropdown-lumo/date-limit/firefox.png differ diff --git a/test/visual/screens/vaadin-date-picker/dropdown-lumo/week-numbers/chrome.png b/test/visual/screens/vaadin-date-picker/dropdown-lumo/week-numbers/chrome.png index 934f0665..61a5e9fb 100644 Binary files a/test/visual/screens/vaadin-date-picker/dropdown-lumo/week-numbers/chrome.png and b/test/visual/screens/vaadin-date-picker/dropdown-lumo/week-numbers/chrome.png differ diff --git a/test/visual/screens/vaadin-date-picker/dropdown-lumo/week-numbers/firefox.png b/test/visual/screens/vaadin-date-picker/dropdown-lumo/week-numbers/firefox.png index 19bf3cfb..0e437da0 100644 Binary files a/test/visual/screens/vaadin-date-picker/dropdown-lumo/week-numbers/firefox.png and b/test/visual/screens/vaadin-date-picker/dropdown-lumo/week-numbers/firefox.png differ