diff --git a/demo/src/app/components/+datepicker/datepicker-section.list.ts b/demo/src/app/components/+datepicker/datepicker-section.list.ts
index ed8771a8f1..417b68bdb5 100644
--- a/demo/src/app/components/+datepicker/datepicker-section.list.ts
+++ b/demo/src/app/components/+datepicker/datepicker-section.list.ts
@@ -10,6 +10,7 @@ import { DemoDatePickerConfigObjectComponent } from './demos/config-object/confi
import { DemoDatePickerCustomFormatComponent } from './demos/custom-format/custom-format';
import { DemoDatepickerDateInitialStateComponent } from './demos/date-initial-state/date-initial-state';
import { DemoDatepickerDatesDisabledComponent } from './demos/disable-dates/disable-dates';
+import { DemoDatepickerDatesEnabledComponent } from './demos/enable-dates/enable-dates';
import { DemoDatepickerDaysDisabledComponent } from './demos/disable-days/disable-days';
import { DemoDatepickerDisabledComponent } from './demos/disabled/disabled.component';
import { DemoDatepickerFormsComponent } from './demos/forms/forms.component';
@@ -205,9 +206,21 @@ export const demoComponentContent: ContentSection[] = [
html: require('!!raw-loader!./demos/disable-dates/disable-dates.html'),
description: `
You can set which dates should be disabled with datesDisabled
- In the following example datesDisabled
is set with an array to disable 2019-02-05 and 2019-02-09.
`,
+ In the following example datesDisabled
is set with an array to disable 2019-02-05 and 2019-02-09.
+ NOTE: DO NOT USE this functionality with datesEnabled
at the same time
`,
outlet: DemoDatepickerDatesDisabledComponent
},
+ {
+ title: 'Dates enabled',
+ anchor: 'dates-enabled',
+ component: require('!!raw-loader!./demos/enable-dates/enable-dates.ts'),
+ html: require('!!raw-loader!./demos/enable-dates/enable-dates.html'),
+ description: `
+ You can set which dates should be enable with datesEnabled
+ In the following example datesEnabled
is set with an array to enable 2020-02-06, 2020-02-08 and 2020-02-11. All other dates are disabled
+ NOTE: DO NOT USE this functionality with datesDisabled
at the same time
`,
+ outlet: DemoDatepickerDatesEnabledComponent
+ },
{
title: 'Min-mode',
anchor: 'min-mode',
diff --git a/demo/src/app/components/+datepicker/demos/enable-dates/enable-dates.html b/demo/src/app/components/+datepicker/demos/enable-dates/enable-dates.html
new file mode 100644
index 0000000000..5332c660ad
--- /dev/null
+++ b/demo/src/app/components/+datepicker/demos/enable-dates/enable-dates.html
@@ -0,0 +1,16 @@
+
diff --git a/demo/src/app/components/+datepicker/demos/enable-dates/enable-dates.ts b/demo/src/app/components/+datepicker/demos/enable-dates/enable-dates.ts
new file mode 100644
index 0000000000..0b2581b8f6
--- /dev/null
+++ b/demo/src/app/components/+datepicker/demos/enable-dates/enable-dates.ts
@@ -0,0 +1,13 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'demo-datepicker-datesenabled',
+ templateUrl: './enable-dates.html'
+})
+export class DemoDatepickerDatesEnabledComponent {
+ enabledDates = [
+ new Date('2020-02-06'),
+ new Date('2020-02-08'),
+ new Date('2020-02-11'),
+ ];
+}
diff --git a/demo/src/app/components/+datepicker/demos/index.ts b/demo/src/app/components/+datepicker/demos/index.ts
index 409f2a0658..3b401d09ed 100644
--- a/demo/src/app/components/+datepicker/demos/index.ts
+++ b/demo/src/app/components/+datepicker/demos/index.ts
@@ -10,6 +10,7 @@ import { DemoDatepickerCustomTodayClassComponent } from './custom-today-class/cu
import { DemoDatepickerDateInitialStateComponent } from './date-initial-state/date-initial-state';
import { DemoDatepickerDaysDisabledComponent } from './disable-days/disable-days';
import { DemoDatepickerDatesDisabledComponent } from './disable-dates/disable-dates';
+import { DemoDatepickerDatesEnabledComponent } from './enable-dates/enable-dates';
import { DemoDatepickerDisabledComponent } from './disabled/disabled.component';
import { DemoDatepickerFormsComponent } from './forms/forms.component';
import { DemoDatepickerHideOnScrollComponent } from './hide-on-scroll/hide-on-scroll';
@@ -52,6 +53,7 @@ export const DEMO_COMPONENTS = [
DemoDatepickerDateCustomClassesComponent,
DemoDatepickerDateInitialStateComponent,
DemoDatepickerDatesDisabledComponent,
+ DemoDatepickerDatesEnabledComponent,
DemoDatepickerDaysDisabledComponent,
DemoDatepickerDisabledComponent,
DemoDatepickerFormsComponent,
diff --git a/src/datepicker/base/bs-datepicker-container.ts b/src/datepicker/base/bs-datepicker-container.ts
index e0df4710ca..11667cad8c 100644
--- a/src/datepicker/base/bs-datepicker-container.ts
+++ b/src/datepicker/base/bs-datepicker-container.ts
@@ -38,6 +38,10 @@ export abstract class BsDatepickerAbstractComponent {
this._effects.setDatesDisabled(value);
}
+ set datesEnabled(value: Date[]) {
+ this._effects.setDatesEnabled(value);
+ }
+
set isDisabled(value: boolean) {
this._effects.setDisabled(value);
}
diff --git a/src/datepicker/bs-datepicker-inline.component.ts b/src/datepicker/bs-datepicker-inline.component.ts
index f0262f17f8..52f253ac54 100644
--- a/src/datepicker/bs-datepicker-inline.component.ts
+++ b/src/datepicker/bs-datepicker-inline.component.ts
@@ -53,6 +53,10 @@ export class BsDatepickerInlineDirective implements OnInit, OnDestroy, OnChanges
/**
* Disable specific dates
*/
+ @Input() datesEnabled: Date[];
+ /**
+ * Enable specific dates
+ */
@Input() datesDisabled: Date[];
/**
* Emits when datepicker value has been changed
@@ -124,6 +128,11 @@ export class BsDatepickerInlineDirective implements OnInit, OnDestroy, OnChanges
this._datepickerRef.instance.value = this._bsValue;
}
+ if (changes.datesEnabled) {
+ this._datepickerRef.instance.datesEnabled = this.datesEnabled;
+ this._datepickerRef.instance.value = this._bsValue;
+ }
+
if (changes.isDisabled) {
this._datepickerRef.instance.isDisabled = this.isDisabled;
}
@@ -143,7 +152,8 @@ export class BsDatepickerInlineDirective implements OnInit, OnDestroy, OnChanges
minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
- datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled
+ datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
+ datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled
});
if (this._datepickerRef !== undefined) {
diff --git a/src/datepicker/bs-datepicker.component.ts b/src/datepicker/bs-datepicker.component.ts
index 6dd2eb84eb..2ab7bade16 100644
--- a/src/datepicker/bs-datepicker.component.ts
+++ b/src/datepicker/bs-datepicker.component.ts
@@ -104,6 +104,10 @@ export class BsDatepickerDirective implements OnInit, OnDestroy, OnChanges {
* Disable specific dates
*/
@Input() datesDisabled: Date[];
+ /**
+ * Enable specific dates
+ */
+ @Input() datesEnabled: Date[];
/**
* Date custom classes
*/
@@ -165,6 +169,10 @@ export class BsDatepickerDirective implements OnInit, OnDestroy, OnChanges {
this._datepickerRef.instance.datesDisabled = this.datesDisabled;
}
+ if (changes.datesEnabled) {
+ this._datepickerRef.instance.datesEnabled = this.datesEnabled;
+ }
+
if (changes.isDisabled) {
this._datepickerRef.instance.isDisabled = this.isDisabled;
}
@@ -249,6 +257,7 @@ export class BsDatepickerDirective implements OnInit, OnDestroy, OnChanges {
daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
+ datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
minMode: this.minMode || this.bsConfig && this.bsConfig.minMode
});
}
diff --git a/src/datepicker/bs-datepicker.config.ts b/src/datepicker/bs-datepicker.config.ts
index 7e93d6f148..ef80030546 100644
--- a/src/datepicker/bs-datepicker.config.ts
+++ b/src/datepicker/bs-datepicker.config.ts
@@ -41,6 +41,10 @@ export class BsDatepickerConfig implements DatepickerRenderOptions {
* Disable specific dates
*/
datesDisabled?: Date[];
+ /**
+ * Enable specific dates
+ */
+ datesEnabled?: Date[];
/**
* Makes dates from other months active
*/
diff --git a/src/datepicker/bs-daterangepicker-inline.component.ts b/src/datepicker/bs-daterangepicker-inline.component.ts
index 7b6ab443b7..54b99d8f7b 100644
--- a/src/datepicker/bs-daterangepicker-inline.component.ts
+++ b/src/datepicker/bs-daterangepicker-inline.component.ts
@@ -59,6 +59,10 @@ export class BsDaterangepickerInlineDirective implements OnInit, OnDestroy, OnCh
* Disable specific dates
*/
@Input() datesDisabled: Date[];
+ /**
+ * Disable specific dates
+ */
+ @Input() datesEnabled: Date[];
/**
* Emits when daterangepicker value has been changed
*/
@@ -126,6 +130,10 @@ export class BsDaterangepickerInlineDirective implements OnInit, OnDestroy, OnCh
this._datepickerRef.instance.maxDate = this.maxDate;
}
+ if (changes.datesEnabled) {
+ this._datepickerRef.instance.datesEnabled = this.datesEnabled;
+ }
+
if (changes.datesDisabled) {
this._datepickerRef.instance.datesDisabled = this.datesDisabled;
}
@@ -155,6 +163,7 @@ export class BsDaterangepickerInlineDirective implements OnInit, OnDestroy, OnCh
daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
+ datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
ranges: this.bsConfig && this.bsConfig.ranges
});
}
diff --git a/src/datepicker/bs-daterangepicker.component.ts b/src/datepicker/bs-daterangepicker.component.ts
index c8dc45c850..1ea0fae434 100644
--- a/src/datepicker/bs-daterangepicker.component.ts
+++ b/src/datepicker/bs-daterangepicker.component.ts
@@ -115,6 +115,10 @@ export class BsDaterangepickerDirective
*/
@Input() datesDisabled: Date[];
+ /**
+ * Enable specific dates
+ */
+ @Input() datesEnabled: Date[];
/**
* Emits when daterangepicker value has been changed
*/
@@ -167,6 +171,10 @@ export class BsDaterangepickerDirective
this._datepickerRef.instance.datesDisabled = this.datesDisabled;
}
+ if (changes.datesEnabled) {
+ this._datepickerRef.instance.datesEnabled = this.datesEnabled;
+ }
+
if (changes.daysDisabled) {
this._datepickerRef.instance.daysDisabled = this.daysDisabled;
}
@@ -234,6 +242,7 @@ export class BsDaterangepickerDirective
daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
+ datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
ranges: this.bsConfig && this.bsConfig.ranges
}
);
diff --git a/src/datepicker/engine/flag-days-calendar.ts b/src/datepicker/engine/flag-days-calendar.ts
index 0c2d4865ae..7adbe888fb 100644
--- a/src/datepicker/engine/flag-days-calendar.ts
+++ b/src/datepicker/engine/flag-days-calendar.ts
@@ -14,7 +14,7 @@ import {
shiftDate
} from 'ngx-bootstrap/chronos';
-import { isMonthDisabled, isDisabledDate } from '../utils/bs-calendar-utils';
+import { isMonthDisabled, isDisabledDate, isEnabledDate } from '../utils/bs-calendar-utils';
export interface FlagDaysCalendarOptions {
isDisabled: boolean;
@@ -22,6 +22,7 @@ export interface FlagDaysCalendarOptions {
maxDate: Date;
daysDisabled: number[];
datesDisabled: Date[];
+ datesEnabled: Date[];
hoveredDate: Date;
selectedDate: Date;
selectedRange: Date[];
@@ -67,7 +68,8 @@ export function flagDaysCalendar(
isBefore(day.date, options.minDate, 'day') ||
isAfter(day.date, options.maxDate, 'day') ||
isDisabledDay(day.date, options.daysDisabled) ||
- isDisabledDate(day.date, options.datesDisabled);
+ isDisabledDate(day.date, options.datesDisabled) ||
+ isEnabledDate(day.date, options.datesEnabled);
const currentDate = new Date();
const isToday = !isOtherMonth && isSameDay(day.date, currentDate);
diff --git a/src/datepicker/engine/flag-days.calendar.spec.ts b/src/datepicker/engine/flag-days.calendar.spec.ts
index 48be80497f..43ff6f944c 100644
--- a/src/datepicker/engine/flag-days.calendar.spec.ts
+++ b/src/datepicker/engine/flag-days.calendar.spec.ts
@@ -2,42 +2,85 @@ import { flagDaysCalendar } from './flag-days-calendar';
describe('flag-days-calendar:', () => {
- it('should flag days as disabled when they are part of the datesDisabled', () => {
- const weekViewModel = {
- month: new Date('2019-02-01'),
- weeks: [
- {
- days: [
- { date: new Date('2019-02-07'), label: '2019-02-07' },
- { date: new Date('2019-02-08'), label: '2019-02-08' },
- { date: new Date('2019-02-09'), label: '2019-02-09' }
- ]}
- ],
- weekNumbers: [],
- weekdays: [],
- monthTitle: '',
- yearTitle: ''
- };
- const datesDisabled = [
- new Date('2019-02-07'),
- new Date('2019-02-09')
- ];
- const result = flagDaysCalendar(weekViewModel, {
- datesDisabled,
- isDisabled: false,
- minDate: new Date('2019-01-01'),
- maxDate: new Date('2019-12-31'),
- daysDisabled: [],
- hoveredDate: new Date('2019-02-06'),
- selectedDate: new Date('2019-02-05'),
- selectedRange: [],
- displayMonths: 1,
- monthIndex: 1,
- dateCustomClasses: []
- });
+ it('should flag days as disabled when they are part of the datesDisabled', () => {
+ const weekViewModel = {
+ month: new Date('2019-02-01'),
+ weeks: [
+ {
+ days: [
+ { date: new Date('2019-02-07'), label: '2019-02-07' },
+ { date: new Date('2019-02-08'), label: '2019-02-08' },
+ { date: new Date('2019-02-09'), label: '2019-02-09' }
+ ]
+ }
+ ],
+ weekNumbers: [],
+ weekdays: [],
+ monthTitle: '',
+ yearTitle: ''
+ };
+ const datesDisabled = [
+ new Date('2019-02-07'),
+ new Date('2019-02-09')
+ ];
+ const result = flagDaysCalendar(weekViewModel, {
+ datesDisabled,
+ isDisabled: false,
+ minDate: new Date('2019-01-01'),
+ maxDate: new Date('2019-12-31'),
+ daysDisabled: [],
+ datesEnabled: [],
+ hoveredDate: new Date('2019-02-06'),
+ selectedDate: new Date('2019-02-05'),
+ selectedRange: [],
+ displayMonths: 1,
+ monthIndex: 1,
+ dateCustomClasses: []
+ });
+
+ expect(result.weeks[0].days.find(day => day.label === '2019-02-07').isDisabled).toBe(true);
+ expect(result.weeks[0].days.find(day => day.label === '2019-02-08').isDisabled).toBe(false);
+ expect(result.weeks[0].days.find(day => day.label === '2019-02-09').isDisabled).toBe(true);
+ });
- expect(result.weeks[0].days.find(day => day.label === '2019-02-07').isDisabled).toBe(true);
- expect(result.weeks[0].days.find(day => day.label === '2019-02-08').isDisabled).toBe(false);
- expect(result.weeks[0].days.find(day => day.label === '2019-02-09').isDisabled).toBe(true);
+ it('should flag days as disabled when they are not part of the datesEnabled', () => {
+ const weekViewModel = {
+ month: new Date('2020-02-01'),
+ weeks: [
+ {
+ days: [
+ { date: new Date('2020-02-07'), label: '2020-02-07' },
+ { date: new Date('2020-02-08'), label: '2020-02-08' },
+ { date: new Date('2020-02-09'), label: '2020-02-09' }
+ ]
+ }
+ ],
+ weekNumbers: [],
+ weekdays: [],
+ monthTitle: '',
+ yearTitle: ''
+ };
+ const datesEnabled = [
+ new Date('2020-02-07'),
+ new Date('2020-02-09')
+ ];
+ const result = flagDaysCalendar(weekViewModel, {
+ datesEnabled,
+ isDisabled: false,
+ minDate: new Date('2020-01-01'),
+ maxDate: new Date('2020-12-31'),
+ daysDisabled: [],
+ datesDisabled: [],
+ hoveredDate: new Date('2020-02-06'),
+ selectedDate: new Date('2020-02-05'),
+ selectedRange: [],
+ displayMonths: 1,
+ monthIndex: 1,
+ dateCustomClasses: []
});
- });
+
+ expect(result.weeks[0].days.find(day => day.label === '2020-02-07').isDisabled).toBe(false);
+ expect(result.weeks[0].days.find(day => day.label === '2020-02-08').isDisabled).toBe(true);
+ expect(result.weeks[0].days.find(day => day.label === '2020-02-09').isDisabled).toBe(false);
+ });
+});
diff --git a/src/datepicker/reducer/bs-datepicker.actions.ts b/src/datepicker/reducer/bs-datepicker.actions.ts
index 9c98bb5ea8..4ded45b8f1 100644
--- a/src/datepicker/reducer/bs-datepicker.actions.ts
+++ b/src/datepicker/reducer/bs-datepicker.actions.ts
@@ -25,6 +25,7 @@ export class BsDatepickerActions {
static readonly SET_MAX_DATE = '[datepicker] set max date';
static readonly SET_DAYSDISABLED = '[datepicker] set days disabled';
static readonly SET_DATESDISABLED = '[datepicker] set dates disabled';
+ static readonly SET_DATESENABLED = '[datepicker] set dates enabled';
static readonly SET_IS_DISABLED = '[datepicker] set is disabled';
static readonly SET_DATE_CUSTOM_CLASSES = '[datepicker] set date custom classes';
@@ -122,6 +123,13 @@ export class BsDatepickerActions {
};
}
+ datesEnabled(dates: Date[]): Action {
+ return {
+ type: BsDatepickerActions.SET_DATESENABLED,
+ payload: dates
+ };
+ }
+
isDisabled(value: boolean): Action {
return {
type: BsDatepickerActions.SET_IS_DISABLED,
diff --git a/src/datepicker/reducer/bs-datepicker.effects.ts b/src/datepicker/reducer/bs-datepicker.effects.ts
index 8796ba10ef..b93ef7dc34 100644
--- a/src/datepicker/reducer/bs-datepicker.effects.ts
+++ b/src/datepicker/reducer/bs-datepicker.effects.ts
@@ -67,18 +67,24 @@ export class BsDatepickerEffects {
return this;
}
- setDaysDisabled(value: number[]) {
+ setDaysDisabled(value: number[]): BsDatepickerEffects {
this._store.dispatch(this._actions.daysDisabled(value));
return this;
}
- setDatesDisabled(value: Date[]) {
+ setDatesDisabled(value: Date[]): BsDatepickerEffects {
this._store.dispatch(this._actions.datesDisabled(value));
return this;
}
+ setDatesEnabled(value: Date[]): BsDatepickerEffects {
+ this._store.dispatch(this._actions.datesEnabled(value));
+
+ return this;
+ }
+
setDisabled(value: boolean): BsDatepickerEffects {
this._store.dispatch(this._actions.isDisabled(value));
diff --git a/src/datepicker/reducer/bs-datepicker.reducer.ts b/src/datepicker/reducer/bs-datepicker.reducer.ts
index e1570143b9..31e0e497c1 100644
--- a/src/datepicker/reducer/bs-datepicker.reducer.ts
+++ b/src/datepicker/reducer/bs-datepicker.reducer.ts
@@ -291,6 +291,7 @@ function flagReducer(state: BsDatepickerState,
maxDate: state.maxDate,
daysDisabled: state.daysDisabled,
datesDisabled: state.datesDisabled,
+ datesEnabled: state.datesEnabled,
hoveredDate: state.hoveredDate,
selectedDate: state.selectedDate,
selectedRange: state.selectedRange,
diff --git a/src/datepicker/reducer/bs-datepicker.state.ts b/src/datepicker/reducer/bs-datepicker.state.ts
index f8ce2f3982..0dcc129ff5 100644
--- a/src/datepicker/reducer/bs-datepicker.state.ts
+++ b/src/datepicker/reducer/bs-datepicker.state.ts
@@ -33,6 +33,7 @@ export class BsDatepickerState
maxDate?: Date;
daysDisabled?: number[];
datesDisabled?: Date[];
+ datesEnabled?: Date[];
minMode?: BsDatepickerViewMode;
dateCustomClasses?: DatepickerDateCustomClasses[];
diff --git a/src/datepicker/utils/bs-calendar-utils.ts b/src/datepicker/utils/bs-calendar-utils.ts
index 94cee4779f..25e3edad82 100644
--- a/src/datepicker/utils/bs-calendar-utils.ts
+++ b/src/datepicker/utils/bs-calendar-utils.ts
@@ -6,6 +6,7 @@ import {
shiftDate,
endOf,
startOf,
+ isArray,
isSame
} from 'ngx-bootstrap/chronos';
import { BsDatepickerState } from '../reducer/bs-datepicker.state';
@@ -47,13 +48,21 @@ export function isYearDisabled(date: Date, min: Date, max: Date): boolean {
}
export function isDisabledDate(date: Date, datesDisabled: Date[]): boolean {
- if (datesDisabled === undefined || !datesDisabled || !datesDisabled.length) {
+ if (!datesDisabled || !isArray(datesDisabled) || !datesDisabled.length) {
return false;
}
return datesDisabled.some((dateDisabled: Date) => isSame(date, dateDisabled, 'date'));
}
+export function isEnabledDate(date: Date, datesEnabled: Date[]): boolean {
+ if (!datesEnabled || !isArray(datesEnabled) || !datesEnabled.length) {
+ return false;
+ }
+
+ return !datesEnabled.some((enabledDate: Date) => isSame(date, enabledDate, 'date'));
+}
+
export function getYearsCalendarInitialDate(state: BsDatepickerState, calendarIndex = 0): Date {
const model = state && state.yearsCalendarModel && state.yearsCalendarModel[calendarIndex];