Skip to content

Commit

Permalink
feat(datepicker): add config service to provide default values
Browse files Browse the repository at this point in the history
refs #518

Closes #677
  • Loading branch information
jnizet authored and icfantv committed Sep 5, 2016
1 parent 720c409 commit 42002d9
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 11 deletions.
6 changes: 6 additions & 0 deletions demo/src/app/components/datepicker/datepicker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@ import {DEMO_SNIPPETS} from './demos';
<ngbd-content-wrapper component="Datepicker">
<ngbd-api-docs directive="NgbDatepicker"></ngbd-api-docs>
<ngbd-api-docs-class type="DayTemplateContext"></ngbd-api-docs-class>
<ngbd-api-docs-config type="NgbDatepickerConfig"></ngbd-api-docs-config>
<ngbd-example-box demoTitle="Basic datepicker" [htmlSnippet]="snippets.basic.markup" [tsSnippet]="snippets.basic.code">
<ngbd-datepicker-basic></ngbd-datepicker-basic>
</ngbd-example-box>
<ngbd-example-box demoTitle="Global configuration of datepickers"
[htmlSnippet]="snippets.config.markup"
[tsSnippet]="snippets.config.code">
<ngbd-datepicker-config></ngbd-datepicker-config>
</ngbd-example-box>
</ngbd-content-wrapper>
`
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<p>This datepicker uses customized default values.</p>

<ngb-datepicker [(ngModel)]="model"></ngb-datepicker>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {Component} from '@angular/core';
import {NgbDatepickerConfig} from '@ng-bootstrap/ng-bootstrap';

@Component({
selector: 'ngbd-datepicker-config',
templateUrl: './datepicker-config.html',
providers: [NgbDatepickerConfig] // add NgbDatepickerConfig to the component providers
})
export class NgbdDatepickerConfig {

model;

constructor(config: NgbDatepickerConfig) {
// customize default values of datepickers used by this component tree
config.minDate = {year: 1900, month: 0, day: 1};
config.maxDate = {year: 2099, month: 11, day: 31};

// weekends are disabled
config.markDisabled = (date: {year: number, month: number, day: number}) => {
const d = new Date(date.year, date.month, date.day);
return d.getDay() === 0 || d.getDay() === 6;
};
}
}
10 changes: 8 additions & 2 deletions demo/src/app/components/datepicker/demos/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import {NgbdDatepickerBasic} from './basic/datepicker-basic';
import {NgbdDatepickerConfig} from './config/datepicker-config';

export const DEMO_DIRECTIVES = [NgbdDatepickerBasic];
export const DEMO_DIRECTIVES = [NgbdDatepickerBasic, NgbdDatepickerConfig];

export const DEMO_SNIPPETS = {
basic: {
code: require('!!prismjs?lang=typescript!./basic/datepicker-basic'),
markup: require('!!prismjs?lang=markup!./basic/datepicker-basic.html')}
markup: require('!!prismjs?lang=markup!./basic/datepicker-basic.html')
},
config: {
code: require('!!prismjs?lang=typescript!./config/datepicker-config'),
markup: require('!!prismjs?lang=markup!./config/datepicker-config.html')
}
};
2 changes: 1 addition & 1 deletion demo/src/app/components/datepicker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ import {DEMO_DIRECTIVES} from './demos';
@NgModule({
imports: [NgbdSharedModule, NgbdComponentsSharedModule],
exports: [NgbdDatepicker],
declarations: [NgbdDatepicker, ...DEMO_DIRECTIVES]
declarations: [NgbdDatepicker, ...DEMO_DIRECTIVES],
})
export class NgbdDatepickerModule {}
17 changes: 17 additions & 0 deletions src/datepicker/datepicker-config.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {NgbDatepickerConfig} from './datepicker-config';

describe('ngb-datepicker-config', () => {
it('should have sensible default values', () => {
const config = new NgbDatepickerConfig();

expect(config.dayTemplate).toBeUndefined();
expect(config.firstDayOfWeek).toBe(1);
expect(config.markDisabled).toBeUndefined();
expect(config.minDate).toBeUndefined();
expect(config.maxDate).toBeUndefined();
expect(config.showNavigation).toBe(true);
expect(config.showWeekdays).toBe(true);
expect(config.showWeekNumbers).toBe(false);
expect(config.startDate).toBeUndefined();
});
});
20 changes: 20 additions & 0 deletions src/datepicker/datepicker-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {Injectable, TemplateRef} from '@angular/core';
import {DayTemplateContext} from './datepicker-day-template-context';

/**
* Configuration service for the 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 datepickers used in the application.
*/
@Injectable()
export class NgbDatepickerConfig {
dayTemplate: TemplateRef<DayTemplateContext>;
firstDayOfWeek = 1;
markDisabled: (date: {year: number, month: number, day: number}) => boolean;
minDate: {year: number, month: number, day: number};
maxDate: {year: number, month: number, day: number};
showNavigation = true;
showWeekdays = true;
showWeekNumbers = false;
startDate: {year: number, month: number};
}
5 changes: 4 additions & 1 deletion src/datepicker/datepicker.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import {NgbDatepickerI18n, NgbDatepickerI18nDefault} from './datepicker-i18n';
import {NgbCalendar, NgbCalendarGregorian} from './ngb-calendar';
import {NgbDatepickerService} from './datepicker-service';
import {NgbDatepickerNavigationSelect} from './datepicker-navigation-select';
import {NgbDatepickerConfig} from './datepicker-config';

export {NgbDatepickerConfig} from './datepicker-config';

@NgModule({
declarations: [
Expand All @@ -18,7 +21,7 @@ import {NgbDatepickerNavigationSelect} from './datepicker-navigation-select';
imports: [CommonModule, FormsModule],
providers: [
{provide: NgbCalendar, useClass: NgbCalendarGregorian},
{provide: NgbDatepickerI18n, useClass: NgbDatepickerI18nDefault}, NgbDatepickerService
{provide: NgbDatepickerI18n, useClass: NgbDatepickerI18nDefault}, NgbDatepickerService, NgbDatepickerConfig
]
})
export class NgbDatepickerModule {
Expand Down
71 changes: 69 additions & 2 deletions src/datepicker/datepicker.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import {TestBed, ComponentFixture, async} from '@angular/core/testing';
import {TestBed, ComponentFixture, async, inject} from '@angular/core/testing';
import {createGenericTestComponent} from '../test/common';
import {getMonthSelect, getYearSelect, getNavigationLinks} from '../test/datepicker/common';

import {Component} from '@angular/core';
import {Component, TemplateRef} from '@angular/core';
import {FormsModule, ReactiveFormsModule, FormGroup, FormControl, Validators} from '@angular/forms';

import {NgbDatepickerModule} from './datepicker.module';
import {NgbDate} from './ngb-date';
import {NgbDatepickerConfig} from './datepicker-config';
import {NgbDatepicker} from './datepicker';
import {DayTemplateContext} from './datepicker-day-template-context';

const createTestComponent = (html: string) =>
createGenericTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
Expand All @@ -23,13 +26,43 @@ function getDatepicker(element: HTMLElement): HTMLElement {
return element.querySelector('ngb-datepicker') as HTMLElement;
}

function expectSameValues(datepicker: NgbDatepicker, config: NgbDatepickerConfig) {
expect(datepicker.dayTemplate).toBe(config.dayTemplate);
expect(datepicker.firstDayOfWeek).toBe(config.firstDayOfWeek);
expect(datepicker.markDisabled).toBe(config.markDisabled);
expect(datepicker.minDate).toBe(config.minDate);
expect(datepicker.maxDate).toBe(config.maxDate);
expect(datepicker.showNavigation).toBe(config.showNavigation);
expect(datepicker.showWeekdays).toBe(config.showWeekdays);
expect(datepicker.showWeekNumbers).toBe(config.showWeekNumbers);
expect(datepicker.startDate).toBe(config.startDate);
}

function customizeConfig(config: NgbDatepickerConfig) {
config.dayTemplate = {} as TemplateRef<DayTemplateContext>;
config.firstDayOfWeek = 2;
config.markDisabled = (date) => false;
config.minDate = {year: 2000, month: 0, day: 1};
config.maxDate = {year: 2030, month: 11, day: 31};
config.showNavigation = false;
config.showWeekdays = false;
config.showWeekNumbers = true;
config.startDate = {year: 2015, month: 1};
}

describe('ngb-datepicker', () => {

beforeEach(() => {
TestBed.configureTestingModule(
{declarations: [TestComponent], imports: [NgbDatepickerModule, FormsModule, ReactiveFormsModule]});
});

it('should initialize inputs with provided config', () => {
const defaultConfig = new NgbDatepickerConfig();
const datepicker = TestBed.createComponent(NgbDatepicker).componentInstance;
expectSameValues(datepicker, defaultConfig);
});

it('should display current month if no date provided', () => {
const fixture = createTestComponent(`<ngb-datepicker></ngb-datepicker>`);

Expand Down Expand Up @@ -250,6 +283,40 @@ describe('ngb-datepicker', () => {
}));
});

describe('Custom config', () => {
let config: NgbDatepickerConfig;

beforeEach(() => { TestBed.configureTestingModule({imports: [NgbDatepickerModule]}); });

beforeEach(inject([NgbDatepickerConfig], (c: NgbDatepickerConfig) => {
config = c;
customizeConfig(config);
}));

it('should initialize inputs with provided config', () => {
const fixture = TestBed.createComponent(NgbDatepicker);

const datepicker = fixture.componentInstance;
expectSameValues(datepicker, config);
});
});

describe('Custom config as provider', () => {
const config = new NgbDatepickerConfig();
customizeConfig(config);

beforeEach(() => {
TestBed.configureTestingModule(
{imports: [NgbDatepickerModule], providers: [{provide: NgbDatepickerConfig, useValue: config}]});
});

it('should initialize inputs with provided config as provider', () => {
const fixture = createGenericTestComponent('', NgbDatepicker);

const datepicker = fixture.componentInstance;
expectSameValues(datepicker, config);
});
});
});

@Component({selector: 'test-cmp', template: ''})
Expand Down
21 changes: 16 additions & 5 deletions src/datepicker/datepicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {NgbDatepickerService} from './datepicker-service';
import {MonthViewModel, NavigationEvent} from './datepicker-view-model';
import {toInteger} from '../util/util';
import {DayTemplateContext} from './datepicker-day-template-context';
import {NgbDatepickerConfig} from './datepicker-config';

const NGB_DATEPICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
Expand Down Expand Up @@ -63,7 +64,7 @@ export class NgbDatepicker implements OnChanges,
/**
* First day of the week, 0=Sun, 1=Mon, etc.
*/
@Input() firstDayOfWeek = 1;
@Input() firstDayOfWeek: number;

/**
* Callback to mark a given date as disabled
Expand All @@ -83,17 +84,17 @@ export class NgbDatepicker implements OnChanges,
/**
* Whether to display navigation or not
*/
@Input() showNavigation = true;
@Input() showNavigation: boolean;

/**
* Whether to display days of the week
*/
@Input() showWeekdays = true;
@Input() showWeekdays: boolean;

/**
* Whether to display week numbers
*/
@Input() showWeekNumbers = false;
@Input() showWeekNumbers: boolean;

/**
* Date to open calendar with. If nothing provided, calendar will open with current month.
Expand All @@ -104,7 +105,17 @@ export class NgbDatepicker implements OnChanges,
onChange = (_: any) => {};
onTouched = () => {};

constructor(private _service: NgbDatepickerService, private _calendar: NgbCalendar) {}
constructor(private _service: NgbDatepickerService, private _calendar: NgbCalendar, config: NgbDatepickerConfig) {
this.dayTemplate = config.dayTemplate;
this.firstDayOfWeek = config.firstDayOfWeek;
this.markDisabled = config.markDisabled;
this.minDate = config.minDate;
this.maxDate = config.maxDate;
this.showNavigation = config.showNavigation;
this.showWeekdays = config.showWeekdays;
this.showWeekNumbers = config.showWeekNumbers;
this.startDate = config.startDate;
}

/**
* Navigates current view to provided date. If nothing provided calendar will open current month.
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export {NgbModal, NgbModalOptions, NgbModalRef, ModalDismissReasons} from './mod
export {NgbTabChangeEvent} from './tabset/tabset.module';
export {NgbAlertConfig, NgbSelfClosingAlertConfig} from './alert/alert.module';
export {NgbCarouselConfig} from './carousel/carousel.module';
export {NgbDatepickerConfig} from './datepicker/datepicker.module';
export {NgbPaginationConfig} from './pagination/pagination.module';
export {NgbProgressbarConfig} from './progressbar/progressbar.module';
export {NgbRatingConfig} from './rating/rating.module';
Expand Down

0 comments on commit 42002d9

Please sign in to comment.