@@ -570,11 +570,23 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
570
570
public validate ( control : AbstractControl ) : ValidationErrors | null {
571
571
const value : DateRange = control . value ;
572
572
if ( value ) {
573
+ // TODO (in issue #7477)
574
+ // Accumulate all errors and return them as one object.
575
+ if ( this . hasProjectedInputs ) {
576
+ const startInput = this . projectedInputs . find ( i => i instanceof IgxDateRangeStartComponent ) as IgxDateRangeStartComponent ;
577
+ const endInput = this . projectedInputs . find ( i => i instanceof IgxDateRangeEndComponent ) as IgxDateRangeEndComponent ;
578
+ if ( ! startInput . dateTimeEditor . value ) {
579
+ return { 'startValue' : true } ;
580
+ }
581
+ if ( ! endInput . dateTimeEditor . value ) {
582
+ return { 'endValue' : true } ;
583
+ }
584
+ }
585
+
573
586
const min = DatePickerUtil . parseDate ( this . minValue ) ;
574
587
const max = DatePickerUtil . parseDate ( this . maxValue ) ;
575
588
const start = DatePickerUtil . parseDate ( value . start ) ;
576
589
const end = DatePickerUtil . parseDate ( value . end ) ;
577
-
578
590
if ( min && start && DatePickerUtil . lessThanMinValue ( start , min , false ) ) {
579
591
return { 'minValue' : true } ;
580
592
}
@@ -589,7 +601,6 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
589
601
}
590
602
}
591
603
592
- // TODO: fix what happens on blur and ensure on blur the value is either null or with both start and end filled
593
604
return null ;
594
605
}
595
606
@@ -676,15 +687,12 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
676
687
677
688
/** @hidden @internal */
678
689
public handleClosing ( event : CancelableBrowserEventArgs & IBaseEventArgs ) : void {
679
- this . onClosing . emit ( event ) ;
680
-
681
- if ( this . value && this . value . start && ! this . value . end ) {
682
- this . value = { start : this . value . start , end : this . value . start } ;
683
- }
684
690
if ( this . value && ! this . value . start && ! this . value . end ) {
685
691
this . value = null ;
686
692
}
687
693
694
+ this . onClosing . emit ( event ) ;
695
+
688
696
if ( this . mode === InteractionMode . DropDown && event . event && ! this . element . nativeElement . contains ( event . event . target ) ) {
689
697
// outside click
690
698
this . updateValidityOnBlur ( ) ;
@@ -790,46 +798,77 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
790
798
} ) ;
791
799
}
792
800
793
- private updateCalendar ( ) : void {
794
- this . calendar . disabledDates = [ ] ;
795
- let minValue : Date = DatePickerUtil . parseDate ( this . minValue ) ;
801
+ private parseMinValue ( value : string | Date ) : Date | null {
802
+ let minValue : Date = DatePickerUtil . parseDate ( value ) ;
796
803
if ( ! minValue && this . hasProjectedInputs ) {
797
804
const start = this . projectedInputs . filter ( i => i instanceof IgxDateRangeStartComponent ) [ 0 ] ;
798
805
if ( start ) {
799
806
minValue = DatePickerUtil . parseDate ( start . dateTimeEditor . minValue ) ;
800
807
}
801
808
}
802
- if ( minValue ) {
803
- this . calendar . disabledDates . push ( { type : DateRangeType . Before , dateRange : [ minValue ] } ) ;
804
- }
805
809
806
- let maxValue : Date = DatePickerUtil . parseDate ( this . maxValue ) ;
807
- if ( ! maxValue && this . hasProjectedInputs ) {
810
+ return minValue ;
811
+ }
812
+
813
+ private parseMaxValue ( value : string | Date ) : Date | null {
814
+ let maxValue : Date = DatePickerUtil . parseDate ( value ) ;
815
+ if ( ! maxValue && this . projectedInputs ) {
808
816
const end = this . projectedInputs . filter ( i => i instanceof IgxDateRangeEndComponent ) [ 0 ] ;
809
817
if ( end ) {
810
818
maxValue = DatePickerUtil . parseDate ( end . dateTimeEditor . maxValue ) ;
811
819
}
812
820
}
821
+
822
+ return maxValue ;
823
+ }
824
+
825
+ private updateCalendar ( ) : void {
826
+ this . calendar . disabledDates = [ ] ;
827
+ const minValue = this . parseMinValue ( this . minValue ) ;
828
+ if ( minValue ) {
829
+ this . calendar . disabledDates . push ( { type : DateRangeType . Before , dateRange : [ minValue ] } ) ;
830
+ }
831
+ const maxValue = this . parseMaxValue ( this . maxValue ) ;
813
832
if ( maxValue ) {
814
833
this . calendar . disabledDates . push ( { type : DateRangeType . After , dateRange : [ maxValue ] } ) ;
815
834
}
816
835
817
836
const range : Date [ ] = [ ] ;
818
- if ( this . value ) {
819
- if ( this . value . start ) {
820
- range . push ( this . value . start ) ;
837
+ if ( this . value ?. start && this . value ?. end ) {
838
+ if ( DatePickerUtil . greaterThanMaxValue ( this . value . start , this . value . end ) ) {
839
+ this . swapEditorDates ( ) ;
821
840
}
822
- if ( this . value . end ) {
823
- range . push ( this . value . end ) ;
841
+ if ( this . valueInRange ( this . value , minValue , maxValue ) ) {
842
+ range . push ( this . value . start , this . value . end ) ;
824
843
}
825
844
}
826
845
827
846
if ( range . length > 0 ) {
828
847
this . calendar . selectDate ( range ) ;
829
- this . calendar . viewDate = range [ 0 ] ;
830
848
} else {
831
849
this . calendar . deselectDate ( ) ;
832
850
}
851
+ this . calendar . viewDate = range [ 0 ] || new Date ( ) ;
852
+ }
853
+
854
+ private swapEditorDates ( ) : void {
855
+ if ( this . hasProjectedInputs ) {
856
+ const start = this . projectedInputs . find ( i => i instanceof IgxDateRangeStartComponent ) as IgxDateRangeStartComponent ;
857
+ const end = this . projectedInputs . find ( i => i instanceof IgxDateRangeEndComponent ) as IgxDateRangeEndComponent ;
858
+ [ start . dateTimeEditor . value , end . dateTimeEditor . value ] = [ end . dateTimeEditor . value , start . dateTimeEditor . value ] ;
859
+ [ this . value . start , this . value . end ] = [ this . value . end , this . value . start ] ;
860
+ }
861
+ }
862
+
863
+ private valueInRange ( value : DateRange , minValue ?: Date , maxValue ?: Date ) : boolean {
864
+ if ( minValue && DatePickerUtil . lessThanMinValue ( value . start , minValue , false ) ) {
865
+ return false ;
866
+ }
867
+ if ( maxValue && DatePickerUtil . greaterThanMaxValue ( value . end , maxValue , false ) ) {
868
+ return false ;
869
+ }
870
+
871
+ return true ;
833
872
}
834
873
835
874
private extractRange ( selection : Date [ ] ) : DateRange {
@@ -858,7 +897,6 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
858
897
} else {
859
898
this . value = { start : value , end : null } ;
860
899
}
861
- // TODO: should we check start and reset end value
862
900
} ) ;
863
901
end . dateTimeEditor . valueChange
864
902
. pipe ( takeUntil ( this . $destroy ) )
@@ -882,11 +920,6 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
882
920
if ( this . collapsed ) {
883
921
this . updateValidityOnBlur ( ) ;
884
922
}
885
- if ( this . value && ! this . value . start ) {
886
- this . value = null ;
887
- }
888
- // TODO: if we have start and have no end should we fill end
889
- // as we do on calendar close
890
923
} ) ;
891
924
} ) ;
892
925
} else {
@@ -942,9 +975,9 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
942
975
private updateInputs ( ) : void {
943
976
const start = this . projectedInputs ?. find ( i => i instanceof IgxDateRangeStartComponent ) as IgxDateRangeStartComponent ;
944
977
const end = this . projectedInputs ?. find ( i => i instanceof IgxDateRangeEndComponent ) as IgxDateRangeEndComponent ;
945
- if ( start && end && this . value ) {
946
- start . updateInputValue ( this . value . start ) ;
947
- end . updateInputValue ( this . value . end ) ;
978
+ if ( start && end ) {
979
+ start . updateInputValue ( this . value ? .start ?? null ) ;
980
+ end . updateInputValue ( this . value ? .end ?? null ) ;
948
981
}
949
982
}
950
983
}
0 commit comments