Skip to content

Commit 6cc64c0

Browse files
MikiawmDomainv
authored andcommitted
feat(datepicker): add daterangepicker inline (#5307)
* daterangepicker inline init * add test file to daterangepicker inline * fix template html naming * remove unused code in test * add inline daterangepicker to demo * fix(datepicker): resolve conflicts * fix(datepicker): fix markup
1 parent 3286382 commit 6cc64c0

16 files changed

+303
-32
lines changed

cypress/full/datepicker/inline_datepicker_spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ describe('Datepicker demo test suite: Inline Datepicker', () => {
77

88
beforeEach(() => {
99
datepicker.navigateTo();
10-
datepicker.scrollToMenu('Inline Datepicker');
10+
datepicker.scrollToMenu('Inline');
1111
});
1212

1313
it(`example contains Datepicker with selected date (Today)`, () => {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
NgApiDocConfigComponent
4242
} from '../../docs/api-docs';
4343

44+
4445
export const demoComponentContent: ContentSection[] = [
4546
{
4647
name: 'Usage',
@@ -76,7 +77,7 @@ export const demoComponentContent: ContentSection[] = [
7677
outlet: DemoDatepickerBasicComponent
7778
},
7879
{
79-
title: 'Inline Datepicker',
80+
title: 'Inline',
8081
anchor: 'inline-datepicker',
8182
component: require('!!raw-loader!./demos/inline-datepicker/inline-datepicker.component.ts'),
8283
html: require('!!raw-loader!./demos/inline-datepicker/inline-datepicker.component.html'),

demo/src/app/components/+datepicker/demo-datepicker.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import { RouterModule } from '@angular/router';
55

66
import { defineLocale, LocaleData } from 'ngx-bootstrap/chronos';
77
import { BsDatepickerModule, DatepickerModule } from 'ngx-bootstrap/datepicker';
8+
89
import {
910
arLocale, bgLocale, caLocale, csLocale, daLocale, deLocale, enGbLocale, esDoLocale, esLocale, esUsLocale, etLocale, frLocale, heLocale,
1011
hiLocale, fiLocale, glLocale, huLocale, idLocale, itLocale, jaLocale, koLocale, ltLocale, mnLocale, nbLocale,
1112
nlBeLocale, nlLocale, plLocale, ptBrLocale, ruLocale, roLocale, skLocale, slLocale, svLocale, thLocale, trLocale, viLocale,
1213
zhCnLocale
1314
} from 'ngx-bootstrap/locale';
15+
1416
import { TabsModule } from 'ngx-bootstrap/tabs';
1517

1618
import { DocsModule } from '../../docs';
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<div class="row">
2-
<div class="col-xs-12 col-12 col-md-4 form-group">
2+
<div class="pr-3 pb-3">
33
<bs-datepicker-inline [bsValue]="bsInlineValue"></bs-datepicker-inline>
44
</div>
5+
<div class="pr-3 pb-3">
6+
<bs-daterangepicker-inline [bsValue]="bsInlineRangeValue"></bs-daterangepicker-inline>
7+
</div>
58
</div>

demo/src/app/components/+datepicker/demos/inline-datepicker/inline-datepicker.component.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,11 @@ import { Component } from '@angular/core';
66
})
77
export class DemoDatepickerInlineComponent {
88
bsInlineValue = new Date();
9+
bsInlineRangeValue: Date[];
10+
maxDate = new Date();
11+
12+
constructor() {
13+
this.maxDate.setDate(this.maxDate.getDate() + 7);
14+
this.bsInlineRangeValue = [this.bsInlineValue, this.maxDate];
15+
}
916
}

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ import {
22
ComponentRef, Directive, ElementRef, EventEmitter, Input, OnChanges,
33
OnDestroy, OnInit, Output, Renderer2, SimpleChanges, ViewContainerRef
44
} from '@angular/core';
5+
56
import { ComponentLoader, ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
6-
import { BsDatepickerInlineContainerComponent } from './themes/bs/bs-datepicker-inline-container.component';
7+
78
import { Subscription } from 'rxjs';
8-
import { BsDatepickerInlineConfig } from './bs-datepicker-inline.config';
9+
910
import { BsDatepickerConfig } from './bs-datepicker.config';
11+
import { BsDatepickerInlineConfig } from './bs-datepicker-inline.config';
12+
import { BsDatepickerInlineContainerComponent } from './themes/bs/bs-datepicker-inline-container.component';
1013
import { DatepickerDateCustomClasses } from './models';
1114

1215
@Directive({
@@ -61,11 +64,13 @@ export class BsDatepickerInlineDirective implements OnInit, OnDestroy, OnChanges
6164
private _datepicker: ComponentLoader<BsDatepickerInlineContainerComponent>;
6265
private _datepickerRef: ComponentRef<BsDatepickerInlineContainerComponent>;
6366

64-
constructor(public _config: BsDatepickerInlineConfig,
65-
private _elementRef: ElementRef,
66-
_renderer: Renderer2,
67-
_viewContainerRef: ViewContainerRef,
68-
cis: ComponentLoaderFactory) {
67+
constructor(
68+
public _config: BsDatepickerInlineConfig,
69+
private _elementRef: ElementRef,
70+
_renderer: Renderer2,
71+
_viewContainerRef: ViewContainerRef,
72+
cis: ComponentLoaderFactory
73+
) {
6974
// todo: assign only subset of fields
7075
Object.assign(this, this._config);
7176
this._datepicker = cis.createLoader<BsDatepickerInlineContainerComponent>(

src/datepicker/bs-datepicker.module.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,61 +9,66 @@ 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+
1213
import { BsDatepickerInlineDirective } from './bs-datepicker-inline.component';
1314
import { BsDatepickerInlineConfig } from './bs-datepicker-inline.config';
1415

1516
import { BsLocaleService } from './bs-locale.service';
1617
import { BsDatepickerActions } from './reducer/bs-datepicker.actions';
1718
import { BsDatepickerEffects } from './reducer/bs-datepicker.effects';
1819
import { BsDatepickerStore } from './reducer/bs-datepicker.store';
20+
import { BsDatepickerContainerComponent } from './themes/bs/bs-datepicker-container.component';
21+
import { BsDaterangepickerContainerComponent } from './themes/bs/bs-daterangepicker-container.component';
22+
23+
import { BsDatepickerInlineContainerComponent } from './themes/bs/bs-datepicker-inline-container.component';
24+
import { BsDaterangepickerInlineContainerComponent } from './themes/bs/bs-daterangepicker-inline-container.component';
25+
26+
import { BsDaterangepickerInlineDirective } from './bs-daterangepicker-inline.component';
27+
import { BsDaterangepickerInlineConfig } from './bs-daterangepicker-inline.config';
28+
1929
import { BsCalendarLayoutComponent } from './themes/bs/bs-calendar-layout.component';
2030
import { BsCurrentDateViewComponent } from './themes/bs/bs-current-date-view.component';
2131
import { BsCustomDatesViewComponent } from './themes/bs/bs-custom-dates-view.component';
22-
import { BsDatepickerContainerComponent } from './themes/bs/bs-datepicker-container.component';
2332
import { BsDatepickerDayDecoratorComponent } from './themes/bs/bs-datepicker-day-decorator.directive';
2433
import { BsDatepickerNavigationViewComponent } from './themes/bs/bs-datepicker-navigation-view.component';
25-
import { BsDaterangepickerContainerComponent } from './themes/bs/bs-daterangepicker-container.component';
2634
import { BsDaysCalendarViewComponent } from './themes/bs/bs-days-calendar-view.component';
2735
import { BsMonthCalendarViewComponent } from './themes/bs/bs-months-calendar-view.component';
2836
import { BsTimepickerViewComponent } from './themes/bs/bs-timepicker-view.component';
2937
import { BsYearsCalendarViewComponent } from './themes/bs/bs-years-calendar-view.component';
30-
import { BsDatepickerInlineContainerComponent } from './themes/bs/bs-datepicker-inline-container.component';
3138

3239
const _exports = [
3340
BsDatepickerContainerComponent,
34-
BsDaterangepickerContainerComponent,
35-
BsDatepickerInlineContainerComponent,
36-
3741
BsDatepickerDirective,
42+
BsDatepickerInlineContainerComponent,
43+
BsDatepickerInlineDirective,
3844
BsDatepickerInputDirective,
39-
40-
BsDaterangepickerInputDirective,
45+
BsDaterangepickerContainerComponent,
4146
BsDaterangepickerDirective,
42-
43-
BsDatepickerInlineDirective
47+
BsDaterangepickerInlineContainerComponent,
48+
BsDaterangepickerInlineDirective,
49+
BsDaterangepickerInputDirective
4450
];
4551

4652
@NgModule({
4753
imports: [CommonModule],
4854
declarations: [
49-
BsDatepickerDayDecoratorComponent,
55+
BsCalendarLayoutComponent,
5056
BsCurrentDateViewComponent,
57+
BsCustomDatesViewComponent,
58+
BsDatepickerDayDecoratorComponent,
5159
BsDatepickerNavigationViewComponent,
52-
BsTimepickerViewComponent,
53-
54-
BsCalendarLayoutComponent,
5560
BsDaysCalendarViewComponent,
5661
BsMonthCalendarViewComponent,
62+
BsTimepickerViewComponent,
5763
BsYearsCalendarViewComponent,
5864

59-
BsCustomDatesViewComponent,
60-
6165
..._exports
6266
],
6367
entryComponents: [
6468
BsDatepickerContainerComponent,
6569
BsDaterangepickerContainerComponent,
66-
BsDatepickerInlineContainerComponent
70+
BsDatepickerInlineContainerComponent,
71+
BsDaterangepickerInlineContainerComponent
6772
],
6873
exports: _exports
6974
})
@@ -79,6 +84,7 @@ export class BsDatepickerModule {
7984
BsDatepickerConfig,
8085
BsDaterangepickerConfig,
8186
BsDatepickerInlineConfig,
87+
BsDaterangepickerInlineConfig,
8288
BsDatepickerEffects,
8389
BsLocaleService
8490
]
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import {
2+
ComponentRef, Directive, ElementRef, EventEmitter, Input, OnChanges,
3+
OnDestroy, OnInit, Output, Renderer2, SimpleChanges, ViewContainerRef
4+
} from '@angular/core';
5+
6+
import { ComponentLoader, ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
7+
8+
import { Subscription } from 'rxjs';
9+
import { filter } from 'rxjs/operators';
10+
11+
import { BsDatepickerConfig } from './bs-datepicker.config';
12+
import { BsDaterangepickerInlineConfig } from './bs-daterangepicker-inline.config';
13+
import { BsDaterangepickerInlineContainerComponent } from './themes/bs/bs-daterangepicker-inline-container.component';
14+
import { DatepickerDateCustomClasses } from './models';
15+
16+
@Directive({
17+
selector: 'bs-daterangepicker-inline',
18+
exportAs: 'bsDaterangepickerInline'
19+
})
20+
export class BsDaterangepickerInlineDirective implements OnInit, OnDestroy, OnChanges {
21+
_bsValue: Date[];
22+
/**
23+
* Initial value of datepicker
24+
*/
25+
@Input()
26+
set bsValue(value: Date[]) {
27+
if (this._bsValue === value) {
28+
return;
29+
}
30+
this._bsValue = value;
31+
this.bsValueChange.emit(value);
32+
}
33+
34+
/**
35+
* Config object for datepicker
36+
*/
37+
@Input() bsConfig: Partial<BsDaterangepickerInlineConfig>;
38+
/**
39+
* Indicates whether datepicker is enabled or not
40+
*/
41+
@Input() isDisabled: boolean;
42+
/**
43+
* Minimum date which is available for selection
44+
*/
45+
@Input() minDate: Date;
46+
/**
47+
* Maximum date which is available for selection
48+
*/
49+
@Input() maxDate: Date;
50+
/**
51+
* Date custom classes
52+
*/
53+
@Input() dateCustomClasses: DatepickerDateCustomClasses[];
54+
/**
55+
* Disable specific dates
56+
*/
57+
@Input() datesDisabled: Date[];
58+
/**
59+
* Emits when daterangepicker value has been changed
60+
*/
61+
@Output() bsValueChange: EventEmitter<Date[]> = new EventEmitter();
62+
63+
protected _subs: Subscription[] = [];
64+
65+
private _datepicker: ComponentLoader<BsDaterangepickerInlineContainerComponent>;
66+
private _datepickerRef: ComponentRef<BsDaterangepickerInlineContainerComponent>;
67+
68+
constructor(
69+
public _config: BsDaterangepickerInlineConfig,
70+
private _elementRef: ElementRef,
71+
_renderer: Renderer2,
72+
_viewContainerRef: ViewContainerRef,
73+
cis: ComponentLoaderFactory
74+
) {
75+
// todo: assign only subset of fields
76+
Object.assign(this, this._config);
77+
this._datepicker = cis.createLoader<BsDaterangepickerInlineContainerComponent>(
78+
_elementRef,
79+
_viewContainerRef,
80+
_renderer
81+
);
82+
}
83+
84+
ngOnInit(): void {
85+
this.setConfig();
86+
87+
this._datepickerRef = this._datepicker
88+
.provide({ provide: BsDatepickerConfig, useValue: this._config })
89+
.attach(BsDaterangepickerInlineContainerComponent)
90+
.to(this._elementRef)
91+
.show();
92+
93+
// if date changes from external source (model -> view)
94+
this._subs.push(
95+
this.bsValueChange.subscribe((value: Date[]) => {
96+
this._datepickerRef.instance.value = value;
97+
})
98+
);
99+
100+
// if date changes from picker (view -> model)
101+
this._subs.push(
102+
this._datepickerRef.instance.valueChange
103+
.pipe(
104+
filter((range: Date[]) => range && range[0] && !!range[1])
105+
)
106+
.subscribe((value: Date[]) => {
107+
this.bsValue = value;
108+
})
109+
);
110+
}
111+
112+
ngOnChanges(changes: SimpleChanges): void {
113+
if (!this._datepickerRef || !this._datepickerRef.instance) {
114+
return;
115+
}
116+
117+
if (changes.minDate) {
118+
this._datepickerRef.instance.minDate = this.minDate;
119+
}
120+
121+
if (changes.maxDate) {
122+
this._datepickerRef.instance.maxDate = this.maxDate;
123+
}
124+
125+
if (changes.datesDisabled) {
126+
this._datepickerRef.instance.datesDisabled = this.datesDisabled;
127+
}
128+
129+
if (changes.isDisabled) {
130+
this._datepickerRef.instance.isDisabled = this.isDisabled;
131+
}
132+
133+
if (changes.dateCustomClasses) {
134+
this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
135+
}
136+
}
137+
138+
/**
139+
* Set config for datepicker
140+
*/
141+
setConfig(): void {
142+
this._config = Object.assign({}, this._config, this.bsConfig, {
143+
value: this._bsValue,
144+
isDisabled: this.isDisabled,
145+
minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
146+
maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
147+
dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
148+
datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled
149+
});
150+
}
151+
152+
ngOnDestroy(): any {
153+
this._datepicker.dispose();
154+
}
155+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Injectable } from '@angular/core';
2+
import { BsDatepickerConfig } from './bs-datepicker.config';
3+
4+
@Injectable()
5+
export class BsDaterangepickerInlineConfig extends BsDatepickerConfig {
6+
// DatepickerRenderOptions
7+
displayMonths = 2;
8+
/** turn on/off animation */
9+
isAnimated = false;
10+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Component, ViewChild } from '@angular/core';
2+
import { BsDaterangepickerInlineDirective, BsDaterangepickerInlineConfig, BsDatepickerModule } from '.';
3+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
4+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
5+
6+
7+
@Component({
8+
selector: 'test-cmp',
9+
template: `<bs-daterangepicker-inline [bsConfig]="bsConfig"></bs-daterangepicker-inline>`
10+
})
11+
class TestComponent {
12+
@ViewChild(BsDaterangepickerInlineDirective, { static: false }) daterangepicker: BsDaterangepickerInlineDirective;
13+
bsConfig: Partial<BsDaterangepickerInlineConfig> = {
14+
customTodayClass: 'custom-today-class'
15+
};
16+
}
17+
18+
type TestFixture = ComponentFixture<TestComponent>;
19+
20+
describe('daterangepicker inline:', () => {
21+
let fixture: TestFixture;
22+
beforeEach(
23+
async(() => TestBed.configureTestingModule({
24+
declarations: [TestComponent],
25+
imports: [
26+
BsDatepickerModule.forRoot(),
27+
BrowserAnimationsModule
28+
]
29+
}).compileComponents()
30+
));
31+
beforeEach(() => {
32+
fixture = TestBed.createComponent(TestComponent);
33+
fixture.detectChanges();
34+
});
35+
});

0 commit comments

Comments
 (0)