Skip to content

Commit d9a89b4

Browse files
martintrovalorkin
authored andcommitted
feat(datepicker): Add directive for inline datepicker (#3956)
* feat(datepicker): Add directive for inline datepicker Closes #3955 * feat(datepicker): add support to set custom classes on specific dates Closes #3958 * Revert "feat(datepicker): add support to set custom classes on specific dates" This reverts commit 47a1a11. * feat(datepicker): resolve conflicts * fix(datepicker): fix tslint * fix(datepicker): clean up * fix(datepicker): add base spec for inline datepicker * fix(common): fix imports for system js
1 parent 89f7265 commit d9a89b4

14 files changed

+354
-16
lines changed

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { DemoDatepickerConfigMethodComponent } from './demos/config-method/confi
99
import { DemoDatePickerConfigObjectComponent } from './demos/config-object/config-object';
1010
import { DemoDatePickerCustomFormatComponent } from './demos/custom-format/custom-format';
1111
import { DemoDatepickerDateInitialStateComponent } from './demos/date-initial-state/date-initial-state';
12+
import { DemoDatepickerDaysDisabledComponent } from './demos/disable-days/disable-days';
13+
import { DemoDatepickerInlineComponent } from './demos/inline-datepicker/inline-datepicker.component';
1214
import { DemoDatepickerDisabledComponent } from './demos/disabled/disabled.component';
1315
import { DemoDatepickerFormsComponent } from './demos/forms/forms.component';
1416
import { DemoDatepickerHideOnScrollComponent } from './demos/hide-on-scroll/hide-on-scroll';
@@ -17,6 +19,7 @@ import { DemoDatepickerMinModeComponent } from './demos/min-mode/min-mode.compon
1719
import { DemoDatepickerOutsideClickComponent } from './demos/outside-click/outside-click';
1820
import { DemoDatepickerPlacementComponent } from './demos/placement/placement';
1921
import { DemoDatepickerReactiveFormsComponent } from './demos/reactive-forms/reactive-forms.component';
22+
2023
import {
2124
DemoDatePickerSelectDatesFromOtherMonthsComponent
2225
} from './demos/select-dates-from-other-months/select-dates-from-other-months';
@@ -33,8 +36,6 @@ import {
3336
NgApiDocComponent,
3437
NgApiDocConfigComponent
3538
} from '../../docs/api-docs';
36-
import { DemoDatepickerDaysDisabledComponent } from './demos/disable-days/disable-days';
37-
3839

3940
export const demoComponentContent: ContentSection[] = [
4041
{
@@ -70,6 +71,14 @@ export const demoComponentContent: ContentSection[] = [
7071
`,
7172
outlet: DemoDatepickerBasicComponent
7273
},
74+
{
75+
title: 'Inline Datepicker',
76+
anchor: 'inline-datepicker',
77+
component: require('!!raw-loader?lang=typescript!./demos/inline-datepicker/inline-datepicker.component.ts'),
78+
html: require('!!raw-loader?lang=markup!./demos/inline-datepicker/inline-datepicker.component.html'),
79+
description: `<p>with initial state set by <code>bsInlineValue</code> property</p>`,
80+
outlet: DemoDatepickerInlineComponent
81+
},
7382
{
7483
title: 'Initial state',
7584
anchor: 'date-initial-state',
@@ -315,6 +324,11 @@ export const demoComponentContent: ContentSection[] = [
315324
anchor: 'bs-daterangepicker',
316325
outlet: NgApiDocComponent
317326
},
327+
{
328+
title: 'BsDatepickerInlineDirective',
329+
anchor: 'bs-datepicker-inline',
330+
outlet: NgApiDocComponent
331+
},
318332
{
319333
title: 'BsDatepickerConfig',
320334
anchor: 'bs-datepicker-config',

demo/src/app/components/+datepicker/demos/basic/basic.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,3 @@
1212
bsDaterangepicker>
1313
</div>
1414
</div>
15-

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ import { DemoDatepickerDaysDisabledComponent } from './disable-days/disable-days
1212
import { DemoDatepickerDisabledComponent } from './disabled/disabled.component';
1313
import { DemoDatepickerFormsComponent } from './forms/forms.component';
1414
import { DemoDatepickerHideOnScrollComponent } from './hide-on-scroll/hide-on-scroll';
15+
import { DemoDatepickerInlineComponent } from './inline-datepicker/inline-datepicker.component';
1516
import { DemoDatepickerMinMaxComponent } from './min-max/min-max.component';
1617
import { DemoDatepickerMinModeComponent } from './min-mode/min-mode.component';
1718
import { DemoDatepickerOutsideClickComponent } from './outside-click/outside-click';
1819
import { DemoDatepickerPlacementComponent } from './placement/placement';
1920
import { DemoDatepickerReactiveFormsComponent } from './reactive-forms/reactive-forms.component';
21+
2022
import {
2123
DemoDatePickerSelectDatesFromOtherMonthsComponent
2224
} from './select-dates-from-other-months/select-dates-from-other-months';
25+
2326
import { DemoDatePickerSelectWeekComponent } from './select-week/select-week';
2427
import { DemoDatepickerTriggersCustomComponent } from './triggers-custom/triggers-custom';
2528
import { DemoDatepickerTriggersManualComponent } from './triggers-manual/triggers-manual';
@@ -42,6 +45,7 @@ export const DEMO_COMPONENTS = [
4245
DemoDatepickerDisabledComponent,
4346
DemoDatepickerFormsComponent,
4447
DemoDatepickerHideOnScrollComponent,
48+
DemoDatepickerInlineComponent,
4549
DemoDatepickerMinMaxComponent,
4650
DemoDatepickerMinModeComponent,
4751
DemoDatepickerOutsideClickComponent,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div class="row">
2+
<div class="col-xs-12 col-12 col-md-4 form-group">
3+
<bs-datepicker-inline [bsValue]="bsInlineValue"></bs-datepicker-inline>
4+
</div>
5+
</div>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
selector: 'demo-datepicker-inline',
5+
templateUrl: './inline-datepicker.component.html'
6+
})
7+
export class DemoDatepickerInlineComponent {
8+
bsInlineValue = new Date();
9+
}

demo/src/ng-api-doc.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,62 @@ export const ngdoc: any = {
659659
"methods": [],
660660
"properties": []
661661
},
662+
"BsDatepickerInlineDirective": {
663+
"fileName": "src/datepicker/bs-datepicker-inline.component.ts",
664+
"className": "BsDatepickerInlineDirective",
665+
"description": "",
666+
"selector": "bs-datepicker-inline",
667+
"exportAs": "bsDatepickerInline",
668+
"inputs": [
669+
{
670+
"name": "bsConfig",
671+
"type": "Partial<BsDatepickerInlineConfig>",
672+
"description": "<p>Config object for datepicker</p>\n"
673+
},
674+
{
675+
"name": "bsValue",
676+
"type": "Date",
677+
"description": "<p>Initial value of datepicker</p>\n"
678+
},
679+
{
680+
"name": "isDisabled",
681+
"type": "boolean",
682+
"description": "<p>Indicates whether datepicker is enabled or not</p>\n"
683+
},
684+
{
685+
"name": "maxDate",
686+
"type": "Date",
687+
"description": "<p>Maximum date which is available for selection</p>\n"
688+
},
689+
{
690+
"name": "minDate",
691+
"type": "Date",
692+
"description": "<p>Minimum date which is available for selection</p>\n"
693+
}
694+
],
695+
"outputs": [
696+
{
697+
"name": "bsValueChange",
698+
"description": "<p>Emits when datepicker value has been changed</p>\n"
699+
}
700+
],
701+
"properties": [],
702+
"methods": [
703+
{
704+
"name": "setConfig",
705+
"description": "<p>Set config for datepicker</p>\n",
706+
"args": [],
707+
"returnType": "void"
708+
}
709+
]
710+
},
711+
"BsDatepickerInlineConfig": {
712+
"fileName": "src/datepicker/bs-datepicker-inline.config.ts",
713+
"className": "BsDatepickerInlineConfig",
714+
"description": "",
715+
"methods": [],
716+
"properties": []
717+
},
662718
"BsDatepickerInputDirective": {
663719
"fileName": "src/datepicker/bs-datepicker-input.directive.ts",
664720
"className": "BsDatepickerInputDirective",
@@ -1543,6 +1599,16 @@ export const ngdoc: any = {
15431599
"properties": [],
15441600
"methods": []
15451601
},
1602+
"BsDatepickerInlineContainerComponent": {
1603+
"fileName": "src/datepicker/themes/bs/bs-datepicker-inline-container.component.ts",
1604+
"className": "BsDatepickerInlineContainerComponent",
1605+
"description": "",
1606+
"selector": "bs-datepicker-inline-container",
1607+
"inputs": [],
1608+
"outputs": [],
1609+
"properties": [],
1610+
"methods": []
1611+
},
15461612
"BsDatepickerNavigationViewComponent": {
15471613
"fileName": "src/datepicker/themes/bs/bs-datepicker-navigation-view.component.ts",
15481614
"className": "BsDatepickerNavigationViewComponent",
@@ -2887,6 +2953,11 @@ export const ngdoc: any = {
28872953
"type": "boolean",
28882954
"description": "<p>if true hours and minutes fields will be disabled </p>\n"
28892955
},
2956+
{
2957+
"name": "disabled",
2958+
"type": "boolean",
2959+
"description": "<p>if true hours and minutes fields will be disabled </p>\n"
2960+
},
28902961
{
28912962
"name": "hourStep",
28922963
"type": "number",
@@ -2975,6 +3046,12 @@ export const ngdoc: any = {
29753046
"type": "boolean",
29763047
"description": "<p>if true hours and minutes fields will be disabled </p>\n"
29773048
},
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+
},
29783055
{
29793056
"name": "hourStep",
29803057
"defaultValue": "1",

src/component-loader/component-loader.class.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export class ComponentLoader<T> {
107107
}
108108

109109
// todo: add behaviour: to target element, `body`, custom element
110-
to(container?: string): ComponentLoader<T> {
110+
to(container?: string | ElementRef): ComponentLoader<T> {
111111
this.container = container || this.container;
112112

113113
return this;
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import {
2+
ComponentRef, Directive, ElementRef, EventEmitter, Input, OnChanges,
3+
OnDestroy, OnInit, Output, Renderer2, SimpleChanges, ViewContainerRef
4+
} from '@angular/core';
5+
import { ComponentLoader, ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
6+
import { BsDatepickerInlineContainerComponent } from './themes/bs/bs-datepicker-inline-container.component';
7+
import { Subscription } from 'rxjs';
8+
import { BsDatepickerInlineConfig } from './bs-datepicker-inline.config';
9+
import { BsDatepickerConfig } from './bs-datepicker.config';
10+
11+
@Directive({
12+
selector: 'bs-datepicker-inline',
13+
exportAs: 'bsDatepickerInline'
14+
})
15+
export class BsDatepickerInlineDirective implements OnInit, OnDestroy, OnChanges {
16+
_bsValue: Date;
17+
/**
18+
* Initial value of datepicker
19+
*/
20+
@Input()
21+
set bsValue(value: Date) {
22+
if (this._bsValue === value) {
23+
return;
24+
}
25+
this._bsValue = value;
26+
this.bsValueChange.emit(value);
27+
}
28+
29+
/**
30+
* Config object for datepicker
31+
*/
32+
@Input() bsConfig: Partial<BsDatepickerInlineConfig>;
33+
/**
34+
* Indicates whether datepicker is enabled or not
35+
*/
36+
@Input() isDisabled: boolean;
37+
/**
38+
* Minimum date which is available for selection
39+
*/
40+
@Input() minDate: Date;
41+
/**
42+
* Maximum date which is available for selection
43+
*/
44+
@Input() maxDate: Date;
45+
/**
46+
* Emits when datepicker value has been changed
47+
*/
48+
@Output() bsValueChange: EventEmitter<Date> = new EventEmitter();
49+
50+
protected _subs: Subscription[] = [];
51+
52+
private _datepicker: ComponentLoader<BsDatepickerInlineContainerComponent>;
53+
private _datepickerRef: ComponentRef<BsDatepickerInlineContainerComponent>;
54+
55+
constructor(public _config: BsDatepickerInlineConfig,
56+
private _elementRef: ElementRef,
57+
_renderer: Renderer2,
58+
_viewContainerRef: ViewContainerRef,
59+
cis: ComponentLoaderFactory) {
60+
// todo: assign only subset of fields
61+
Object.assign(this, this._config);
62+
this._datepicker = cis.createLoader<BsDatepickerInlineContainerComponent>(
63+
_elementRef,
64+
_viewContainerRef,
65+
_renderer
66+
);
67+
}
68+
69+
ngOnInit(): void {
70+
this.setConfig();
71+
72+
this._datepickerRef = this._datepicker
73+
.provide({provide: BsDatepickerConfig, useValue: this._config})
74+
.attach(BsDatepickerInlineContainerComponent)
75+
.to(this._elementRef)
76+
.show();
77+
78+
// if date changes from external source (model -> view)
79+
this._subs.push(
80+
this.bsValueChange.subscribe((value: Date) => {
81+
this._datepickerRef.instance.value = value;
82+
})
83+
);
84+
85+
// if date changes from picker (view -> model)
86+
this._subs.push(
87+
this._datepickerRef.instance.valueChange.subscribe((value: Date) => {
88+
this.bsValue = value;
89+
})
90+
);
91+
}
92+
93+
ngOnChanges(changes: SimpleChanges): void {
94+
if (!this._datepickerRef || !this._datepickerRef.instance) {
95+
return;
96+
}
97+
98+
if (changes.minDate) {
99+
this._datepickerRef.instance.minDate = this.minDate;
100+
}
101+
102+
if (changes.maxDate) {
103+
this._datepickerRef.instance.maxDate = this.maxDate;
104+
}
105+
106+
if (changes.isDisabled) {
107+
this._datepickerRef.instance.isDisabled = this.isDisabled;
108+
}
109+
}
110+
111+
/**
112+
* Set config for datepicker
113+
*/
114+
setConfig(): void {
115+
this._config = Object.assign({}, this._config, this.bsConfig, {
116+
value: this._bsValue,
117+
isDisabled: this.isDisabled,
118+
minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
119+
maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate
120+
});
121+
}
122+
123+
ngOnDestroy(): any {
124+
this._datepicker.dispose();
125+
}
126+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Injectable } from '@angular/core';
2+
import { BsDatepickerConfig } from './bs-datepicker.config';
3+
4+
@Injectable()
5+
export class BsDatepickerInlineConfig extends BsDatepickerConfig { }

src/datepicker/bs-datepicker.module.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { BsDatepickerConfig } from './bs-datepicker.config';
99
import { BsDaterangepickerInputDirective } from './bs-daterangepicker-input.directive';
1010
import { BsDaterangepickerDirective } from './bs-daterangepicker.component';
1111
import { BsDaterangepickerConfig } from './bs-daterangepicker.config';
12+
import { BsDatepickerInlineDirective } from './bs-datepicker-inline.component';
13+
import { BsDatepickerInlineConfig } from './bs-datepicker-inline.config';
1214

1315
import { BsLocaleService } from './bs-locale.service';
1416
import { BsDatepickerActions } from './reducer/bs-datepicker.actions';
@@ -25,16 +27,20 @@ import { BsDaysCalendarViewComponent } from './themes/bs/bs-days-calendar-view.c
2527
import { BsMonthCalendarViewComponent } from './themes/bs/bs-months-calendar-view.component';
2628
import { BsTimepickerViewComponent } from './themes/bs/bs-timepicker-view.component';
2729
import { BsYearsCalendarViewComponent } from './themes/bs/bs-years-calendar-view.component';
30+
import { BsDatepickerInlineContainerComponent } from './themes/bs/bs-datepicker-inline-container.component';
2831

2932
const _exports = [
3033
BsDatepickerContainerComponent,
3134
BsDaterangepickerContainerComponent,
35+
BsDatepickerInlineContainerComponent,
3236

3337
BsDatepickerDirective,
3438
BsDatepickerInputDirective,
3539

3640
BsDaterangepickerInputDirective,
37-
BsDaterangepickerDirective
41+
BsDaterangepickerDirective,
42+
43+
BsDatepickerInlineDirective
3844
];
3945

4046
@NgModule({
@@ -56,7 +62,8 @@ const _exports = [
5662
],
5763
entryComponents: [
5864
BsDatepickerContainerComponent,
59-
BsDaterangepickerContainerComponent
65+
BsDaterangepickerContainerComponent,
66+
BsDatepickerInlineContainerComponent
6067
],
6168
exports: _exports
6269
})
@@ -71,6 +78,7 @@ export class BsDatepickerModule {
7178
BsDatepickerActions,
7279
BsDatepickerConfig,
7380
BsDaterangepickerConfig,
81+
BsDatepickerInlineConfig,
7482
BsDatepickerEffects,
7583
BsLocaleService
7684
]

0 commit comments

Comments
 (0)