Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit a0ceb82

Browse files
committed
fix(input): re-validate when partially editing a date-family input
In date-family input types (`date`, `datetime-local`, `month`, `time`, `week`), the user can interact with parts of the value (e.g. year, month, hours etc) independently. Neverhteless, the actual value of the element is empty (`''`) unless all parts are filled (and valid). Thus, editing a signle part of the value may result in a change in the validity state of the `<input>` (see below), without an accompanying change in the actual value of the element. In such cases, no `input` event is fired by the browser to inform Angular of the change (and the need to re-validate). --- The following scenario describes a series of interactions that would run into the problem (on a browser that supports the `date` input type): 1. Initially empty field. - `input.value`: '' - `input.validity`: {valid: true, badInput: false, ...} 2. The user fills part of the value (e.g. the year) using the keyboard. - `input.value`: '' - `input.validity`: {valid: false, badInput: true, ...} - 'input' event: Not fired (since `input.value` hasn't changed) 3. The user fills the value completely (using either the keyboard or the date-picker). - `input.value`: '<some-valid-value>' - `input.validity`: {valid: true, badInput: false, ...} - 'input' event: Fired 4. The user deletes part of the value (e.g. the year) using the keyboard. - `input.value`: '' (since a partial value is invalid) - `input.validity`: {valid: false, badInput: true, ...} - 'input' event: Fired 5. The user deletes all parts of the value using the keyboard (i.e. clears the field). - `input.value`: '' - `input.validity`: {valid: true, badInput: false, ...} - 'input' event: Not fired (since `input.value` hasn't changed) The problematic cases are (2) and (5), because there is a change in the validity state, but no 'input' event is fired to inform Angular of that change and the need to re-validate. --- This commit fixes the issue by firing an `input` event on `keyup`, correctly triggering re-validation. Fixes #12207
1 parent d3de006 commit a0ceb82

File tree

2 files changed

+362
-0
lines changed

2 files changed

+362
-0
lines changed

src/ng/directive/input.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{
1919
var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/;
2020
var MONTH_REGEXP = /^(\d{4})-(\d\d)$/;
2121
var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
22+
var DATE_INPUT_TYPES = ['date', 'datetime-local', 'month', 'time', 'week'];
2223

2324
var inputType = {
2425

@@ -1134,6 +1135,15 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11341135
// input event on backspace, delete or cut
11351136
if ($sniffer.hasEvent('input')) {
11361137
element.on('input', listener);
1138+
1139+
// On date-family inputs, we also need to listen for `keyup` in case the date is partially
1140+
// edited by the user using the keyboard, resulting in a change in the validity state, but
1141+
// without an accompanying change in the input value (thus no `input` event).
1142+
// (This is only necessary on browsers that support inputs of that type - other browsers set the
1143+
// `type` property to "text".)
1144+
var isTypeSupported = (type === attr.type);
1145+
var listenForKeyup = isTypeSupported && (DATE_INPUT_TYPES.indexOf(type) !== -1);
1146+
if (listenForKeyup) element.on('keyup', function() { element.triggerHandler('input'); });
11371147
} else {
11381148
var timeout;
11391149

0 commit comments

Comments
 (0)