@progress/kendo-dateinputs-common 0.2.0-dev.202301231327 → 0.2.0-dev.202301241303
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/js/kendo-dateinputs-common.js +1 -1
- package/dist/cdn/main.js +1 -1
- package/dist/es/common/dateobject.js +26 -52
- package/dist/es/dateinput/dateinput.js +147 -128
- package/dist/es/dateinput/utils.js +2 -2
- package/dist/es2015/common/dateobject.js +26 -51
- package/dist/es2015/dateinput/dateinput.js +147 -128
- package/dist/es2015/dateinput/utils.js +2 -2
- package/dist/npm/common/dateobject.js +26 -52
- package/dist/npm/dateinput/dateinput.d.ts +9 -1
- package/dist/npm/dateinput/dateinput.js +147 -128
- package/dist/npm/dateinput/utils.js +2 -2
- package/dist/systemjs/kendo-dateinputs-common.js +1 -1
- package/package.json +1 -1
|
@@ -28,7 +28,6 @@ const FOCUS_END = "focusEnd";
|
|
|
28
28
|
const CHANGE = "change";
|
|
29
29
|
const defaultDateInputOptions = {
|
|
30
30
|
format: "d",
|
|
31
|
-
allowNulls: false,
|
|
32
31
|
hasPlaceholder: false,
|
|
33
32
|
placeholder: null,
|
|
34
33
|
cycleTime: true,
|
|
@@ -56,6 +55,7 @@ const defaultDateInputOptions = {
|
|
|
56
55
|
[CHANGE]: null
|
|
57
56
|
},
|
|
58
57
|
selectNearestSegmentOnFocus: false,
|
|
58
|
+
selectPreviousSegmentOnBackspace: false,
|
|
59
59
|
enableMouseWheel: false,
|
|
60
60
|
allowCaretMode: false,
|
|
61
61
|
autoSwitchParts: true,
|
|
@@ -202,6 +202,7 @@ export class DateInput extends Observable {
|
|
|
202
202
|
*/
|
|
203
203
|
onElementClick(e) {
|
|
204
204
|
this.mouseDownStarted = false;
|
|
205
|
+
this.switchedPartOnPreviousKeyAction = false;
|
|
205
206
|
const selection = this.selection;
|
|
206
207
|
if (this.isInCaretMode()) {
|
|
207
208
|
// explicitly refresh the input element value
|
|
@@ -234,12 +235,10 @@ export class DateInput extends Observable {
|
|
|
234
235
|
*/
|
|
235
236
|
onElementInput(e) {
|
|
236
237
|
this.triggerInput({ event: e });
|
|
237
|
-
const keyDownEvent = this.keyDownEvent || {};
|
|
238
|
-
const isBackspaceKey = keyDownEvent.keyCode === KeyCode.BACKSPACE || keyDownEvent.key === Key.BACKSPACE;
|
|
239
|
-
const isDeleteKey = keyDownEvent.keyCode === KeyCode.DELETE || keyDownEvent.key === Key.DELETE;
|
|
240
238
|
if (!this.element || !this.dateObject) {
|
|
241
239
|
return;
|
|
242
240
|
}
|
|
241
|
+
const switchedPartOnPreviousKeyAction = this.switchedPartOnPreviousKeyAction;
|
|
243
242
|
if (this.isPasteInProgress) {
|
|
244
243
|
if (this.options.allowCaretMode) {
|
|
245
244
|
// pasting should leave the input with caret
|
|
@@ -250,6 +249,9 @@ export class DateInput extends Observable {
|
|
|
250
249
|
this.isPasteInProgress = false;
|
|
251
250
|
return;
|
|
252
251
|
}
|
|
252
|
+
const keyDownEvent = this.keyDownEvent || {};
|
|
253
|
+
const isBackspaceKey = keyDownEvent.keyCode === KeyCode.BACKSPACE || keyDownEvent.key === Key.BACKSPACE;
|
|
254
|
+
const isDeleteKey = keyDownEvent.keyCode === KeyCode.DELETE || keyDownEvent.key === Key.DELETE;
|
|
253
255
|
const originalInteractionMode = this.interactionMode;
|
|
254
256
|
if (this.options.allowCaretMode &&
|
|
255
257
|
originalInteractionMode !== DateInputInteractionMode.Caret &&
|
|
@@ -268,50 +270,36 @@ export class DateInput extends Observable {
|
|
|
268
270
|
this.restorePreviousInputEventState();
|
|
269
271
|
return;
|
|
270
272
|
}
|
|
271
|
-
const
|
|
273
|
+
const oldExistingDateValue = this.dateObject && this.dateObject.getValue();
|
|
274
|
+
const oldDateValue = this.dateObject ? this.dateObject.value : null;
|
|
272
275
|
const { text: currentText, format: currentFormat } = this.dateObject.getTextAndFormat();
|
|
273
276
|
this.currentFormat = currentFormat;
|
|
274
|
-
let
|
|
277
|
+
let oldText = "";
|
|
275
278
|
if (hasCaret) {
|
|
276
279
|
if (isBackspaceKey || isDeleteKey) {
|
|
277
|
-
|
|
280
|
+
oldText = this.previousElementValue;
|
|
278
281
|
}
|
|
279
282
|
else if (originalInteractionMode === DateInputInteractionMode.Caret) {
|
|
280
|
-
|
|
283
|
+
oldText = this.previousElementValue;
|
|
281
284
|
}
|
|
282
285
|
else {
|
|
283
|
-
|
|
286
|
+
oldText = currentText;
|
|
284
287
|
}
|
|
285
288
|
}
|
|
286
289
|
else {
|
|
287
|
-
|
|
290
|
+
oldText = currentText;
|
|
288
291
|
}
|
|
289
292
|
const newText = this.elementValue;
|
|
290
293
|
let diff = approximateStringMatching({
|
|
291
|
-
oldText:
|
|
294
|
+
oldText: oldText,
|
|
292
295
|
newText: newText,
|
|
293
296
|
formatPattern: this.currentFormat,
|
|
294
297
|
selectionStart: this.selection.start,
|
|
295
298
|
isInCaretMode: hasCaret,
|
|
296
299
|
keyEvent: this.keyDownEvent
|
|
297
300
|
});
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if (currentFormatChar &&
|
|
301
|
-
currentFormatChar.length > 0 &&
|
|
302
|
-
currentFormatChar !== Constants.formatSeparator) {
|
|
303
|
-
if (!diff || diff.length === 0) {
|
|
304
|
-
diff = [];
|
|
305
|
-
diff[0][0] = currentFormatChar;
|
|
306
|
-
diff[0][1] = e.data || "";
|
|
307
|
-
}
|
|
308
|
-
else if (diff[0] && diff[0][0] !== Constants.formatSeparator) {
|
|
309
|
-
if (diff[0][0] !== currentFormatChar) {
|
|
310
|
-
diff[0][0] = currentFormatChar;
|
|
311
|
-
diff[0][1] = e.data || "";
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
301
|
+
if (diff && diff.length && diff[0] && diff[0][1] !== Constants.formatSeparator) {
|
|
302
|
+
this.switchedPartOnPreviousKeyAction = false;
|
|
315
303
|
}
|
|
316
304
|
if (hasCaret && (!diff || diff.length === 0)) {
|
|
317
305
|
this.restorePreviousInputEventState();
|
|
@@ -350,104 +338,128 @@ export class DateInput extends Observable {
|
|
|
350
338
|
switchPart = false;
|
|
351
339
|
}
|
|
352
340
|
this.resetSegmentValue = false;
|
|
341
|
+
const hasFixedFormat = this.options.format === this.currentFormat ||
|
|
342
|
+
// all not fixed formats are 1 symbol, e.g. "d"
|
|
343
|
+
(isPresent(this.options.format) && this.options.format.length > 1);
|
|
353
344
|
const lastParseResult = parsePartsResults[parsePartsResults.length - 1];
|
|
354
|
-
const lastParseResultHasNoValue = lastParseResult && !lastParseResult.value;
|
|
345
|
+
const lastParseResultHasNoValue = lastParseResult && !isPresent(lastParseResult.value);
|
|
355
346
|
const parsingFailedOnDelete = (hasCaret && (isBackspaceKey || isDeleteKey) && lastParseResultHasNoValue);
|
|
356
347
|
const resetPart = lastParseResult ? lastParseResult.resetPart : false;
|
|
357
|
-
const
|
|
358
|
-
const
|
|
348
|
+
const newExistingDateValue = this.dateObject.getValue();
|
|
349
|
+
const hasExistingDateValueChanged = !isEqual(oldExistingDateValue, newExistingDateValue);
|
|
350
|
+
const newDateValue = this.dateObject.value;
|
|
359
351
|
let symbolForSelection;
|
|
360
352
|
const currentSelection = this.selection;
|
|
361
|
-
if (
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if (!hasCaret || parsingFailedOnDelete || resetPart) {
|
|
369
|
-
if (symbolForSelection) {
|
|
370
|
-
this.setSelection(this.selectionBySymbol(symbolForSelection));
|
|
353
|
+
if (hasCaret) {
|
|
354
|
+
const diffChar = diff && diff.length > 0 ? diff[0][0] : null;
|
|
355
|
+
let hasLeadingZero = this.dateObject.getLeadingZero()[diffChar];
|
|
356
|
+
if (diff.length && diff[0][0] !== Constants.formatSeparator) {
|
|
357
|
+
if (switchPart) {
|
|
358
|
+
this.forceUpdateWithSelection();
|
|
359
|
+
this.switchDateSegment(1);
|
|
371
360
|
}
|
|
372
|
-
else {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
361
|
+
else if (resetPart) {
|
|
362
|
+
symbolForSelection = this.currentFormat[currentSelection.start];
|
|
363
|
+
if (symbolForSelection) {
|
|
364
|
+
this.forceUpdate();
|
|
365
|
+
this.setSelection(this.selectionBySymbol(symbolForSelection));
|
|
376
366
|
}
|
|
377
367
|
else {
|
|
368
|
+
this.restorePreviousInputEventState();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
else if (parsingFailedOnDelete) {
|
|
372
|
+
this.forceUpdate();
|
|
373
|
+
if (diff.length && diff[0][0] !== Constants.formatSeparator) {
|
|
378
374
|
this.setSelection(this.selectionBySymbol(diff[0][0]));
|
|
379
375
|
}
|
|
380
376
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
if (switchPart) {
|
|
386
|
-
this.switchDateSegment(1);
|
|
377
|
+
else if (lastParseResultHasNoValue) {
|
|
378
|
+
if (e.data === "0" && hasLeadingZero) {
|
|
379
|
+
// do not reset element value on a leading zero
|
|
380
|
+
// wait for consecutive input to determine the value
|
|
387
381
|
}
|
|
388
|
-
else {
|
|
389
|
-
|
|
390
|
-
currentFormatChar && currentFormatChar !== "y") {
|
|
391
|
-
const elementValueLength = this.elementValue.length;
|
|
392
|
-
this.forceUpdate();
|
|
393
|
-
const selectionOffset = this.elementValue.length - elementValueLength;
|
|
394
|
-
this.setSelection({
|
|
395
|
-
start: currentSelection.start + selectionOffset,
|
|
396
|
-
end: currentSelection.start + selectionOffset
|
|
397
|
-
});
|
|
398
|
-
}
|
|
382
|
+
else if (isPresent(oldExistingDateValue) && !isPresent(newExistingDateValue)) {
|
|
383
|
+
this.restorePreviousInputEventState();
|
|
399
384
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
if (
|
|
405
|
-
this.
|
|
406
|
-
}
|
|
407
|
-
else if (e.data === "0" && hasLeadingZero) {
|
|
385
|
+
else if (!isPresent(oldExistingDateValue) && isPresent(newExistingDateValue)) {
|
|
386
|
+
this.forceUpdateWithSelection();
|
|
387
|
+
}
|
|
388
|
+
else if (isPresent(oldExistingDateValue) && isPresent(newExistingDateValue)) {
|
|
389
|
+
if (hasExistingDateValueChanged) {
|
|
390
|
+
this.forceUpdateWithSelection();
|
|
408
391
|
}
|
|
409
392
|
else {
|
|
410
393
|
this.restorePreviousInputEventState();
|
|
411
394
|
}
|
|
412
395
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
416
|
-
if (!switchPart && hasCaret && !isBackspaceKey && !isDeleteKey && !resetPart && lastParseResultHasNoValue) {
|
|
417
|
-
if (hasDateValueChanged) {
|
|
418
|
-
if (this.currentFormat.length === this.elementValue.length) {
|
|
419
|
-
// if a full date is entered, do not reset it
|
|
420
|
-
}
|
|
421
|
-
else {
|
|
422
|
-
// the input is not complete, not parsable or not updatable
|
|
423
|
-
if (originalInteractionMode !== DateInputInteractionMode.Caret && hasDateValueChanged) {
|
|
396
|
+
else if (!isPresent(oldExistingDateValue) && !isPresent(newExistingDateValue)) {
|
|
397
|
+
this.forceUpdateWithSelection();
|
|
424
398
|
}
|
|
425
|
-
else if (
|
|
426
|
-
|
|
427
|
-
this.forceUpdate();
|
|
428
|
-
this.setSelection(this.selectionBySymbol(symbolForSelection));
|
|
399
|
+
else if (oldDateValue !== newDateValue) {
|
|
400
|
+
// this can happen on auto correct when no valid value is parsed
|
|
429
401
|
}
|
|
430
|
-
else
|
|
402
|
+
else {
|
|
431
403
|
this.restorePreviousInputEventState();
|
|
432
404
|
}
|
|
433
405
|
}
|
|
406
|
+
else if (!lastParseResultHasNoValue) {
|
|
407
|
+
// the user types a valid but incomplete date (e.g. year "123" with format "yyyy")
|
|
408
|
+
// let them continue typing, but refresh for not fixed formats
|
|
409
|
+
if (!hasFixedFormat) {
|
|
410
|
+
this.forceUpdateWithSelection();
|
|
411
|
+
}
|
|
412
|
+
}
|
|
434
413
|
}
|
|
435
414
|
else {
|
|
436
|
-
|
|
437
|
-
|
|
415
|
+
if (!this.options.autoSwitchParts && diff[0][1] === Constants.formatSeparator) {
|
|
416
|
+
// do not change the selection when a separator is pressed
|
|
417
|
+
// this should happen only if autoSwitchKeys contains the separator explicitly
|
|
438
418
|
}
|
|
439
|
-
else
|
|
440
|
-
this.
|
|
419
|
+
else {
|
|
420
|
+
this.setSelection(this.selectionBySymbol(diff[0][0]));
|
|
441
421
|
}
|
|
442
422
|
}
|
|
443
423
|
}
|
|
444
|
-
else if (
|
|
445
|
-
|
|
446
|
-
|
|
424
|
+
else if (!hasCaret) {
|
|
425
|
+
this.forceUpdate();
|
|
426
|
+
if (diff.length && diff[0][0] !== Constants.formatSeparator) {
|
|
427
|
+
this.setSelection(this.selectionBySymbol(diff[0][0]));
|
|
428
|
+
}
|
|
429
|
+
if (this.options.autoSwitchParts) {
|
|
430
|
+
if (navigationOnly) {
|
|
431
|
+
this.resetSegmentValue = true;
|
|
432
|
+
if (!switchedPartOnPreviousKeyAction) {
|
|
433
|
+
this.switchDateSegment(1);
|
|
434
|
+
}
|
|
435
|
+
this.switchedPartOnPreviousKeyAction = true;
|
|
436
|
+
}
|
|
437
|
+
else if (switchPart) {
|
|
438
|
+
this.switchDateSegment(1);
|
|
439
|
+
this.switchedPartOnPreviousKeyAction = true;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
if (lastParseResult && lastParseResult.switchToNext) {
|
|
444
|
+
// the value is complete and should be switched, but the "autoSwitchParts" option prevents this
|
|
445
|
+
// ensure that the segment value can be reset on next input
|
|
446
|
+
this.resetSegmentValue = true;
|
|
447
|
+
}
|
|
448
|
+
else if (navigationOnly) {
|
|
449
|
+
this.resetSegmentValue = true;
|
|
450
|
+
if (!switchedPartOnPreviousKeyAction) {
|
|
451
|
+
this.switchDateSegment(1);
|
|
452
|
+
}
|
|
453
|
+
this.switchedPartOnPreviousKeyAction = true;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
if (isBackspaceKey && this.options.selectPreviousSegmentOnBackspace) {
|
|
457
|
+
// kendo angular have this UX
|
|
458
|
+
this.switchDateSegment(-1);
|
|
447
459
|
}
|
|
448
460
|
}
|
|
449
461
|
this.tryTriggerValueChange({
|
|
450
|
-
oldValue:
|
|
462
|
+
oldValue: oldExistingDateValue,
|
|
451
463
|
event: e
|
|
452
464
|
});
|
|
453
465
|
this.triggerInputEnd({ event: e });
|
|
@@ -467,6 +479,7 @@ export class DateInput extends Observable {
|
|
|
467
479
|
}
|
|
468
480
|
this.isActive = true;
|
|
469
481
|
this.interactionMode = DateInputInteractionMode.None;
|
|
482
|
+
this.switchedPartOnPreviousKeyAction = false;
|
|
470
483
|
this.refreshElementValue();
|
|
471
484
|
if (!this.mouseDownStarted) {
|
|
472
485
|
this.caret(0, this.elementValue.length);
|
|
@@ -484,6 +497,7 @@ export class DateInput extends Observable {
|
|
|
484
497
|
return;
|
|
485
498
|
}
|
|
486
499
|
this.interactionMode = DateInputInteractionMode.None;
|
|
500
|
+
this.switchedPartOnPreviousKeyAction = false;
|
|
487
501
|
this.refreshElementValue();
|
|
488
502
|
this.triggerBlurEnd({ event: e });
|
|
489
503
|
}
|
|
@@ -503,20 +517,9 @@ export class DateInput extends Observable {
|
|
|
503
517
|
const { start, end } = this.selection;
|
|
504
518
|
this.keyDownEvent = e;
|
|
505
519
|
this.previousElementValue = this.element.value;
|
|
506
|
-
this.formatStateOnKeyDown = {
|
|
507
|
-
format: this.currentFormat,
|
|
508
|
-
selectionStart: start,
|
|
509
|
-
selectionEnd: end
|
|
510
|
-
};
|
|
511
520
|
this.previousElementSelection = { start, end };
|
|
512
|
-
|
|
513
|
-
.
|
|
514
|
-
if (autoSwitchKeys.indexOf(e.keyCode.toString()) >= 0 ||
|
|
515
|
-
autoSwitchKeys.indexOf(e.keyCode) >= 0 ||
|
|
516
|
-
autoSwitchKeys.indexOf(e.key.toLowerCase().trim()) >= 0) {
|
|
517
|
-
const isTabKey = autoSwitchKeys.indexOf(Key.TAB.toLowerCase().trim()) >= 0 ||
|
|
518
|
-
autoSwitchKeys.indexOf(KeyCode.TAB) >= 0 ||
|
|
519
|
-
autoSwitchKeys.indexOf(KeyCode.TAB.toString()) >= 0;
|
|
521
|
+
if (this.keyEventMatchesAutoSwitchKeys(e)) {
|
|
522
|
+
const isTabKey = e.KeyCode === KeyCode.TAB;
|
|
520
523
|
if (isTabKey) {
|
|
521
524
|
const { start: selectionStart, end: selectionEnd } = this.selection;
|
|
522
525
|
if (e.shiftKey && isTabKey) {
|
|
@@ -548,45 +551,33 @@ export class DateInput extends Observable {
|
|
|
548
551
|
case KeyCode.ARROW_LEFT:
|
|
549
552
|
this.switchDateSegment(-1);
|
|
550
553
|
shouldPreventDefault = true;
|
|
554
|
+
this.switchedPartOnPreviousKeyAction = false;
|
|
551
555
|
break;
|
|
552
556
|
case KeyCode.ARROW_UP:
|
|
553
557
|
this.modifyDateSegmentValue(step, symbol, event);
|
|
554
558
|
shouldPreventDefault = true;
|
|
559
|
+
this.switchedPartOnPreviousKeyAction = false;
|
|
555
560
|
break;
|
|
556
561
|
case KeyCode.ARROW_RIGHT:
|
|
557
562
|
this.switchDateSegment(1);
|
|
558
563
|
shouldPreventDefault = true;
|
|
564
|
+
this.switchedPartOnPreviousKeyAction = false;
|
|
559
565
|
break;
|
|
560
566
|
case KeyCode.ARROW_DOWN:
|
|
561
567
|
this.modifyDateSegmentValue(-step, symbol, event);
|
|
562
568
|
shouldPreventDefault = true;
|
|
569
|
+
this.switchedPartOnPreviousKeyAction = false;
|
|
563
570
|
break;
|
|
564
571
|
case KeyCode.ENTER:
|
|
565
572
|
// todo: handle "change" event
|
|
566
573
|
break;
|
|
567
|
-
case KeyCode.DELETE:
|
|
568
|
-
case KeyCode.BACKSPACE:
|
|
569
|
-
if (this.options.allowNulls) {
|
|
570
|
-
const oldValue = this.dateObject.value;
|
|
571
|
-
this.dateObject.setValue(null);
|
|
572
|
-
this.forceUpdate();
|
|
573
|
-
this.tryTriggerValueChange({
|
|
574
|
-
oldValue: oldValue,
|
|
575
|
-
event: e
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
shouldPreventDefault = true;
|
|
579
|
-
if (e.keyCode === KeyCode.BACKSPACE &&
|
|
580
|
-
((this.options.autoSwitchKeys || []).indexOf(KeyCode.BACKSPACE) >= 0 ||
|
|
581
|
-
(this.options.autoSwitchKeys || []).indexOf(Key.BACKSPACE) >= 0)) {
|
|
582
|
-
this.switchDateSegment(-1);
|
|
583
|
-
}
|
|
584
|
-
return;
|
|
585
574
|
case Key.HOME:
|
|
586
575
|
this.selectNearestSegment(0);
|
|
576
|
+
this.switchedPartOnPreviousKeyAction = false;
|
|
587
577
|
break;
|
|
588
578
|
case Key.END:
|
|
589
579
|
this.selectNearestSegment(this.elementValue.length);
|
|
580
|
+
this.switchedPartOnPreviousKeyAction = false;
|
|
590
581
|
break;
|
|
591
582
|
default:
|
|
592
583
|
// allow the "input" event to handle the change
|
|
@@ -675,9 +666,11 @@ export class DateInput extends Observable {
|
|
|
675
666
|
return returnValue;
|
|
676
667
|
}
|
|
677
668
|
setSelection(selection) {
|
|
678
|
-
// this._lastSelectedSymbol = this.currentFormat[selection.start];
|
|
679
669
|
if (this.element && document.activeElement === this.element) {
|
|
680
670
|
this.element.setSelectionRange(selection.start, selection.end);
|
|
671
|
+
if (selection.start !== selection.end) {
|
|
672
|
+
this.interactionMode = DateInputInteractionMode.Selection;
|
|
673
|
+
}
|
|
681
674
|
}
|
|
682
675
|
}
|
|
683
676
|
/**
|
|
@@ -728,8 +721,7 @@ export class DateInput extends Observable {
|
|
|
728
721
|
const selection = this.selection;
|
|
729
722
|
if (this.isInCaretMode()) {
|
|
730
723
|
let start = selection.start;
|
|
731
|
-
const currentSymbol = this.currentFormat[start -
|
|
732
|
-
this.currentFormat[start];
|
|
724
|
+
const currentSymbol = this.currentFormat[start - 1];
|
|
733
725
|
let symbol = "";
|
|
734
726
|
let symbolCandidate = "";
|
|
735
727
|
if (offset < 0) {
|
|
@@ -903,6 +895,19 @@ export class DateInput extends Observable {
|
|
|
903
895
|
this.setTextAndFormat();
|
|
904
896
|
this.refreshElementValue();
|
|
905
897
|
}
|
|
898
|
+
/**
|
|
899
|
+
* @hidden
|
|
900
|
+
*/
|
|
901
|
+
forceUpdateWithSelection() {
|
|
902
|
+
const { start, end } = this.selection;
|
|
903
|
+
const elementValueLength = this.elementValue.length;
|
|
904
|
+
this.forceUpdate();
|
|
905
|
+
const selectionOffset = this.elementValue.length - elementValueLength;
|
|
906
|
+
this.setSelection({
|
|
907
|
+
start: start + selectionOffset,
|
|
908
|
+
end: end + selectionOffset
|
|
909
|
+
});
|
|
910
|
+
}
|
|
906
911
|
/**
|
|
907
912
|
* @hidden
|
|
908
913
|
*/
|
|
@@ -1084,4 +1089,18 @@ export class DateInput extends Observable {
|
|
|
1084
1089
|
}, options));
|
|
1085
1090
|
return dateObject;
|
|
1086
1091
|
}
|
|
1092
|
+
/* tslint:enable:align */
|
|
1093
|
+
/**
|
|
1094
|
+
* @hidden
|
|
1095
|
+
*/
|
|
1096
|
+
keyEventMatchesAutoSwitchKeys(keyObject) {
|
|
1097
|
+
const autoSwitchKeys = (this.options.autoSwitchKeys || [])
|
|
1098
|
+
.map(x => x.toString().toLowerCase().trim());
|
|
1099
|
+
if (autoSwitchKeys.indexOf(keyObject.keyCode.toString()) >= 0 ||
|
|
1100
|
+
autoSwitchKeys.indexOf(keyObject.keyCode) >= 0 ||
|
|
1101
|
+
autoSwitchKeys.indexOf(keyObject.key.toLowerCase().trim()) >= 0) {
|
|
1102
|
+
return true;
|
|
1103
|
+
}
|
|
1104
|
+
return false;
|
|
1105
|
+
}
|
|
1087
1106
|
}
|
|
@@ -67,8 +67,8 @@ export const approximateStringMatching = ({ oldText, newText, formatPattern, sel
|
|
|
67
67
|
return [[symbol, newSegmentText[selectionStart - 1]]];
|
|
68
68
|
}
|
|
69
69
|
/* Handle the entering of a space or a separator for navigating to the next item. */
|
|
70
|
-
if ((
|
|
71
|
-
(
|
|
70
|
+
if ((newSegmentText[newSegmentText.length - 1] === ' ') ||
|
|
71
|
+
(newSegmentText[newSegmentText.length - 1] === oldTextSeparator)) {
|
|
72
72
|
return [[formatPattern[selectionStart - 1], Constants.formatSeparator]];
|
|
73
73
|
}
|
|
74
74
|
/* Handle typing over a correctly selected part. */
|
|
@@ -533,7 +533,6 @@ var DateObject = /** @class */ (function () {
|
|
|
533
533
|
* @hidden
|
|
534
534
|
*/
|
|
535
535
|
DateObject.prototype.parsePart = function (_a) {
|
|
536
|
-
var _b;
|
|
537
536
|
var symbol = _a.symbol, currentChar = _a.currentChar, resetSegmentValue = _a.resetSegmentValue, cycleSegmentValue = _a.cycleSegmentValue, rawInputValue = _a.rawTextValue, isDeleting = _a.isDeleting, originalFormat = _a.originalFormat;
|
|
538
537
|
var isInCaretMode = !cycleSegmentValue;
|
|
539
538
|
var dateParts = this.dateFormatString(this.value, this.format);
|
|
@@ -578,7 +577,7 @@ var DateObject = /** @class */ (function () {
|
|
|
578
577
|
.some(function (x) { return x.pattern.length > MONTH_PART_WITH_WORDS_THRESHOLD; });
|
|
579
578
|
var parseResult = {
|
|
580
579
|
value: null,
|
|
581
|
-
|
|
580
|
+
switchToNext: false,
|
|
582
581
|
resetPart: shouldResetPart,
|
|
583
582
|
hasInvalidDatePart: false
|
|
584
583
|
};
|
|
@@ -601,8 +600,7 @@ var DateObject = /** @class */ (function () {
|
|
|
601
600
|
this.resetLeadingZero();
|
|
602
601
|
this.setExisting(symbol, false);
|
|
603
602
|
this.resetInvalidDateSymbol(symbol);
|
|
604
|
-
|
|
605
|
-
return { value: null, switchToNext: false };
|
|
603
|
+
return utils_2.extend(parseResult, { value: null, switchToNext: false });
|
|
606
604
|
}
|
|
607
605
|
}
|
|
608
606
|
var baseDate = this.intl.formatDate(this.value, this.format, this.localeId);
|
|
@@ -625,21 +623,13 @@ var DateObject = /** @class */ (function () {
|
|
|
625
623
|
var datePartStartIndex = (hasFixedFormat ? convertedBaseFormat : originalFormat).indexOf(symbol);
|
|
626
624
|
var datePartEndIndex = (hasFixedFormat ? convertedBaseFormat : originalFormat).lastIndexOf(symbol);
|
|
627
625
|
var segmentLength = datePartEndIndex - datePartStartIndex + 1;
|
|
628
|
-
var processedSegmentCharsCount = 0;
|
|
629
626
|
var formatToTextLengthDiff = originalFormat.length - rawInputValue.length;
|
|
630
627
|
if (isInCaretMode || (!isInCaretMode && !this.autoCorrectParts)) {
|
|
631
628
|
for (var i = 0; i < baseDate.length; i++) {
|
|
632
629
|
if (baseFormat[i] === symbol) {
|
|
633
630
|
var existing = this.getExisting(symbol);
|
|
634
631
|
current += existing ? baseDate[i] : '0';
|
|
635
|
-
if (
|
|
636
|
-
// when deleting, process (segmentLength - 1) chars
|
|
637
|
-
if (processedSegmentCharsCount < segmentLength - 1) {
|
|
638
|
-
datePartText += rawInputValue[i] || "";
|
|
639
|
-
}
|
|
640
|
-
processedSegmentCharsCount++;
|
|
641
|
-
}
|
|
642
|
-
else if (formatToTextLengthDiff > 0) {
|
|
632
|
+
if (formatToTextLengthDiff > 0) {
|
|
643
633
|
if (datePartText.length + formatToTextLengthDiff < segmentLength) {
|
|
644
634
|
datePartText += rawInputValue[i] || "";
|
|
645
635
|
}
|
|
@@ -663,18 +653,13 @@ var DateObject = /** @class */ (function () {
|
|
|
663
653
|
datePartText += currentChar;
|
|
664
654
|
}
|
|
665
655
|
else if (!isDeleting && originalFormat.length > rawInputValue.length) {
|
|
666
|
-
|
|
667
|
-
var trimmedDatePartText = datePartText.substr(0, datePartText.length - lengthDiff);
|
|
668
|
-
if (trimmedDatePartText && trimmedDatePartText.length > 0) {
|
|
669
|
-
datePartText = trimmedDatePartText;
|
|
670
|
-
}
|
|
656
|
+
// let the parsing to determine if the incomplete value is valid
|
|
671
657
|
}
|
|
672
658
|
if (datePartText.length > segmentLength) {
|
|
673
659
|
return utils_2.extend(parseResult, { value: null, switchToNext: false });
|
|
674
660
|
}
|
|
675
661
|
}
|
|
676
662
|
if (!hasFixedFormat || (hasFixedFormat && !this.autoCorrectParts)) {
|
|
677
|
-
processedSegmentCharsCount = 0;
|
|
678
663
|
current = "";
|
|
679
664
|
datePartText = "";
|
|
680
665
|
prefix = "";
|
|
@@ -684,14 +669,7 @@ var DateObject = /** @class */ (function () {
|
|
|
684
669
|
if (originalFormat[i] === symbol) {
|
|
685
670
|
var existing = this.getExisting(symbol);
|
|
686
671
|
current += existing ? baseDate[i] || "" : '0';
|
|
687
|
-
if (
|
|
688
|
-
// when deleting, process (segmentLength - 1) chars
|
|
689
|
-
if (processedSegmentCharsCount < segmentLength - 1) {
|
|
690
|
-
datePartText += rawInputValue[i] || "";
|
|
691
|
-
}
|
|
692
|
-
processedSegmentCharsCount++;
|
|
693
|
-
}
|
|
694
|
-
else if (formatToTextLengthDiff > 0) {
|
|
672
|
+
if (formatToTextLengthDiff > 0) {
|
|
695
673
|
if (datePartText.length + formatToTextLengthDiff < segmentLength) {
|
|
696
674
|
datePartText += rawInputValue[i] || "";
|
|
697
675
|
}
|
|
@@ -715,7 +693,6 @@ var DateObject = /** @class */ (function () {
|
|
|
715
693
|
}
|
|
716
694
|
if (!isInCaretMode) {
|
|
717
695
|
if (this.autoCorrectParts) {
|
|
718
|
-
processedSegmentCharsCount = 0;
|
|
719
696
|
current = "";
|
|
720
697
|
datePartText = "";
|
|
721
698
|
prefix = "";
|
|
@@ -760,6 +737,7 @@ var DateObject = /** @class */ (function () {
|
|
|
760
737
|
}
|
|
761
738
|
var partPattern = this.partPattern(dateParts.partMap, symbol);
|
|
762
739
|
var patternValue = partPattern ? partPattern.pattern : null;
|
|
740
|
+
var patternLength = this.patternLength(patternValue) || patternValue.length;
|
|
763
741
|
if (isInCaretMode) {
|
|
764
742
|
if (isDeleting && !datePartText) {
|
|
765
743
|
this.setExisting(symbol, false);
|
|
@@ -781,11 +759,13 @@ var DateObject = /** @class */ (function () {
|
|
|
781
759
|
if (isInCaretMode || !this.autoCorrectParts) {
|
|
782
760
|
tryParse = false;
|
|
783
761
|
middle = utils_1.unpadZero(middle);
|
|
784
|
-
middle =
|
|
762
|
+
// middle = padZero(segmentLength - middle.length) + middle;
|
|
763
|
+
middle = utils_1.padZero(patternLength - middle.length) + middle;
|
|
785
764
|
}
|
|
786
765
|
var middleNumber = parseInt(middle, 10);
|
|
787
766
|
var candidateDateString = prefix + middle + suffix;
|
|
788
767
|
parsedDate = this.intl.parseDate(candidateDateString, this.format, this.localeId);
|
|
768
|
+
var autoCorrectedPrefixAndSuffix = false;
|
|
789
769
|
if (isInCaretMode && !utils_2.isValidDate(parsedDate)) {
|
|
790
770
|
// if part of the date is not available, e.g. "d"
|
|
791
771
|
// but an expanded format like "F" is used
|
|
@@ -796,6 +776,7 @@ var DateObject = /** @class */ (function () {
|
|
|
796
776
|
// as "EEEE, February..." is not parsable
|
|
797
777
|
if (this.autoCorrectParts) {
|
|
798
778
|
parsedDate = this.intl.parseDate(basePrefix + middle + baseSuffix, this.format, this.localeId);
|
|
779
|
+
autoCorrectedPrefixAndSuffix = true;
|
|
799
780
|
}
|
|
800
781
|
}
|
|
801
782
|
var isCurrentCharParsable = !isNaN(parseInt(currentChar, 10)) || (isInCaretMode && isDeleting && currentChar === "");
|
|
@@ -822,10 +803,22 @@ var DateObject = /** @class */ (function () {
|
|
|
822
803
|
if ((isInCaretMode && utils_2.isValidDate(parsedDate)) || (!isInCaretMode && parsedDate)) {
|
|
823
804
|
// move to next segment if the part will overflow with next char
|
|
824
805
|
// when start from empty date (01, then 010), padded zeros should be trimmed
|
|
825
|
-
var
|
|
826
|
-
var
|
|
827
|
-
|
|
828
|
-
|
|
806
|
+
var peekedValue = this.peek(middle, patternValue);
|
|
807
|
+
var peekedDateString = autoCorrectedPrefixAndSuffix ?
|
|
808
|
+
"" + basePrefix + peekedValue + baseSuffix :
|
|
809
|
+
"" + prefix + peekedValue + suffix;
|
|
810
|
+
var peekedDate = this.intl.parseDate(peekedDateString, this.format, this.localeId);
|
|
811
|
+
var leadingZeroOffset = (this.leadingZero || {})[symbol] || 0;
|
|
812
|
+
var patternSatisfied = (leadingZeroOffset + utils_1.unpadZero(middle).length) >= patternLength;
|
|
813
|
+
var switchToNext = peekedDate === null ||
|
|
814
|
+
(leadingZero[symbol] ?
|
|
815
|
+
patternValue.length <= middle.length :
|
|
816
|
+
patternSatisfied);
|
|
817
|
+
// console.log("peeek: " + peekedDate);
|
|
818
|
+
// console.log("lead : " + (leadingZero[symbol] && patternValue.length <= middle.length ));
|
|
819
|
+
// console.log("pat s: " + patternSatisfied);
|
|
820
|
+
// console.log("middl: " + middle);
|
|
821
|
+
// console.log("pater: " + patternValue);
|
|
829
822
|
if (this.shouldNormalizeCentury()) {
|
|
830
823
|
parsedDate = this.normalizeCentury(parsedDate);
|
|
831
824
|
}
|
|
@@ -851,24 +844,6 @@ var DateObject = /** @class */ (function () {
|
|
|
851
844
|
this.markDatePartsAsExisting();
|
|
852
845
|
}
|
|
853
846
|
}
|
|
854
|
-
if (isInCaretMode && switchToNext) {
|
|
855
|
-
if (symbol === "M") {
|
|
856
|
-
var datePartValue = utils_2.parseToInt(datePartText);
|
|
857
|
-
if (datePartValue >= 2 || datePartText.length >= 2) {
|
|
858
|
-
switchToNext = true;
|
|
859
|
-
}
|
|
860
|
-
else {
|
|
861
|
-
switchToNext = false;
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
else {
|
|
865
|
-
switchToNext = switchToNext ?
|
|
866
|
-
hasFixedFormat ?
|
|
867
|
-
datePartText.length === segmentLength :
|
|
868
|
-
datePartText.length > segmentLength :
|
|
869
|
-
switchToNext;
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
847
|
return utils_2.extend(parseResult, { value: this.value, switchToNext: switchToNext });
|
|
873
848
|
}
|
|
874
849
|
}
|
|
@@ -888,7 +863,6 @@ var DateObject = /** @class */ (function () {
|
|
|
888
863
|
}
|
|
889
864
|
}
|
|
890
865
|
if (isZeroCurrentChar) {
|
|
891
|
-
this.leadingZero = !this.isAbbrMonth(dateParts.partMap, symbol) ? (_b = {}, _b[symbol] = true, _b) : null;
|
|
892
866
|
this.setExisting(symbol, false);
|
|
893
867
|
}
|
|
894
868
|
if (!this.autoCorrectParts) {
|