Skip to content

Commit

Permalink
feat(datepicker): add enabledDates functionality (#5645)
Browse files Browse the repository at this point in the history
* feat(datepicker): add enabledDates functionality

* feat(demo): add demo for enabledDates functionality
  • Loading branch information
daniloff200 authored Feb 21, 2020
1 parent 750377a commit e2cdbb3
Show file tree
Hide file tree
Showing 17 changed files with 203 additions and 44 deletions.
15 changes: 14 additions & 1 deletion demo/src/app/components/+datepicker/datepicker-section.list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -205,9 +206,21 @@ export const demoComponentContent: ContentSection[] = [
html: require('!!raw-loader!./demos/disable-dates/disable-dates.html'),
description: `
<p>You can set which dates should be disabled with <code>datesDisabled</code></p>
<p>In the following example <code>datesDisabled</code> is set with an array to disable 2019-02-05 and 2019-02-09.</p>`,
<p>In the following example <code>datesDisabled</code> is set with an array to disable 2019-02-05 and 2019-02-09.</p>
<p>NOTE: DO NOT USE this functionality with <code>datesEnabled</code> at the same time</p>`,
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: `
<p>You can set which dates should be enable with <code>datesEnabled</code></p>
<p>In the following example <code>datesEnabled</code> is set with an array to enable 2020-02-06, 2020-02-08 and 2020-02-11. All other dates are disabled</p>
<p>NOTE: DO NOT USE this functionality with <code>datesDisabled</code> at the same time</p>`,
outlet: DemoDatepickerDatesEnabledComponent
},
{
title: 'Min-mode',
anchor: 'min-mode',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="row">
<div class="col-xs-12 col-12 col-md-4 form-group">
<input type="text"
placeholder="Datepicker"
class="form-control"
bsDatepicker
[datesEnabled]="enabledDates">
</div>
<div class="col-xs-12 col-12 col-md-4 form-group">
<input type="text"
placeholder="Daterangepicker"
class="form-control"
bsDaterangepicker
[datesEnabled]="enabledDates">
</div>
</div>
Original file line number Diff line number Diff line change
@@ -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'),
];
}
2 changes: 2 additions & 0 deletions demo/src/app/components/+datepicker/demos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -52,6 +53,7 @@ export const DEMO_COMPONENTS = [
DemoDatepickerDateCustomClassesComponent,
DemoDatepickerDateInitialStateComponent,
DemoDatepickerDatesDisabledComponent,
DemoDatepickerDatesEnabledComponent,
DemoDatepickerDaysDisabledComponent,
DemoDatepickerDisabledComponent,
DemoDatepickerFormsComponent,
Expand Down
4 changes: 4 additions & 0 deletions src/datepicker/base/bs-datepicker-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
12 changes: 11 additions & 1 deletion src/datepicker/bs-datepicker-inline.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand All @@ -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) {
Expand Down
9 changes: 9 additions & 0 deletions src/datepicker/bs-datepicker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
});
}
Expand Down
4 changes: 4 additions & 0 deletions src/datepicker/bs-datepicker.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
9 changes: 9 additions & 0 deletions src/datepicker/bs-daterangepicker-inline.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
});
}
Expand Down
9 changes: 9 additions & 0 deletions src/datepicker/bs-daterangepicker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ export class BsDaterangepickerDirective
*/
@Input() datesDisabled: Date[];

/**
* Enable specific dates
*/
@Input() datesEnabled: Date[];
/**
* Emits when daterangepicker value has been changed
*/
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
}
);
Expand Down
6 changes: 4 additions & 2 deletions src/datepicker/engine/flag-days-calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ 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;
minDate: Date;
maxDate: Date;
daysDisabled: number[];
datesDisabled: Date[];
datesEnabled: Date[];
hoveredDate: Date;
selectedDate: Date;
selectedRange: Date[];
Expand Down Expand Up @@ -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);
Expand Down
117 changes: 80 additions & 37 deletions src/datepicker/engine/flag-days.calendar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
8 changes: 8 additions & 0 deletions src/datepicker/reducer/bs-datepicker.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit e2cdbb3

Please sign in to comment.