@@ -570,11 +570,23 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
570570 public validate ( control : AbstractControl ) : ValidationErrors | null {
571571 const value : DateRange = control . value ;
572572 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+
573586 const min = DatePickerUtil . parseDate ( this . minValue ) ;
574587 const max = DatePickerUtil . parseDate ( this . maxValue ) ;
575588 const start = DatePickerUtil . parseDate ( value . start ) ;
576589 const end = DatePickerUtil . parseDate ( value . end ) ;
577-
578590 if ( min && start && DatePickerUtil . lessThanMinValue ( start , min , false ) ) {
579591 return { 'minValue' : true } ;
580592 }
@@ -589,7 +601,6 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
589601 }
590602 }
591603
592- // TODO: fix what happens on blur and ensure on blur the value is either null or with both start and end filled
593604 return null ;
594605 }
595606
@@ -676,15 +687,12 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
676687
677688 /** @hidden @internal */
678689 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- }
684690 if ( this . value && ! this . value . start && ! this . value . end ) {
685691 this . value = null ;
686692 }
687693
694+ this . onClosing . emit ( event ) ;
695+
688696 if ( this . mode === InteractionMode . DropDown && event . event && ! this . element . nativeElement . contains ( event . event . target ) ) {
689697 // outside click
690698 this . updateValidityOnBlur ( ) ;
@@ -790,46 +798,77 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
790798 } ) ;
791799 }
792800
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 ) ;
796803 if ( ! minValue && this . hasProjectedInputs ) {
797804 const start = this . projectedInputs . filter ( i => i instanceof IgxDateRangeStartComponent ) [ 0 ] ;
798805 if ( start ) {
799806 minValue = DatePickerUtil . parseDate ( start . dateTimeEditor . minValue ) ;
800807 }
801808 }
802- if ( minValue ) {
803- this . calendar . disabledDates . push ( { type : DateRangeType . Before , dateRange : [ minValue ] } ) ;
804- }
805809
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 ) {
808816 const end = this . projectedInputs . filter ( i => i instanceof IgxDateRangeEndComponent ) [ 0 ] ;
809817 if ( end ) {
810818 maxValue = DatePickerUtil . parseDate ( end . dateTimeEditor . maxValue ) ;
811819 }
812820 }
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 ) ;
813832 if ( maxValue ) {
814833 this . calendar . disabledDates . push ( { type : DateRangeType . After , dateRange : [ maxValue ] } ) ;
815834 }
816835
817836 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 ( ) ;
821840 }
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 ) ;
824843 }
825844 }
826845
827846 if ( range . length > 0 ) {
828847 this . calendar . selectDate ( range ) ;
829- this . calendar . viewDate = range [ 0 ] ;
830848 } else {
831849 this . calendar . deselectDate ( ) ;
832850 }
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 ;
833872 }
834873
835874 private extractRange ( selection : Date [ ] ) : DateRange {
@@ -858,7 +897,6 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
858897 } else {
859898 this . value = { start : value , end : null } ;
860899 }
861- // TODO: should we check start and reset end value
862900 } ) ;
863901 end . dateTimeEditor . valueChange
864902 . pipe ( takeUntil ( this . $destroy ) )
@@ -882,11 +920,6 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
882920 if ( this . collapsed ) {
883921 this . updateValidityOnBlur ( ) ;
884922 }
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
890923 } ) ;
891924 } ) ;
892925 } else {
@@ -942,9 +975,9 @@ export class IgxDateRangePickerComponent extends DisplayDensityBase
942975 private updateInputs ( ) : void {
943976 const start = this . projectedInputs ?. find ( i => i instanceof IgxDateRangeStartComponent ) as IgxDateRangeStartComponent ;
944977 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 ) ;
948981 }
949982 }
950983}
0 commit comments