Skip to content

Commit 5633d2d

Browse files
frederikprijckvalorkin
authored andcommitted
feat(datepicker): Allow to disable specific dates (#5046)
* feat(datepicker): Allow to disable specific dates * feat(datepicker): Move isDisabledDate outside of chronos * feat(datepicker): Add datesDisabled to inline datepicker * feat(datepicker): Add datesDisabled to daterangepicker * feat(datepicker): Update demo for datesDisabled * feat(datepicker): Add test for flag days calendar * feat(datepicker): update docs for datesDisabled * feat(datepicker): Fix typo * feat(datepicker): Add demo for datesDisabled with daterangepicker
1 parent af59314 commit 5633d2d

18 files changed

+183
-19
lines changed

demo/src/app/components/+datepicker/datepicker-section.list.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { DemoDatePickerConfigObjectComponent } from './demos/config-object/confi
1010
import { DemoDatePickerCustomFormatComponent } from './demos/custom-format/custom-format';
1111
import { DemoDatepickerDateInitialStateComponent } from './demos/date-initial-state/date-initial-state';
1212
import { DemoDatepickerDaysDisabledComponent } from './demos/disable-days/disable-days';
13+
import { DemoDatepickerDatesDisabledComponent } from './demos/disable-dates/disable-dates';
1314
import { DemoDatepickerInlineComponent } from './demos/inline-datepicker/inline-datepicker.component';
1415
import { DemoDatepickerDisabledComponent } from './demos/disabled/disabled.component';
1516
import { DemoDatepickerFormsComponent } from './demos/forms/forms.component';
@@ -173,6 +174,16 @@ export const demoComponentContent: ContentSection[] = [
173174
Sunday is considered the first day of the week and thus has the value 0</p>`,
174175
outlet: DemoDatepickerDaysDisabledComponent
175176
},
177+
{
178+
title: 'Dates disabled',
179+
anchor: 'dates-disabled',
180+
component: require('!!raw-loader?lang=typescript!./demos/disable-dates/disable-dates.ts'),
181+
html: require('!!raw-loader?lang=markup!./demos/disable-dates/disable-dates.html'),
182+
description: `
183+
<p>You can set which dates should be disabled with <code>datesDisabled</code></p>
184+
<p>In the following example <code>datesDisabled</code> is set with an array to disable 2019-02-05 and 2019-02-09.</p>`,
185+
outlet: DemoDatepickerDatesDisabledComponent
186+
},
176187
{
177188
title: 'Min-mode',
178189
anchor: 'min-mode',
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<div class="row">
2+
<div class="col-xs-12 col-12 col-md-4 form-group">
3+
<input type="text"
4+
placeholder="Datepicker"
5+
class="form-control"
6+
bsDatepicker
7+
[datesDisabled]="disabledDates">
8+
</div>
9+
<div class="col-xs-12 col-12 col-md-4 form-group">
10+
<input type="text"
11+
placeholder="Daterangepicker"
12+
class="form-control"
13+
bsDaterangepicker
14+
[datesDisabled]="disabledDates">
15+
</div>
16+
</div>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
selector: 'demo-datepicker-datesdisabled',
5+
templateUrl: './disable-dates.html'
6+
})
7+
export class DemoDatepickerDatesDisabledComponent {
8+
disabledDates = [
9+
new Date('2019-02-05'),
10+
new Date('2019-02-09')
11+
];
12+
}

demo/src/app/components/+datepicker/demos/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { DemoDatePickerCustomFormatComponent } from './custom-format/custom-form
99
import { DemoDatepickerCustomTodayClassComponent } from './custom-today-class/custom-today-class.component';
1010
import { DemoDatepickerDateInitialStateComponent } from './date-initial-state/date-initial-state';
1111
import { DemoDatepickerDaysDisabledComponent } from './disable-days/disable-days';
12+
import { DemoDatepickerDatesDisabledComponent } from './disable-dates/disable-dates';
1213
import { DemoDatepickerDisabledComponent } from './disabled/disabled.component';
1314
import { DemoDatepickerFormsComponent } from './forms/forms.component';
1415
import { DemoDatepickerHideOnScrollComponent } from './hide-on-scroll/hide-on-scroll';
@@ -41,6 +42,7 @@ export const DEMO_COMPONENTS = [
4142
DemoDatePickerCustomFormatComponent,
4243
DemoDatepickerCustomTodayClassComponent,
4344
DemoDatepickerDateInitialStateComponent,
45+
DemoDatepickerDatesDisabledComponent,
4446
DemoDatepickerDaysDisabledComponent,
4547
DemoDatepickerDisabledComponent,
4648
DemoDatepickerFormsComponent,

demo/src/ng-api-doc.ts

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,11 @@ export const ngdoc: any = {
676676
"type": "Date",
677677
"description": "<p>Initial value of datepicker</p>\n"
678678
},
679+
{
680+
"name": "datesDisabled",
681+
"type": "Date[]",
682+
"description": "<p>Disable specific dates</p>\n"
683+
},
679684
{
680685
"name": "isDisabled",
681686
"type": "boolean",
@@ -748,6 +753,11 @@ export const ngdoc: any = {
748753
"type": "string",
749754
"description": "<p>A selector specifying the element the datepicker should be appended to.\nCurrently only supports &quot;body&quot;.</p>\n"
750755
},
756+
{
757+
"name": "datesDisabled",
758+
"type": "Date[]",
759+
"description": "<p>Disable specific dates</p>\n"
760+
},
751761
{
752762
"name": "daysDisabled",
753763
"type": "number[]",
@@ -862,6 +872,11 @@ export const ngdoc: any = {
862872
"type": "string",
863873
"description": "<p>Add class to current day</p>\n"
864874
},
875+
{
876+
"name": "datesDisabled",
877+
"type": "Date[]",
878+
"description": "<p>Disable specific dates</p>\n"
879+
},
865880
{
866881
"name": "maxDate",
867882
"type": "Date",
@@ -875,7 +890,7 @@ export const ngdoc: any = {
875890
{
876891
"name": "minMode",
877892
"type": "BsDatepickerViewMode",
878-
"description": "<p>Defaut mode for all date pickers</p>\n"
893+
"description": "<p>Default mode for all date pickers</p>\n"
879894
},
880895
{
881896
"name": "rangeInputFormat",
@@ -888,6 +903,11 @@ export const ngdoc: any = {
888903
"type": "boolean",
889904
"description": "<p>Makes dates from other months active</p>\n"
890905
},
906+
{
907+
"name": "selectWeek",
908+
"type": "boolean",
909+
"description": "<p>Makes dates from other months active</p>\n"
910+
},
891911
{
892912
"name": "showWeekNumbers",
893913
"defaultValue": "true",
@@ -929,6 +949,11 @@ export const ngdoc: any = {
929949
"type": "string",
930950
"description": "<p>A selector specifying the element the daterangepicker should be appended\nto. Currently only supports &quot;body&quot;.</p>\n"
931951
},
952+
{
953+
"name": "datesDisabled",
954+
"type": "Date[]",
955+
"description": "<p>Disable specific dates</p>\n"
956+
},
932957
{
933958
"name": "isDisabled",
934959
"type": "boolean",
@@ -1666,6 +1691,10 @@ export const ngdoc: any = {
16661691
"name": "onHover",
16671692
"description": ""
16681693
},
1694+
{
1695+
"name": "onHoverWeek",
1696+
"description": ""
1697+
},
16691698
{
16701699
"name": "onNavigate",
16711700
"description": ""
@@ -1940,7 +1969,7 @@ export const ngdoc: any = {
19401969
"properties": [
19411970
{
19421971
"name": "dropdownMenu",
1943-
"type": "Promise<any>",
1972+
"type": "Promise<BsComponentRef<any>>",
19441973
"description": "<p>Content to be displayed as popover.</p>\n"
19451974
}
19461975
]
@@ -2953,11 +2982,6 @@ export const ngdoc: any = {
29532982
"type": "boolean",
29542983
"description": "<p>if true hours and minutes fields will be disabled </p>\n"
29552984
},
2956-
{
2957-
"name": "disabled",
2958-
"type": "boolean",
2959-
"description": "<p>if true hours and minutes fields will be disabled </p>\n"
2960-
},
29612985
{
29622986
"name": "hourStep",
29632987
"type": "number",
@@ -3046,12 +3070,6 @@ export const ngdoc: any = {
30463070
"type": "boolean",
30473071
"description": "<p>if true hours and minutes fields will be disabled </p>\n"
30483072
},
3049-
{
3050-
"name": "disabled",
3051-
"defaultValue": "false",
3052-
"type": "boolean",
3053-
"description": "<p>if true hours and minutes fields will be disabled </p>\n"
3054-
},
30553073
{
30563074
"name": "hourStep",
30573075
"defaultValue": "1",

src/chronos/public_api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export {
2727

2828
export { LocaleData } from './locale/locale.class';
2929

30-
export { isAfter, isBefore, isDisabledDay } from './utils/date-compare';
30+
export { isAfter, isBefore, isDisabledDay, isSame } from './utils/date-compare';
3131
export { isArray, isDateValid, isDate } from './utils/type-checks';
3232
export { shiftDate, setFullDate } from './utils/date-setters';
3333
export { endOf, startOf } from './utils/start-end-of';

src/datepicker/base/bs-datepicker-container.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export abstract class BsDatepickerAbstractComponent {
3333
set daysDisabled(value: number[]) {
3434
this._effects.setDaysDisabled(value);
3535
}
36+
set datesDisabled(value: Date[]) {
37+
this._effects.setDatesDisabled(value);
38+
}
3639

3740
set isDisabled(value: boolean) {
3841
this._effects.setDisabled(value);

src/datepicker/bs-datepicker-inline.component.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ export class BsDatepickerInlineDirective implements OnInit, OnDestroy, OnChanges
4242
* Maximum date which is available for selection
4343
*/
4444
@Input() maxDate: Date;
45+
/**
46+
* Disable specific dates
47+
*/
48+
@Input() datesDisabled: Date[];
4549
/**
4650
* Emits when datepicker value has been changed
4751
*/
@@ -103,6 +107,10 @@ export class BsDatepickerInlineDirective implements OnInit, OnDestroy, OnChanges
103107
this._datepickerRef.instance.maxDate = this.maxDate;
104108
}
105109

110+
if (changes.datesDisabled) {
111+
this._datepickerRef.instance.datesDisabled = this.datesDisabled;
112+
}
113+
106114
if (changes.isDisabled) {
107115
this._datepickerRef.instance.isDisabled = this.isDisabled;
108116
}
@@ -116,7 +124,8 @@ export class BsDatepickerInlineDirective implements OnInit, OnDestroy, OnChanges
116124
value: this._bsValue,
117125
isDisabled: this.isDisabled,
118126
minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
119-
maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate
127+
maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
128+
datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled
120129
});
121130
}
122131

src/datepicker/bs-datepicker.component.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ export class BsDatepickerDirective implements OnInit, OnDestroy, OnChanges {
100100
* Disable Certain days in the week
101101
*/
102102
@Input() daysDisabled: number[];
103+
104+
/**
105+
* Disable specific dates
106+
*/
107+
@Input() datesDisabled: Date[];
103108
/**
104109
* Emits when datepicker value has been changed
105110
*/
@@ -153,6 +158,10 @@ export class BsDatepickerDirective implements OnInit, OnDestroy, OnChanges {
153158
this._datepickerRef.instance.daysDisabled = this.daysDisabled;
154159
}
155160

161+
if (changes.datesDisabled) {
162+
this._datepickerRef.instance.datesDisabled = this.datesDisabled;
163+
}
164+
156165
if (changes.isDisabled) {
157166
this._datepickerRef.instance.isDisabled = this.isDisabled;
158167
}
@@ -227,6 +236,7 @@ export class BsDatepickerDirective implements OnInit, OnDestroy, OnChanges {
227236
minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
228237
maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
229238
daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
239+
datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
230240
minMode: this.minMode || this.bsConfig && this.bsConfig.minMode
231241
});
232242
}

src/datepicker/bs-datepicker.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ export class BsDatepickerConfig implements DatepickerRenderOptions {
2323
maxDate?: Date;
2424

2525
daysDisabled?: number[];
26+
27+
/**
28+
* Disable specific dates
29+
*/
30+
datesDisabled?: Date[];
2631
/**
2732
* Makes dates from other months active
2833
*/

src/datepicker/bs-daterangepicker.component.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ export class BsDaterangepickerDirective
102102
* Maximum date which is available for selection
103103
*/
104104
@Input() maxDate: Date;
105+
/**
106+
* Disable specific dates
107+
*/
108+
@Input() datesDisabled: Date[];
105109
/**
106110
* Emits when daterangepicker value has been changed
107111
*/
@@ -150,6 +154,10 @@ export class BsDaterangepickerDirective
150154
this._datepickerRef.instance.maxDate = this.maxDate;
151155
}
152156

157+
if (changes.datesDisabled) {
158+
this._datepickerRef.instance.datesDisabled = this.datesDisabled;
159+
}
160+
153161
if (changes.isDisabled) {
154162
this._datepickerRef.instance.isDisabled = this.isDisabled;
155163
}
@@ -205,7 +213,8 @@ export class BsDaterangepickerDirective
205213
value: this._bsValue,
206214
isDisabled: this.isDisabled,
207215
minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
208-
maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate
216+
maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
217+
datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled
209218
}
210219
);
211220
}

src/datepicker/engine/flag-days-calendar.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ import {
1313
shiftDate
1414
} from 'ngx-bootstrap/chronos';
1515

16-
import { isMonthDisabled } from '../utils/bs-calendar-utils';
16+
import { isMonthDisabled, isDisabledDate } from '../utils/bs-calendar-utils';
1717

1818
export interface FlagDaysCalendarOptions {
1919
isDisabled: boolean;
2020
minDate: Date;
2121
maxDate: Date;
2222
daysDisabled: number[];
23+
datesDisabled: Date[];
2324
hoveredDate: Date;
2425
selectedDate: Date;
2526
selectedRange: Date[];
@@ -63,7 +64,8 @@ export function flagDaysCalendar(
6364
options.isDisabled ||
6465
isBefore(day.date, options.minDate, 'day') ||
6566
isAfter(day.date, options.maxDate, 'day') ||
66-
isDisabledDay(day.date, options.daysDisabled);
67+
isDisabledDay(day.date, options.daysDisabled) ||
68+
isDisabledDate(day.date, options.datesDisabled);
6769

6870
const currentDate = new Date();
6971
const isToday = !isOtherMonth && isSameDay(day.date, currentDate);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { flagDaysCalendar } from './flag-days-calendar';
2+
3+
describe('flag-days-calendar:', () => {
4+
5+
it('should flag days as disabled when they are part of the datesDisabled', () => {
6+
const weekViewModel = {
7+
month: new Date('2019-02-01'),
8+
weeks: [
9+
{
10+
days: [
11+
{ date: new Date('2019-02-07'), label: '2019-02-07' },
12+
{ date: new Date('2019-02-08'), label: '2019-02-08' },
13+
{ date: new Date('2019-02-09'), label: '2019-02-09' }
14+
]}
15+
],
16+
weekNumbers: [],
17+
weekdays: [],
18+
monthTitle: '',
19+
yearTitle: ''
20+
};
21+
const datesDisabled = [
22+
new Date('2019-02-07'),
23+
new Date('2019-02-09')
24+
];
25+
const result = flagDaysCalendar(weekViewModel, {
26+
datesDisabled,
27+
isDisabled: false,
28+
minDate: new Date('2019-01-01'),
29+
maxDate: new Date('2019-12-31'),
30+
daysDisabled: [],
31+
hoveredDate: new Date('2019-02-06'),
32+
selectedDate: new Date('2019-02-05'),
33+
selectedRange: [],
34+
displayMonths: 1,
35+
monthIndex: 1
36+
});
37+
38+
expect(result.weeks[0].days.find(day => day.label === '2019-02-07').isDisabled).toBe(true);
39+
expect(result.weeks[0].days.find(day => day.label === '2019-02-08').isDisabled).toBe(false);
40+
expect(result.weeks[0].days.find(day => day.label === '2019-02-09').isDisabled).toBe(true);
41+
});
42+
});

0 commit comments

Comments
 (0)