@progress/kendo-dateinputs-common 0.2.0-dev.202301161405 → 0.2.0-dev.202301231327
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 +207 -73
- package/dist/es/dateinput/dateinput.js +58 -7
- package/dist/es2015/common/dateobject.js +208 -74
- package/dist/es2015/dateinput/dateinput.js +59 -8
- package/dist/npm/common/dateobject.d.ts +4 -0
- package/dist/npm/common/dateobject.js +207 -73
- 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 === "");
|
|
@@ -787,13 +805,10 @@ export class DateObject {
|
|
|
787
805
|
if ((isInCaretMode && isValidDate(parsedDate)) || (!isInCaretMode && parsedDate)) {
|
|
788
806
|
// move to next segment if the part will overflow with next char
|
|
789
807
|
// when start from empty date (01, then 010), padded zeros should be trimmed
|
|
790
|
-
const
|
|
791
|
-
const
|
|
792
|
-
const
|
|
793
|
-
|
|
794
|
-
let switchToNext = peekDate === null ||
|
|
795
|
-
(leadingZero[symbol] && patternValue.length <= middle.length) ||
|
|
796
|
-
patternSatisfied;
|
|
808
|
+
const peekValue = this.peek(middle, patternValue);
|
|
809
|
+
const peekDateString = `${prefix}${peekValue}${suffix}`;
|
|
810
|
+
const peekDate = this.intl.parseDate(peekDateString, this.format, this.localeId);
|
|
811
|
+
let switchToNext = peekDate === null || (leadingZero[symbol] && patternValue.length <= middle.length) || false;
|
|
797
812
|
if (this.shouldNormalizeCentury()) {
|
|
798
813
|
parsedDate = this.normalizeCentury(parsedDate);
|
|
799
814
|
}
|
|
@@ -821,14 +836,12 @@ export class DateObject {
|
|
|
821
836
|
}
|
|
822
837
|
if (isInCaretMode && switchToNext) {
|
|
823
838
|
if (symbol === "M") {
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
switchToNext = false;
|
|
831
|
-
}
|
|
839
|
+
const datePartValue = parseToInt(datePartText);
|
|
840
|
+
if (datePartValue >= 2 || datePartText.length >= 2) {
|
|
841
|
+
switchToNext = true;
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
switchToNext = false;
|
|
832
845
|
}
|
|
833
846
|
}
|
|
834
847
|
else {
|
|
@@ -861,9 +874,6 @@ export class DateObject {
|
|
|
861
874
|
this.leadingZero = !this.isAbbrMonth(dateParts.partMap, symbol) ? { [symbol]: true } : null;
|
|
862
875
|
this.setExisting(symbol, false);
|
|
863
876
|
}
|
|
864
|
-
if (isInCaretMode && datePartText.length > segmentLength) {
|
|
865
|
-
return extend(parseResult, { value: null, switchToNext: false });
|
|
866
|
-
}
|
|
867
877
|
if (!this.autoCorrectParts) {
|
|
868
878
|
let datePartValue;
|
|
869
879
|
const textToParse = isInCaretMode ? datePartText : middle;
|
|
@@ -874,20 +884,146 @@ export class DateObject {
|
|
|
874
884
|
return extend(parseResult, { value: null, switchToNext: false });
|
|
875
885
|
}
|
|
876
886
|
datePartValue = symbol === "M" ?
|
|
877
|
-
|
|
887
|
+
parsedValue - JS_MONTH_OFFSET :
|
|
878
888
|
parsedValue;
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
this.
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
889
|
+
const isMonth = symbol === "M";
|
|
890
|
+
const isDay = symbol === "d";
|
|
891
|
+
let newValue = cloneDate(this._value);
|
|
892
|
+
const invalidDateParts = this._partiallyInvalidDate.invalidDateParts || {};
|
|
893
|
+
let year = invalidDateParts.y.value || newValue.getFullYear();
|
|
894
|
+
/* tslint:disable:no-shadowed-variable */
|
|
895
|
+
let month = isMonth ? datePartValue : invalidDateParts.M.value || newValue.getMonth();
|
|
896
|
+
/* tslint:enable:no-shadowed-variable */
|
|
897
|
+
let day = isDay ? datePartValue : invalidDateParts.d.value || invalidDateParts.E.value || newValue.getDate();
|
|
898
|
+
let hour = invalidDateParts.h.value || invalidDateParts.H.value || newValue.getHours();
|
|
899
|
+
let minutes = invalidDateParts.m.value || newValue.getMinutes();
|
|
900
|
+
let seconds = invalidDateParts.s.value || newValue.getSeconds();
|
|
901
|
+
let milliseconds = invalidDateParts.S.value || newValue.getMilliseconds();
|
|
902
|
+
const dateCandidate = createDate(year, month, day, hour, minutes, seconds, milliseconds);
|
|
903
|
+
const dateCandidateExists = areDatePartsEqualTo(dateCandidate, year, month, day, hour, minutes, seconds, milliseconds);
|
|
904
|
+
const newValueCandidate = isMonth || isDay ?
|
|
905
|
+
this.modifyDateSymbolWithValue(newValue, symbol, isMonth ? month : day) :
|
|
906
|
+
null;
|
|
907
|
+
let invalidDateFound = false;
|
|
908
|
+
if (isMonth && newValueCandidate) {
|
|
909
|
+
if (newValueCandidate.getMonth() === month) {
|
|
910
|
+
if (this.getExisting("d")) {
|
|
911
|
+
if (dateCandidateExists) {
|
|
912
|
+
newValue = cloneDate(dateCandidate);
|
|
913
|
+
this.resetInvalidDateSymbol(symbol);
|
|
914
|
+
}
|
|
915
|
+
else {
|
|
916
|
+
invalidDateFound = true;
|
|
917
|
+
this.setInvalidDatePart(symbol, {
|
|
918
|
+
value: month,
|
|
919
|
+
date: cloneDate(newValueCandidate),
|
|
920
|
+
// startDateOffset: offset,
|
|
921
|
+
startDate: cloneDate(this.value)
|
|
922
|
+
});
|
|
923
|
+
this.setExisting(symbol, false);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
else if (dateCandidateExists) {
|
|
927
|
+
this.resetInvalidDateSymbol(symbol);
|
|
928
|
+
newValue = cloneDate(dateCandidate);
|
|
929
|
+
if (this.getExisting("M") && this.getExisting("y")) {
|
|
930
|
+
// changing from 28/Feb to 29/Feb to 29/March
|
|
931
|
+
this.setExisting("d", true);
|
|
932
|
+
this.resetInvalidDateSymbol("d");
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
else {
|
|
936
|
+
this.resetInvalidDateSymbol(symbol);
|
|
937
|
+
newValue = cloneDate(newValueCandidate);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
else {
|
|
941
|
+
invalidDateFound = true;
|
|
942
|
+
this.setInvalidDatePart(symbol, {
|
|
943
|
+
value: month,
|
|
944
|
+
date: cloneDate(newValueCandidate),
|
|
945
|
+
// startDateOffset: offset,
|
|
946
|
+
startDate: cloneDate(this.value)
|
|
947
|
+
});
|
|
948
|
+
this.setExisting(symbol, false);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
else if (isDay && newValueCandidate) {
|
|
952
|
+
if (newValueCandidate.getDate() === day) {
|
|
953
|
+
if (this.getExisting("M")) {
|
|
954
|
+
if (dateCandidateExists) {
|
|
955
|
+
newValue = cloneDate(dateCandidate);
|
|
956
|
+
this.resetInvalidDateSymbol(symbol);
|
|
957
|
+
}
|
|
958
|
+
else {
|
|
959
|
+
invalidDateFound = true;
|
|
960
|
+
this.setInvalidDatePart(symbol, {
|
|
961
|
+
value: day,
|
|
962
|
+
date: cloneDate(newValueCandidate),
|
|
963
|
+
// startDateOffset: offset,
|
|
964
|
+
startDate: cloneDate(this.value)
|
|
965
|
+
});
|
|
966
|
+
this.setExisting(symbol, false);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
else if (dateCandidateExists) {
|
|
970
|
+
newValue = cloneDate(dateCandidate);
|
|
971
|
+
this.resetInvalidDateSymbol(symbol);
|
|
972
|
+
if (this.getExisting("d") && this.getExisting("y")) {
|
|
973
|
+
// changing from 31/Jan to 31/Feb to 28/Feb
|
|
974
|
+
this.setExisting("M", true);
|
|
975
|
+
this.resetInvalidDateSymbol("M");
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
else {
|
|
979
|
+
this.resetInvalidDateSymbol(symbol);
|
|
980
|
+
newValue = cloneDate(newValueCandidate);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
else {
|
|
984
|
+
invalidDateFound = true;
|
|
985
|
+
this.setInvalidDatePart(symbol, {
|
|
986
|
+
value: day,
|
|
987
|
+
date: cloneDate(this.value),
|
|
988
|
+
// startDateOffset: offset,
|
|
989
|
+
startDate: cloneDate(this.value)
|
|
990
|
+
});
|
|
991
|
+
this.setExisting(symbol, false);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
if (!invalidDateFound) {
|
|
995
|
+
this.setExisting(symbol, true);
|
|
996
|
+
if (isInCaretMode && !isValidDate(parsedDate)) {
|
|
997
|
+
const valueCandidate = this.intl.parseDate(basePrefix + middle + baseSuffix, this.format, this.localeId);
|
|
998
|
+
if (isValidDate(valueCandidate)) {
|
|
999
|
+
this._value = valueCandidate;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
else {
|
|
1003
|
+
this._value = newValue;
|
|
1004
|
+
}
|
|
1005
|
+
if (this.getValue()) {
|
|
1006
|
+
this.resetInvalidDate();
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
let switchToNext = false;
|
|
1010
|
+
if (symbol === "M") {
|
|
1011
|
+
if (parsedValue >= 2 || textToParse.length >= 2) {
|
|
1012
|
+
switchToNext = true;
|
|
1013
|
+
}
|
|
1014
|
+
else {
|
|
1015
|
+
switchToNext = false;
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
else {
|
|
1019
|
+
switchToNext = hasFixedFormat ?
|
|
1020
|
+
textToParse.length === segmentLength :
|
|
1021
|
+
textToParse.length > segmentLength;
|
|
1022
|
+
}
|
|
887
1023
|
return extend(parseResult, {
|
|
888
1024
|
value: null,
|
|
889
|
-
switchToNext:
|
|
890
|
-
hasInvalidDatePart:
|
|
1025
|
+
switchToNext: switchToNext,
|
|
1026
|
+
hasInvalidDatePart: invalidDateFound
|
|
891
1027
|
});
|
|
892
1028
|
}
|
|
893
1029
|
}
|
|
@@ -910,6 +1046,12 @@ export class DateObject {
|
|
|
910
1046
|
setLeadingZero(leadingZero) {
|
|
911
1047
|
this.leadingZero = leadingZero;
|
|
912
1048
|
}
|
|
1049
|
+
/**
|
|
1050
|
+
* @hidden
|
|
1051
|
+
*/
|
|
1052
|
+
getLeadingZero() {
|
|
1053
|
+
return this.leadingZero || {};
|
|
1054
|
+
}
|
|
913
1055
|
/**
|
|
914
1056
|
* @hidden
|
|
915
1057
|
*/
|
|
@@ -992,7 +1134,6 @@ export class DateObject {
|
|
|
992
1134
|
const dateFormatParts = this.intl.splitDateFormat(this.format, this.localeId);
|
|
993
1135
|
for (let i = 0; i < dateFormatParts.length; i++) {
|
|
994
1136
|
if (dateFormatParts[i].type === 'month' && dateFormatParts[i].names) {
|
|
995
|
-
// return this.intl.dateFormatNames(dateFormatParts[i].names);
|
|
996
1137
|
return this.intl.dateFormatNames(locale, dateFormatParts[i].names);
|
|
997
1138
|
}
|
|
998
1139
|
}
|
|
@@ -1200,15 +1341,8 @@ export class DateObject {
|
|
|
1200
1341
|
return (invalidDatePart || {}).value;
|
|
1201
1342
|
}
|
|
1202
1343
|
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
1344
|
if (this._partiallyInvalidDate.invalidDateParts[symbol]) {
|
|
1211
|
-
this._partiallyInvalidDate.invalidDateParts[symbol].value =
|
|
1345
|
+
this._partiallyInvalidDate.invalidDateParts[symbol].value = value;
|
|
1212
1346
|
this._partiallyInvalidDate.invalidDateParts[symbol].date = date;
|
|
1213
1347
|
this._partiallyInvalidDate.invalidDateParts[symbol].startDateOffset = startDateOffset;
|
|
1214
1348
|
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) {
|