@progress/kendo-dateinputs-common 0.2.0-dev.202301161405 → 0.2.0-dev.202301171717
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 +203 -66
- package/dist/es/dateinput/dateinput.js +58 -7
- package/dist/es2015/common/dateobject.js +204 -67
- package/dist/es2015/dateinput/dateinput.js +59 -8
- package/dist/npm/common/dateobject.d.ts +4 -0
- package/dist/npm/common/dateobject.js +203 -66
- package/dist/npm/dateinput/dateinput.d.ts +1 -0
- package/dist/npm/dateinput/dateinput.js +58 -7
- package/dist/systemjs/kendo-dateinputs-common.js +1 -1
- package/package.json +1 -1
|
@@ -530,6 +530,14 @@ export class DateObject {
|
|
|
530
530
|
literal: ""
|
|
531
531
|
};
|
|
532
532
|
});
|
|
533
|
+
const flatDateParts = dateParts.partMap
|
|
534
|
+
.map((x) => {
|
|
535
|
+
return {
|
|
536
|
+
type: x.type,
|
|
537
|
+
pattern: x.pattern,
|
|
538
|
+
text: ""
|
|
539
|
+
};
|
|
540
|
+
});
|
|
533
541
|
for (let i = 0; i < datePartsLiterals.length; i++) {
|
|
534
542
|
const datePart = datePartsLiterals[i];
|
|
535
543
|
for (let j = 0; j < datePart.pattern.length; j++) {
|
|
@@ -539,13 +547,23 @@ export class DateObject {
|
|
|
539
547
|
}
|
|
540
548
|
i += datePart.pattern.length - 1;
|
|
541
549
|
}
|
|
550
|
+
for (let i = 0; i < flatDateParts.length; i++) {
|
|
551
|
+
const datePart = flatDateParts[i];
|
|
552
|
+
for (let j = 0; j < datePart.pattern.length; j++) {
|
|
553
|
+
if (flatDateParts[i + j]) {
|
|
554
|
+
flatDateParts[i + j].text = datePart.pattern[j];
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
i += datePart.pattern.length - 1;
|
|
558
|
+
}
|
|
542
559
|
let shouldResetPart = isInCaretMode && symbol === "M" && dateParts.partMap
|
|
543
560
|
.filter(x => x.type === "month")
|
|
544
561
|
.some(x => x.pattern.length > MONTH_PART_WITH_WORDS_THRESHOLD);
|
|
545
562
|
let parseResult = {
|
|
546
563
|
value: null,
|
|
547
564
|
switchPart: false,
|
|
548
|
-
resetPart: shouldResetPart
|
|
565
|
+
resetPart: shouldResetPart,
|
|
566
|
+
hasInvalidDatePart: false
|
|
549
567
|
};
|
|
550
568
|
if (!currentChar) {
|
|
551
569
|
if (isInCaretMode) {
|
|
@@ -579,13 +597,19 @@ export class DateObject {
|
|
|
579
597
|
let basePrefix = '';
|
|
580
598
|
let baseSuffix = '';
|
|
581
599
|
let suffix = '';
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
600
|
+
let convertedBaseFormat = "";
|
|
601
|
+
for (let i = 0; i < flatDateParts.length; i++) {
|
|
602
|
+
convertedBaseFormat += flatDateParts[i].text;
|
|
603
|
+
}
|
|
585
604
|
const hasFixedFormat = (this.format === baseFormat) ||
|
|
605
|
+
(this.format === convertedBaseFormat) ||
|
|
586
606
|
(this.format === originalFormat) ||
|
|
587
607
|
(this.format.length === originalFormat.length);
|
|
608
|
+
const datePartStartIndex = (hasFixedFormat ? convertedBaseFormat : originalFormat).indexOf(symbol);
|
|
609
|
+
const datePartEndIndex = (hasFixedFormat ? convertedBaseFormat : originalFormat).lastIndexOf(symbol);
|
|
610
|
+
const segmentLength = datePartEndIndex - datePartStartIndex + 1;
|
|
588
611
|
let processedSegmentCharsCount = 0;
|
|
612
|
+
let formatToTextLengthDiff = originalFormat.length - rawInputValue.length;
|
|
589
613
|
if (isInCaretMode || (!isInCaretMode && !this.autoCorrectParts)) {
|
|
590
614
|
for (let i = 0; i < baseDate.length; i++) {
|
|
591
615
|
if (baseFormat[i] === symbol) {
|
|
@@ -598,6 +622,11 @@ export class DateObject {
|
|
|
598
622
|
}
|
|
599
623
|
processedSegmentCharsCount++;
|
|
600
624
|
}
|
|
625
|
+
else if (formatToTextLengthDiff > 0) {
|
|
626
|
+
if (datePartText.length + formatToTextLengthDiff < segmentLength) {
|
|
627
|
+
datePartText += rawInputValue[i] || "";
|
|
628
|
+
}
|
|
629
|
+
}
|
|
601
630
|
else {
|
|
602
631
|
datePartText += rawInputValue[i] || "";
|
|
603
632
|
}
|
|
@@ -612,13 +641,13 @@ export class DateObject {
|
|
|
612
641
|
baseSuffix += baseDate[i];
|
|
613
642
|
}
|
|
614
643
|
}
|
|
615
|
-
if (hasFixedFormat
|
|
616
|
-
if (
|
|
644
|
+
if (hasFixedFormat) {
|
|
645
|
+
if (convertedBaseFormat.length < rawInputValue.length) {
|
|
617
646
|
datePartText += currentChar;
|
|
618
647
|
}
|
|
619
648
|
else if (!isDeleting && originalFormat.length > rawInputValue.length) {
|
|
620
649
|
const lengthDiff = originalFormat.length - rawInputValue.length;
|
|
621
|
-
const trimmedDatePartText = datePartText.
|
|
650
|
+
const trimmedDatePartText = datePartText.substr(0, datePartText.length - lengthDiff);
|
|
622
651
|
if (trimmedDatePartText && trimmedDatePartText.length > 0) {
|
|
623
652
|
datePartText = trimmedDatePartText;
|
|
624
653
|
}
|
|
@@ -627,7 +656,7 @@ export class DateObject {
|
|
|
627
656
|
return extend(parseResult, { value: null, switchToNext: false });
|
|
628
657
|
}
|
|
629
658
|
}
|
|
630
|
-
|
|
659
|
+
if (!hasFixedFormat || (hasFixedFormat && !this.autoCorrectParts)) {
|
|
631
660
|
processedSegmentCharsCount = 0;
|
|
632
661
|
current = "";
|
|
633
662
|
datePartText = "";
|
|
@@ -645,6 +674,11 @@ export class DateObject {
|
|
|
645
674
|
}
|
|
646
675
|
processedSegmentCharsCount++;
|
|
647
676
|
}
|
|
677
|
+
else if (formatToTextLengthDiff > 0) {
|
|
678
|
+
if (datePartText.length + formatToTextLengthDiff < segmentLength) {
|
|
679
|
+
datePartText += rawInputValue[i] || "";
|
|
680
|
+
}
|
|
681
|
+
}
|
|
648
682
|
else {
|
|
649
683
|
datePartText += rawInputValue[i] || "";
|
|
650
684
|
}
|
|
@@ -654,24 +688,12 @@ export class DateObject {
|
|
|
654
688
|
prefix += rawInputValue[i] || "";
|
|
655
689
|
}
|
|
656
690
|
else {
|
|
657
|
-
suffix += rawInputValue[i] || "";
|
|
691
|
+
suffix += rawInputValue[i - formatToTextLengthDiff] || "";
|
|
658
692
|
}
|
|
659
693
|
}
|
|
660
694
|
if (originalFormat.length < rawInputValue.length) {
|
|
661
695
|
datePartText += currentChar;
|
|
662
696
|
}
|
|
663
|
-
else if (!isDeleting && originalFormat.length > rawInputValue.length) {
|
|
664
|
-
const lengthDiff = originalFormat.length - rawInputValue.length;
|
|
665
|
-
const trimmedDatePartText = datePartText.substring(0, datePartText.length - lengthDiff);
|
|
666
|
-
if (trimmedDatePartText && trimmedDatePartText.length > 0) {
|
|
667
|
-
const originalDatePartText = datePartText;
|
|
668
|
-
datePartText = trimmedDatePartText;
|
|
669
|
-
if (prefix + datePartText + suffix !== rawInputValue) {
|
|
670
|
-
// move trimmed characters to the suffix
|
|
671
|
-
suffix = originalDatePartText.substring(datePartText.length) + suffix;
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
697
|
}
|
|
676
698
|
}
|
|
677
699
|
if (!isInCaretMode) {
|
|
@@ -701,12 +723,17 @@ export class DateObject {
|
|
|
701
723
|
}
|
|
702
724
|
}
|
|
703
725
|
let parsedDate = null;
|
|
704
|
-
|
|
726
|
+
let month = this.matchMonth(currentChar);
|
|
705
727
|
const dayPeriod = this.matchDayPeriod(currentChar, symbol);
|
|
706
728
|
const isZeroCurrentChar = currentChar === '0';
|
|
707
729
|
const leadingZero = this.leadingZero || {};
|
|
708
|
-
if (isZeroCurrentChar
|
|
709
|
-
|
|
730
|
+
if (isZeroCurrentChar) {
|
|
731
|
+
if (datePartText === "0") {
|
|
732
|
+
datePartText = current;
|
|
733
|
+
}
|
|
734
|
+
let valueNumber = parseToInt(resetSegmentValue ?
|
|
735
|
+
currentChar :
|
|
736
|
+
(isInCaretMode ? datePartText : current) + currentChar);
|
|
710
737
|
if (valueNumber === 0 && !this.isAbbrMonth(dateParts.partMap, symbol)) {
|
|
711
738
|
this.incrementLeadingZero(symbol);
|
|
712
739
|
}
|
|
@@ -734,23 +761,15 @@ export class DateObject {
|
|
|
734
761
|
isInCaretMode ?
|
|
735
762
|
datePartText :
|
|
736
763
|
(current.substring(i) + currentChar);
|
|
737
|
-
if (!this.autoCorrectParts) {
|
|
738
|
-
tryParse = false;
|
|
739
|
-
if (!isInCaretMode) {
|
|
740
|
-
// try to make an exact match as there will be only 1 attempt
|
|
741
|
-
middle = unpadZero(middle);
|
|
742
|
-
middle = padZero(segmentLength - middle.length) + middle;
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
if (isInCaretMode) {
|
|
746
|
-
// try to make an exact match as there will be only 1 attempt
|
|
764
|
+
if (isInCaretMode || !this.autoCorrectParts) {
|
|
747
765
|
tryParse = false;
|
|
748
766
|
middle = unpadZero(middle);
|
|
767
|
+
middle = padZero(segmentLength - middle.length) + middle;
|
|
749
768
|
}
|
|
750
769
|
let middleNumber = parseInt(middle, 10);
|
|
751
770
|
const candidateDateString = prefix + middle + suffix;
|
|
752
771
|
parsedDate = this.intl.parseDate(candidateDateString, this.format, this.localeId);
|
|
753
|
-
if (isInCaretMode && !
|
|
772
|
+
if (isInCaretMode && !isValidDate(parsedDate)) {
|
|
754
773
|
// if part of the date is not available, e.g. "d"
|
|
755
774
|
// but an expanded format like "F" is used
|
|
756
775
|
// the element value can be "EEEE, February 1, 2022 3:04:05 AM"
|
|
@@ -760,7 +779,6 @@ export class DateObject {
|
|
|
760
779
|
// as "EEEE, February..." is not parsable
|
|
761
780
|
if (this.autoCorrectParts) {
|
|
762
781
|
parsedDate = this.intl.parseDate(basePrefix + middle + baseSuffix, this.format, this.localeId);
|
|
763
|
-
datePartText = middle;
|
|
764
782
|
}
|
|
765
783
|
}
|
|
766
784
|
const isCurrentCharParsable = !isNaN(parseInt(currentChar, 10)) || (isInCaretMode && isDeleting && currentChar === "");
|
|
@@ -821,14 +839,12 @@ export class DateObject {
|
|
|
821
839
|
}
|
|
822
840
|
if (isInCaretMode && switchToNext) {
|
|
823
841
|
if (symbol === "M") {
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
switchToNext = false;
|
|
831
|
-
}
|
|
842
|
+
const datePartValue = parseToInt(datePartText);
|
|
843
|
+
if (datePartValue >= 2 || datePartText.length >= 2) {
|
|
844
|
+
switchToNext = true;
|
|
845
|
+
}
|
|
846
|
+
else {
|
|
847
|
+
switchToNext = false;
|
|
832
848
|
}
|
|
833
849
|
}
|
|
834
850
|
else {
|
|
@@ -861,9 +877,6 @@ export class DateObject {
|
|
|
861
877
|
this.leadingZero = !this.isAbbrMonth(dateParts.partMap, symbol) ? { [symbol]: true } : null;
|
|
862
878
|
this.setExisting(symbol, false);
|
|
863
879
|
}
|
|
864
|
-
if (isInCaretMode && datePartText.length > segmentLength) {
|
|
865
|
-
return extend(parseResult, { value: null, switchToNext: false });
|
|
866
|
-
}
|
|
867
880
|
if (!this.autoCorrectParts) {
|
|
868
881
|
let datePartValue;
|
|
869
882
|
const textToParse = isInCaretMode ? datePartText : middle;
|
|
@@ -874,20 +887,146 @@ export class DateObject {
|
|
|
874
887
|
return extend(parseResult, { value: null, switchToNext: false });
|
|
875
888
|
}
|
|
876
889
|
datePartValue = symbol === "M" ?
|
|
877
|
-
|
|
890
|
+
parsedValue - JS_MONTH_OFFSET :
|
|
878
891
|
parsedValue;
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
this.
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
892
|
+
const isMonth = symbol === "M";
|
|
893
|
+
const isDay = symbol === "d";
|
|
894
|
+
let newValue = cloneDate(this._value);
|
|
895
|
+
const invalidDateParts = this._partiallyInvalidDate.invalidDateParts || {};
|
|
896
|
+
let year = invalidDateParts.y.value || newValue.getFullYear();
|
|
897
|
+
/* tslint:disable:no-shadowed-variable */
|
|
898
|
+
let month = isMonth ? datePartValue : invalidDateParts.M.value || newValue.getMonth();
|
|
899
|
+
/* tslint:enable:no-shadowed-variable */
|
|
900
|
+
let day = isDay ? datePartValue : invalidDateParts.d.value || invalidDateParts.E.value || newValue.getDate();
|
|
901
|
+
let hour = invalidDateParts.h.value || invalidDateParts.H.value || newValue.getHours();
|
|
902
|
+
let minutes = invalidDateParts.m.value || newValue.getMinutes();
|
|
903
|
+
let seconds = invalidDateParts.s.value || newValue.getSeconds();
|
|
904
|
+
let milliseconds = invalidDateParts.S.value || newValue.getMilliseconds();
|
|
905
|
+
const dateCandidate = createDate(year, month, day, hour, minutes, seconds, milliseconds);
|
|
906
|
+
const dateCandidateExists = areDatePartsEqualTo(dateCandidate, year, month, day, hour, minutes, seconds, milliseconds);
|
|
907
|
+
const newValueCandidate = isMonth || isDay ?
|
|
908
|
+
this.modifyDateSymbolWithValue(newValue, symbol, isMonth ? month : day) :
|
|
909
|
+
null;
|
|
910
|
+
let invalidDateFound = false;
|
|
911
|
+
if (isMonth && newValueCandidate) {
|
|
912
|
+
if (newValueCandidate.getMonth() === month) {
|
|
913
|
+
if (this.getExisting("d")) {
|
|
914
|
+
if (dateCandidateExists) {
|
|
915
|
+
newValue = cloneDate(dateCandidate);
|
|
916
|
+
this.resetInvalidDateSymbol(symbol);
|
|
917
|
+
}
|
|
918
|
+
else {
|
|
919
|
+
invalidDateFound = true;
|
|
920
|
+
this.setInvalidDatePart(symbol, {
|
|
921
|
+
value: month,
|
|
922
|
+
date: cloneDate(newValueCandidate),
|
|
923
|
+
// startDateOffset: offset,
|
|
924
|
+
startDate: cloneDate(this.value)
|
|
925
|
+
});
|
|
926
|
+
this.setExisting(symbol, false);
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
else if (dateCandidateExists) {
|
|
930
|
+
this.resetInvalidDateSymbol(symbol);
|
|
931
|
+
newValue = cloneDate(dateCandidate);
|
|
932
|
+
if (this.getExisting("M") && this.getExisting("y")) {
|
|
933
|
+
// changing from 28/Feb to 29/Feb to 29/March
|
|
934
|
+
this.setExisting("d", true);
|
|
935
|
+
this.resetInvalidDateSymbol("d");
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
else {
|
|
939
|
+
this.resetInvalidDateSymbol(symbol);
|
|
940
|
+
newValue = cloneDate(newValueCandidate);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
invalidDateFound = true;
|
|
945
|
+
this.setInvalidDatePart(symbol, {
|
|
946
|
+
value: month,
|
|
947
|
+
date: cloneDate(newValueCandidate),
|
|
948
|
+
// startDateOffset: offset,
|
|
949
|
+
startDate: cloneDate(this.value)
|
|
950
|
+
});
|
|
951
|
+
this.setExisting(symbol, false);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
else if (isDay && newValueCandidate) {
|
|
955
|
+
if (newValueCandidate.getDate() === day) {
|
|
956
|
+
if (this.getExisting("M")) {
|
|
957
|
+
if (dateCandidateExists) {
|
|
958
|
+
newValue = cloneDate(dateCandidate);
|
|
959
|
+
this.resetInvalidDateSymbol(symbol);
|
|
960
|
+
}
|
|
961
|
+
else {
|
|
962
|
+
invalidDateFound = true;
|
|
963
|
+
this.setInvalidDatePart(symbol, {
|
|
964
|
+
value: day,
|
|
965
|
+
date: cloneDate(newValueCandidate),
|
|
966
|
+
// startDateOffset: offset,
|
|
967
|
+
startDate: cloneDate(this.value)
|
|
968
|
+
});
|
|
969
|
+
this.setExisting(symbol, false);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
else if (dateCandidateExists) {
|
|
973
|
+
newValue = cloneDate(dateCandidate);
|
|
974
|
+
this.resetInvalidDateSymbol(symbol);
|
|
975
|
+
if (this.getExisting("d") && this.getExisting("y")) {
|
|
976
|
+
// changing from 31/Jan to 31/Feb to 28/Feb
|
|
977
|
+
this.setExisting("M", true);
|
|
978
|
+
this.resetInvalidDateSymbol("M");
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
else {
|
|
982
|
+
this.resetInvalidDateSymbol(symbol);
|
|
983
|
+
newValue = cloneDate(newValueCandidate);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
else {
|
|
987
|
+
invalidDateFound = true;
|
|
988
|
+
this.setInvalidDatePart(symbol, {
|
|
989
|
+
value: day,
|
|
990
|
+
date: cloneDate(this.value),
|
|
991
|
+
// startDateOffset: offset,
|
|
992
|
+
startDate: cloneDate(this.value)
|
|
993
|
+
});
|
|
994
|
+
this.setExisting(symbol, false);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
if (!invalidDateFound) {
|
|
998
|
+
this.setExisting(symbol, true);
|
|
999
|
+
if (isInCaretMode && !isValidDate(parsedDate)) {
|
|
1000
|
+
const valueCandidate = this.intl.parseDate(basePrefix + middle + baseSuffix, this.format, this.localeId);
|
|
1001
|
+
if (isValidDate(valueCandidate)) {
|
|
1002
|
+
this._value = valueCandidate;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
else {
|
|
1006
|
+
this._value = newValue;
|
|
1007
|
+
}
|
|
1008
|
+
if (this.getValue()) {
|
|
1009
|
+
this.resetInvalidDate();
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
let switchToNext = false;
|
|
1013
|
+
if (symbol === "M") {
|
|
1014
|
+
if (parsedValue >= 2 || textToParse.length >= 2) {
|
|
1015
|
+
switchToNext = true;
|
|
1016
|
+
}
|
|
1017
|
+
else {
|
|
1018
|
+
switchToNext = false;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
else {
|
|
1022
|
+
switchToNext = hasFixedFormat ?
|
|
1023
|
+
textToParse.length === segmentLength :
|
|
1024
|
+
textToParse.length > segmentLength;
|
|
1025
|
+
}
|
|
887
1026
|
return extend(parseResult, {
|
|
888
1027
|
value: null,
|
|
889
|
-
switchToNext:
|
|
890
|
-
hasInvalidDatePart:
|
|
1028
|
+
switchToNext: switchToNext,
|
|
1029
|
+
hasInvalidDatePart: invalidDateFound
|
|
891
1030
|
});
|
|
892
1031
|
}
|
|
893
1032
|
}
|
|
@@ -910,6 +1049,12 @@ export class DateObject {
|
|
|
910
1049
|
setLeadingZero(leadingZero) {
|
|
911
1050
|
this.leadingZero = leadingZero;
|
|
912
1051
|
}
|
|
1052
|
+
/**
|
|
1053
|
+
* @hidden
|
|
1054
|
+
*/
|
|
1055
|
+
getLeadingZero() {
|
|
1056
|
+
return this.leadingZero || {};
|
|
1057
|
+
}
|
|
913
1058
|
/**
|
|
914
1059
|
* @hidden
|
|
915
1060
|
*/
|
|
@@ -992,7 +1137,6 @@ export class DateObject {
|
|
|
992
1137
|
const dateFormatParts = this.intl.splitDateFormat(this.format, this.localeId);
|
|
993
1138
|
for (let i = 0; i < dateFormatParts.length; i++) {
|
|
994
1139
|
if (dateFormatParts[i].type === 'month' && dateFormatParts[i].names) {
|
|
995
|
-
// return this.intl.dateFormatNames(dateFormatParts[i].names);
|
|
996
1140
|
return this.intl.dateFormatNames(locale, dateFormatParts[i].names);
|
|
997
1141
|
}
|
|
998
1142
|
}
|
|
@@ -1200,15 +1344,8 @@ export class DateObject {
|
|
|
1200
1344
|
return (invalidDatePart || {}).value;
|
|
1201
1345
|
}
|
|
1202
1346
|
setInvalidDatePart(symbol, { value = null, date = null, startDateOffset = 0, startDate = null }) {
|
|
1203
|
-
let clampedValue = value;
|
|
1204
|
-
if (symbol === "d") {
|
|
1205
|
-
clampedValue = clamp(isPresent(value) ? value : 1, 1, 31);
|
|
1206
|
-
}
|
|
1207
|
-
else if (symbol === "M") {
|
|
1208
|
-
clampedValue = clamp(isPresent(value) ? value : 0, 0, 11);
|
|
1209
|
-
}
|
|
1210
1347
|
if (this._partiallyInvalidDate.invalidDateParts[symbol]) {
|
|
1211
|
-
this._partiallyInvalidDate.invalidDateParts[symbol].value =
|
|
1348
|
+
this._partiallyInvalidDate.invalidDateParts[symbol].value = value;
|
|
1212
1349
|
this._partiallyInvalidDate.invalidDateParts[symbol].date = date;
|
|
1213
1350
|
this._partiallyInvalidDate.invalidDateParts[symbol].startDateOffset = startDateOffset;
|
|
1214
1351
|
this._partiallyInvalidDate.startDate = startDate;
|
|
@@ -29,6 +29,7 @@ const CHANGE = "change";
|
|
|
29
29
|
const defaultDateInputOptions = {
|
|
30
30
|
format: "d",
|
|
31
31
|
allowNulls: false,
|
|
32
|
+
hasPlaceholder: false,
|
|
32
33
|
placeholder: null,
|
|
33
34
|
cycleTime: true,
|
|
34
35
|
locale: null,
|
|
@@ -286,7 +287,7 @@ export class DateInput extends Observable {
|
|
|
286
287
|
text = currentText;
|
|
287
288
|
}
|
|
288
289
|
const newText = this.elementValue;
|
|
289
|
-
|
|
290
|
+
let diff = approximateStringMatching({
|
|
290
291
|
oldText: text,
|
|
291
292
|
newText: newText,
|
|
292
293
|
formatPattern: this.currentFormat,
|
|
@@ -294,6 +295,24 @@ export class DateInput extends Observable {
|
|
|
294
295
|
isInCaretMode: hasCaret,
|
|
295
296
|
keyEvent: this.keyDownEvent
|
|
296
297
|
});
|
|
298
|
+
const currentFormatChar = this.formatStateOnKeyDown.format[this.formatStateOnKeyDown.selectionStart] || "";
|
|
299
|
+
if (this.options.allowCaretMode && hasCaret && this.currentFormat.length !== this.elementValue.length) {
|
|
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
|
+
}
|
|
315
|
+
}
|
|
297
316
|
if (hasCaret && (!diff || diff.length === 0)) {
|
|
298
317
|
this.restorePreviousInputEventState();
|
|
299
318
|
return;
|
|
@@ -366,10 +385,30 @@ export class DateInput extends Observable {
|
|
|
366
385
|
if (switchPart) {
|
|
367
386
|
this.switchDateSegment(1);
|
|
368
387
|
}
|
|
388
|
+
else {
|
|
389
|
+
if (this.options.format.length !== this.currentFormat.length &&
|
|
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
|
+
}
|
|
399
|
+
}
|
|
369
400
|
}
|
|
370
401
|
else {
|
|
371
|
-
if (lastParseResultHasNoValue
|
|
372
|
-
this.
|
|
402
|
+
if (lastParseResultHasNoValue) {
|
|
403
|
+
let hasLeadingZero = this.dateObject.getLeadingZero()[currentFormatChar];
|
|
404
|
+
if (switchPart) {
|
|
405
|
+
this.switchDateSegment(1);
|
|
406
|
+
}
|
|
407
|
+
else if (e.data === "0" && hasLeadingZero) {
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
this.restorePreviousInputEventState();
|
|
411
|
+
}
|
|
373
412
|
}
|
|
374
413
|
}
|
|
375
414
|
}
|
|
@@ -394,7 +433,10 @@ export class DateInput extends Observable {
|
|
|
394
433
|
}
|
|
395
434
|
}
|
|
396
435
|
else {
|
|
397
|
-
|
|
436
|
+
let hasLeadingZero = this.dateObject.getLeadingZero()[currentFormatChar];
|
|
437
|
+
if (e.data === "0" && hasLeadingZero) {
|
|
438
|
+
}
|
|
439
|
+
else if (!hasInvalidDatePart) {
|
|
398
440
|
this.restorePreviousInputEventState();
|
|
399
441
|
}
|
|
400
442
|
}
|
|
@@ -458,9 +500,14 @@ export class DateInput extends Observable {
|
|
|
458
500
|
if (this.triggerKeyDown({ event: e })) {
|
|
459
501
|
return;
|
|
460
502
|
}
|
|
503
|
+
const { start, end } = this.selection;
|
|
461
504
|
this.keyDownEvent = e;
|
|
462
505
|
this.previousElementValue = this.element.value;
|
|
463
|
-
|
|
506
|
+
this.formatStateOnKeyDown = {
|
|
507
|
+
format: this.currentFormat,
|
|
508
|
+
selectionStart: start,
|
|
509
|
+
selectionEnd: end
|
|
510
|
+
};
|
|
464
511
|
this.previousElementSelection = { start, end };
|
|
465
512
|
const autoSwitchKeys = (this.options.autoSwitchKeys || [])
|
|
466
513
|
.map(x => x.toString().toLowerCase().trim());
|
|
@@ -714,11 +761,13 @@ export class DateInput extends Observable {
|
|
|
714
761
|
return;
|
|
715
762
|
}
|
|
716
763
|
}
|
|
764
|
+
this.interactionMode = DateInputInteractionMode.None;
|
|
717
765
|
let { start: selectionStart, end: selectionEnd } = this.selection;
|
|
718
766
|
if (selectionStart < selectionEnd &&
|
|
719
767
|
this.currentFormat[selectionStart] !== this.currentFormat[selectionEnd - 1]) {
|
|
720
768
|
this.setSelection(this.selectionByIndex(offset > 0 ? selectionStart : selectionEnd - 1));
|
|
721
769
|
this.resetSegmentValue = true;
|
|
770
|
+
this.interactionMode = DateInputInteractionMode.None;
|
|
722
771
|
return;
|
|
723
772
|
}
|
|
724
773
|
const previousFormatSymbol = this.currentFormat[selectionStart];
|
|
@@ -749,6 +798,7 @@ export class DateInput extends Observable {
|
|
|
749
798
|
this.setSelection({ start: a, end: b });
|
|
750
799
|
this.resetSegmentValue = true;
|
|
751
800
|
}
|
|
801
|
+
this.interactionMode = DateInputInteractionMode.None;
|
|
752
802
|
}
|
|
753
803
|
modifyDateSegmentValue(offset, symbol = "", event = {}) {
|
|
754
804
|
if (!this.dateObject) {
|
|
@@ -937,13 +987,14 @@ export class DateInput extends Observable {
|
|
|
937
987
|
const { text: currentText, format: currentFormat } = this.dateObject.getTextAndFormat(format);
|
|
938
988
|
this.currentFormat = currentFormat;
|
|
939
989
|
this.currentText = currentText;
|
|
990
|
+
const hasPlaceholder = this.options.hasPlaceholder || isPresent(this.options.placeholder);
|
|
940
991
|
const showPlaceholder = !this.isActive &&
|
|
941
|
-
|
|
992
|
+
hasPlaceholder &&
|
|
942
993
|
!this.dateObject.hasValue();
|
|
943
|
-
if (isPresent(this.options.placeholder)) {
|
|
994
|
+
if (hasPlaceholder && isPresent(this.options.placeholder)) {
|
|
944
995
|
element.placeholder = this.options.placeholder;
|
|
945
996
|
}
|
|
946
|
-
const newElementValue =
|
|
997
|
+
const newElementValue = showPlaceholder ? "" : currentText;
|
|
947
998
|
this.previousElementValue = this.elementValue;
|
|
948
999
|
this.setElementValue(newElementValue);
|
|
949
1000
|
if (this.isActive && !this.options.allowCaretMode && this.options.selectNearestSegmentOnFocus) {
|