diff --git a/apps/ngx-bootstrap-docs/src/app/components/+datepicker/datepicker-section.list.ts b/apps/ngx-bootstrap-docs/src/app/components/+datepicker/datepicker-section.list.ts index 65b30e56de..3a59868e76 100644 --- a/apps/ngx-bootstrap-docs/src/app/components/+datepicker/datepicker-section.list.ts +++ b/apps/ngx-bootstrap-docs/src/app/components/+datepicker/datepicker-section.list.ts @@ -448,7 +448,8 @@ export const demoComponentContent: ContentSection[] = [ anchor: 'daterangepicker-max-date-range', component: require('!!raw-loader!./demos/max-date-range/max-date-range.ts'), html: require('!!raw-loader!./demos/max-date-range/max-date-range.html'), - description: `

Max date range after first date selection can be added to Daterangepicker using maxDateRange

`, + description: `

Max date range after first date selection can be added to Daterangepicker using maxDateRange.

+

If you also use maxDate property, you can't select second date, which exceeds value of maxDate.

`, outlet: DemoDateRangePickerMaxDateRangeComponent } ] diff --git a/apps/ngx-bootstrap-docs/src/app/components/+datepicker/demos/max-date-range/max-date-range.html b/apps/ngx-bootstrap-docs/src/app/components/+datepicker/demos/max-date-range/max-date-range.html index cc6505f300..7cbe467b9f 100644 --- a/apps/ngx-bootstrap-docs/src/app/components/+datepicker/demos/max-date-range/max-date-range.html +++ b/apps/ngx-bootstrap-docs/src/app/components/+datepicker/demos/max-date-range/max-date-range.html @@ -4,6 +4,7 @@ placeholder="Daterangepicker" class="form-control" bsDaterangepicker - [bsConfig]="{ maxDateRange: 20 }"> + [maxDate]="maxDate" + [bsConfig]="{ maxDateRange: 25 }"> diff --git a/apps/ngx-bootstrap-docs/src/app/components/+datepicker/demos/max-date-range/max-date-range.ts b/apps/ngx-bootstrap-docs/src/app/components/+datepicker/demos/max-date-range/max-date-range.ts index 89bc8e39c3..a0ab887780 100644 --- a/apps/ngx-bootstrap-docs/src/app/components/+datepicker/demos/max-date-range/max-date-range.ts +++ b/apps/ngx-bootstrap-docs/src/app/components/+datepicker/demos/max-date-range/max-date-range.ts @@ -5,4 +5,10 @@ import {Component} from '@angular/core'; templateUrl: './max-date-range.html' }) export class DemoDateRangePickerMaxDateRangeComponent { + maxDate: Date; + + constructor() { + this.maxDate = new Date(); + this.maxDate.setDate(this.maxDate.getDate() + 30); +} } diff --git a/src/datepicker/reducer/_defaults.ts b/src/datepicker/reducer/_defaults.ts index 35034e3b8f..795dd76e77 100644 --- a/src/datepicker/reducer/_defaults.ts +++ b/src/datepicker/reducer/_defaults.ts @@ -6,3 +6,5 @@ export const defaultMonthOptions: MonthViewOptions = { width: 7, height: 6 }; + +export const dayInMilliseconds = 24 * 60 * 60 * 1000; diff --git a/src/datepicker/testing/bs-daterangepicker.spec.ts b/src/datepicker/testing/bs-daterangepicker.spec.ts index 81d6527203..03aa3b572a 100644 --- a/src/datepicker/testing/bs-daterangepicker.spec.ts +++ b/src/datepicker/testing/bs-daterangepicker.spec.ts @@ -7,6 +7,9 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { By } from '@angular/platform-browser'; import { BsCustomDates } from '../themes/bs/bs-custom-dates-view.component'; +import { take } from 'rxjs/operators'; +import { getYearsCalendarInitialDate } from '../utils/bs-calendar-utils'; +import { initialYearShift } from '../engine/format-years-calendar'; @Component({ @@ -212,4 +215,47 @@ describe('daterangepicker:', () => { expect(activeRangeButton.length).toEqual(1); expect(activeRangeButton[0].innerHTML.trim()).toEqual(customRangeBtnLbl); }); + + it('should not allow to select date behind max value', () => { + const datepicker = showDatepicker(fixture); + datepicker.bsConfig.maxDate = new Date(); + datepicker.bsConfig.maxDateRange = 10; + + const datepickerContainerInstance = getDaterangepickerContainer(datepicker); + + const correctDateStart = new Date(new Date().setDate(new Date().getDate() - 14)) + const correctDateEnd = new Date(new Date().setDate(new Date().getDate() - 7)) + const selectedRange: BsCustomDates = { + label: '', + value: [correctDateStart, correctDateEnd] + }; + + datepickerContainerInstance.setMaxDateRangeOnCalendar(correctDateStart); + datepickerContainerInstance.setRangeOnCalendar(selectedRange); + fixture.detectChanges(); + + datepickerContainerInstance[`_store`] + .select(state => state) + .subscribe(view => { + expect(view.maxDate).toEqual(correctDateEnd) + }); + + const incorrectCaseStart = new Date(new Date().setDate(new Date().getDate() - 5)) + const incorrectCaseEnd = new Date(new Date().setDate(new Date().getDate() + 15)) + const selectedRange1: BsCustomDates = { + label: '', + value: [incorrectCaseStart, incorrectCaseEnd] + }; + + datepickerContainerInstance.setMaxDateRangeOnCalendar(incorrectCaseStart); + datepickerContainerInstance.setRangeOnCalendar(selectedRange1); + fixture.detectChanges(); + + datepickerContainerInstance[`_store`] + .select(state => state) + .subscribe(view => { + expect(view.maxDate).not.toEqual(incorrectCaseEnd) + }); + }); + }); diff --git a/src/datepicker/themes/bs/bs-daterangepicker-container.component.ts b/src/datepicker/themes/bs/bs-daterangepicker-container.component.ts index 680aad93b5..afb3a888eb 100644 --- a/src/datepicker/themes/bs/bs-daterangepicker-container.component.ts +++ b/src/datepicker/themes/bs/bs-daterangepicker-container.component.ts @@ -14,6 +14,7 @@ import { BsDatepickerEffects } from '../../reducer/bs-datepicker.effects'; import { BsDatepickerStore } from '../../reducer/bs-datepicker.store'; import { datepickerAnimation } from '../../datepicker-animations'; import { BsCustomDates } from './bs-custom-dates-view.component'; +import { dayInMilliseconds } from '../../reducer/_defaults'; @Component({ selector: 'bs-daterangepicker-container', @@ -186,6 +187,10 @@ export class BsDaterangepickerContainerComponent extends BsDatepickerAbstractCom : [day.date]; } + if (this._config.maxDateRange) { + this.setMaxDateRangeOnCalendar(day.date); + } + if (this._rangeStack.length === 0) { this._rangeStack = [day.date]; @@ -214,9 +219,18 @@ export class BsDaterangepickerContainerComponent extends BsDatepickerAbstractCom } setMaxDateRangeOnCalendar(currentSelection: Date): void { - const maxDateRange = new Date(currentSelection); - maxDateRange.setDate(currentSelection.getDate() + (this._config.maxDateRange || 0)); + let maxDateRange = new Date(currentSelection); + + if (this._config.maxDate) { + const maxDateValueInMilliseconds = this._config.maxDate.getTime(); + const maxDateRangeInMilliseconds = currentSelection.getTime() + ((this._config.maxDateRange || 0) * dayInMilliseconds ); + maxDateRange = maxDateRangeInMilliseconds > maxDateValueInMilliseconds ? + new Date(this._config.maxDate) : + new Date(maxDateRangeInMilliseconds); + } else { + maxDateRange.setDate(currentSelection.getDate() + (this._config.maxDateRange || 0)); + } + this._effects?.setMaxDate(maxDateRange); } - }