diff --git a/demo/src/app/components/datepicker/demos/config/datepicker-config.html b/demo/src/app/components/datepicker/demos/config/datepicker-config.html
index 83d2f3064e..7c550c3532 100644
--- a/demo/src/app/components/datepicker/demos/config/datepicker-config.html
+++ b/demo/src/app/components/datepicker/demos/config/datepicker-config.html
@@ -1,3 +1,13 @@
-
This datepicker uses customized default values.
+This datepicker input uses customized default values.
-
+
diff --git a/demo/src/app/components/datepicker/demos/config/datepicker-config.ts b/demo/src/app/components/datepicker/demos/config/datepicker-config.ts
index d03851b3ea..d3e71225ee 100644
--- a/demo/src/app/components/datepicker/demos/config/datepicker-config.ts
+++ b/demo/src/app/components/datepicker/demos/config/datepicker-config.ts
@@ -1,5 +1,11 @@
import {Component} from '@angular/core';
-import {NgbDatepickerConfig, NgbCalendar, NgbDate, NgbDateStruct} from '@ng-bootstrap/ng-bootstrap';
+import {
+ NgbDatepickerConfig,
+ NgbCalendar,
+ NgbDate,
+ NgbDateStruct,
+ NgbInputDatepickerConfig
+} from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'ngbd-datepicker-config',
@@ -10,15 +16,22 @@ export class NgbdDatepickerConfig {
model: NgbDateStruct;
- constructor(config: NgbDatepickerConfig, calendar: NgbCalendar) {
+ constructor(
+ datepickerConfig: NgbDatepickerConfig, inputDatepickerConfig: NgbInputDatepickerConfig, calendar: NgbCalendar) {
// customize default values of datepickers used by this component tree
- config.minDate = {year: 1900, month: 1, day: 1};
- config.maxDate = {year: 2099, month: 12, day: 31};
+ datepickerConfig.minDate = {year: 1900, month: 1, day: 1};
+ datepickerConfig.maxDate = {year: 2099, month: 12, day: 31};
// days that don't belong to current month are not visible
- config.outsideDays = 'hidden';
+ datepickerConfig.outsideDays = 'hidden';
// weekends are disabled
- config.markDisabled = (date: NgbDate) => calendar.getWeekday(date) >= 6;
+ datepickerConfig.markDisabled = (date: NgbDate) => calendar.getWeekday(date) >= 6;
+
+ // setting datepicker popup to close only on click outside
+ inputDatepickerConfig.autoClose = 'outside';
+
+ // setting datepicker popup to open above the input
+ inputDatepickerConfig.placement = ['top-left', 'top-right'];
}
}
diff --git a/src/datepicker/datepicker-input-config.spec.ts b/src/datepicker/datepicker-input-config.spec.ts
new file mode 100644
index 0000000000..7df4346ada
--- /dev/null
+++ b/src/datepicker/datepicker-input-config.spec.ts
@@ -0,0 +1,12 @@
+import {NgbInputDatepickerConfig} from './datepicker-input-config';
+
+describe('NgbInputDatepickerConfig', () => {
+ it('should have sensible default values', () => {
+ const config = new NgbInputDatepickerConfig();
+
+ expect(config.autoClose).toBe(true);
+ expect(config.container).toBeUndefined();
+ expect(config.positionTarget).toBeUndefined();
+ expect(config.placement).toEqual(['bottom-left', 'bottom-right', 'top-left', 'top-right']);
+ });
+});
diff --git a/src/datepicker/datepicker-input-config.ts b/src/datepicker/datepicker-input-config.ts
new file mode 100644
index 0000000000..4366b7389e
--- /dev/null
+++ b/src/datepicker/datepicker-input-config.ts
@@ -0,0 +1,17 @@
+import {Injectable} from '@angular/core';
+
+import {PlacementArray} from '../util/positioning';
+
+/**
+ * A configuration service for the [`NgbDatepickerInput`](#/components/datepicker/api#NgbDatepicker) component.
+ *
+ * You can inject this service, typically in your root component, and customize the values of its properties in
+ * order to provide default values for all the datepicker inputs used in the application.
+ */
+@Injectable({providedIn: 'root'})
+export class NgbInputDatepickerConfig {
+ autoClose: boolean | 'inside' | 'outside' = true;
+ container: null | 'body';
+ positionTarget: string | HTMLElement;
+ placement: PlacementArray = ['bottom-left', 'bottom-right', 'top-left', 'top-right'];
+}
diff --git a/src/datepicker/datepicker-input.spec.ts b/src/datepicker/datepicker-input.spec.ts
index 910bd1d55f..437b87986c 100644
--- a/src/datepicker/datepicker-input.spec.ts
+++ b/src/datepicker/datepicker-input.spec.ts
@@ -11,6 +11,7 @@ import {NgbDatepicker} from './datepicker';
import {NgbDateStruct} from './ngb-date-struct';
import {NgbDate} from './ngb-date';
import * as positioning from 'src/util/positioning';
+import {NgbInputDatepickerConfig} from './datepicker-input-config';
const createTestCmpt = (html: string) =>
createGenericTestComponent(html, TestComponent) as ComponentFixture;
@@ -18,12 +19,64 @@ const createTestCmpt = (html: string) =>
const createTestNativeCmpt = (html: string) =>
createGenericTestComponent(html, TestNativeComponent) as ComponentFixture;
+function expectSameValues(inputDatepicker: NgbInputDatepicker, config: NgbInputDatepickerConfig) {
+ ['autoClose', 'container', 'positionTarget', 'placement'].forEach(
+ field => expect(inputDatepicker[field]).toEqual(config[field], field));
+}
+
+function customizeConfig(config: NgbInputDatepickerConfig) {
+ config.autoClose = 'outside';
+ config.container = 'body';
+ config.positionTarget = 'positionTarget';
+ config.placement = ['bottom-left', 'top-right'];
+}
+
describe('NgbInputDatepicker', () => {
beforeEach(() => {
TestBed.configureTestingModule({declarations: [TestComponent], imports: [NgbDatepickerModule, FormsModule]});
});
+ it('should initialize inputs with provided datepicker config', () => {
+ const defaultConfig = new NgbInputDatepickerConfig();
+ const fixture = createTestCmpt(``);
+
+ const inputDatepicker =
+ fixture.debugElement.query(By.directive(NgbInputDatepicker)).injector.get(NgbInputDatepicker);
+ expectSameValues(inputDatepicker, defaultConfig);
+ });
+
+ it('should initialize inputs with provided config', () => {
+ // overrideComponent should happen before any injections, so createTestCmpt will fail here
+ TestBed.overrideComponent(TestComponent, {set: {template: ''}});
+ const config = TestBed.get(NgbInputDatepickerConfig);
+ customizeConfig(config);
+ const fixture = TestBed.createComponent(TestComponent);
+ fixture.detectChanges();
+
+ const inputDatepicker =
+ fixture.debugElement.query(By.directive(NgbInputDatepicker)).injector.get(NgbInputDatepicker);
+ expectSameValues(inputDatepicker, config);
+ });
+
+ describe('Custom config as provider', () => {
+ const config = new NgbInputDatepickerConfig();
+ customizeConfig(config);
+
+ beforeEach(() => {
+ TestBed.configureTestingModule(
+ {imports: [NgbDatepickerModule], providers: [{provide: NgbInputDatepickerConfig, useValue: config}]});
+ });
+
+ it('should initialize inputs with provided config as provider', () => {
+ const fixture = createTestCmpt(``);
+
+ const inputDatepicker =
+ fixture.debugElement.query(By.directive(NgbInputDatepicker)).injector.get(NgbInputDatepicker);
+ expectSameValues(inputDatepicker, config);
+ });
+ });
+
describe('open, close and toggle', () => {
it('should allow controlling datepicker popup from outside', () => {
diff --git a/src/datepicker/datepicker-input.ts b/src/datepicker/datepicker-input.ts
index 2cabfdabce..be9366e618 100644
--- a/src/datepicker/datepicker-input.ts
+++ b/src/datepicker/datepicker-input.ts
@@ -32,6 +32,7 @@ import {NgbCalendar} from './ngb-calendar';
import {NgbDate} from './ngb-date';
import {NgbDateParserFormatter} from './ngb-date-parser-formatter';
import {NgbDateStruct} from './ngb-date-struct';
+import {NgbInputDatepickerConfig} from './datepicker-input-config';
const NGB_DATEPICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
@@ -81,7 +82,7 @@ export class NgbInputDatepicker implements OnChanges,
*
* @since 3.0.0
*/
- @Input() autoClose: boolean | 'inside' | 'outside' = true;
+ @Input() autoClose: boolean | 'inside' | 'outside';
/**
* The reference to a custom template for the day.
@@ -177,7 +178,7 @@ export class NgbInputDatepicker implements OnChanges,
*
* Please see the [positioning overview](#/positioning) for more details.
*/
- @Input() placement: PlacementArray = ['bottom-left', 'bottom-right', 'top-left', 'top-right'];
+ @Input() placement: PlacementArray;
/**
* If `true`, weekdays will be displayed.
@@ -260,7 +261,8 @@ export class NgbInputDatepicker implements OnChanges,
private _vcRef: ViewContainerRef, private _renderer: Renderer2, private _cfr: ComponentFactoryResolver,
private _ngZone: NgZone, private _service: NgbDatepickerService, private _calendar: NgbCalendar,
private _dateAdapter: NgbDateAdapter, @Inject(DOCUMENT) private _document: any,
- private _changeDetector: ChangeDetectorRef) {
+ private _changeDetector: ChangeDetectorRef, config: NgbInputDatepickerConfig) {
+ ['autoClose', 'container', 'positionTarget', 'placement'].forEach(input => this[input] = config[input]);
this._zoneSubscription = _ngZone.onStable.subscribe(() => this._updatePopupPosition());
}
diff --git a/src/datepicker/datepicker.module.ts b/src/datepicker/datepicker.module.ts
index 850f9ee9b3..8feb350a8c 100644
--- a/src/datepicker/datepicker.module.ts
+++ b/src/datepicker/datepicker.module.ts
@@ -21,6 +21,7 @@ export {NgbDatepickerDayView} from './datepicker-day-view';
export {NgbDatepickerNavigation} from './datepicker-navigation';
export {NgbDatepickerNavigationSelect} from './datepicker-navigation-select';
export {NgbDatepickerConfig} from './datepicker-config';
+export {NgbInputDatepickerConfig} from './datepicker-input-config';
export {NgbDatepickerI18n} from './datepicker-i18n';
export {NgbDateStruct} from './ngb-date-struct';
export {NgbDate} from './ngb-date';
diff --git a/src/index.ts b/src/index.ts
index ddc59a1f97..af0d0c98af 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -58,6 +58,7 @@ export {
NgbDateParserFormatter,
NgbDatepicker,
NgbDatepickerConfig,
+ NgbInputDatepickerConfig,
NgbDatepickerI18n,
NgbDatepickerI18nHebrew,
NgbDatepickerKeyboardService,