Skip to content

Commit

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

Closes #674
  • Loading branch information
jnizet authored and icfantv committed Sep 3, 2016
1 parent 8b7047d commit ca40f27
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<p>This timepicker uses customized default values.</p>

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

@Component({
selector: 'ngbd-timepicker-config',
templateUrl: './timepicker-config.html',
providers: [NgbTimepickerConfig] // add NgbTimepickerConfig to the component providers
})
export class NgbdTimepickerConfig {
time = {hour: 13, minute: 30, second: 0};

constructor(config: NgbTimepickerConfig) {
// customize default values of ratings used by this component tree
config.seconds = true;
config.spinners = false;
}
}
29 changes: 21 additions & 8 deletions demo/src/app/components/timepicker/demos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,40 @@ import {NgbdTimepickerSeconds} from './seconds/timepicker-seconds';
import {NgbdTimepickerSteps} from './steps/timepicker-steps';
import {NgbdTimepickerValidation} from './validation/timepicker-validation';
import {NgbdTimepickerSpinners} from './spinners/timepicker-spinners';
import {NgbdTimepickerConfig} from './config/timepicker-config';

export const DEMO_DIRECTIVES = [NgbdTimepickerBasic, NgbdTimepickerMeridian, NgbdTimepickerSeconds,
NgbdTimepickerSpinners, NgbdTimepickerSteps, NgbdTimepickerValidation];
export const DEMO_DIRECTIVES = [
NgbdTimepickerBasic, NgbdTimepickerMeridian, NgbdTimepickerSeconds, NgbdTimepickerSpinners, NgbdTimepickerSteps,
NgbdTimepickerValidation, NgbdTimepickerConfig
];

export const DEMO_SNIPPETS = {
basic: {
code: require('!!prismjs?lang=typescript!./basic/timepicker-basic'),
markup: require('!!prismjs?lang=markup!./basic/timepicker-basic.html')},
markup: require('!!prismjs?lang=markup!./basic/timepicker-basic.html')
},
meridian: {
code: require('!!prismjs?lang=typescript!./meridian/timepicker-meridian'),
markup: require('!!prismjs?lang=markup!./meridian/timepicker-meridian.html')},
markup: require('!!prismjs?lang=markup!./meridian/timepicker-meridian.html')
},
seconds: {
code: require('!!prismjs?lang=typescript!./seconds/timepicker-seconds'),
markup: require('!!prismjs?lang=markup!./seconds/timepicker-seconds.html')},
markup: require('!!prismjs?lang=markup!./seconds/timepicker-seconds.html')
},
spinners: {
code: require('!!prismjs?lang=typescript!./spinners/timepicker-spinners'),
markup: require('!!prismjs?lang=markup!./spinners/timepicker-spinners.html')},
markup: require('!!prismjs?lang=markup!./spinners/timepicker-spinners.html')
},
steps: {
code: require('!!prismjs?lang=typescript!./steps/timepicker-steps'),
markup: require('!!prismjs?lang=markup!./steps/timepicker-steps.html')},
markup: require('!!prismjs?lang=markup!./steps/timepicker-steps.html')
},
validation: {
code: require('!!prismjs?lang=typescript!./validation/timepicker-validation'),
markup: require('!!prismjs?lang=markup!./validation/timepicker-validation.html')}
markup: require('!!prismjs?lang=markup!./validation/timepicker-validation.html')
},
config: {
code: require('!!prismjs?lang=typescript!./config/timepicker-config'),
markup: require('!!prismjs?lang=markup!./config/timepicker-config.html')
}
};
6 changes: 6 additions & 0 deletions demo/src/app/components/timepicker/timepicker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {DEMO_SNIPPETS} from './demos';
template: `
<ngbd-content-wrapper component="Timepicker">
<ngbd-api-docs directive="NgbTimepicker"></ngbd-api-docs>
<ngbd-api-docs-config type="NgbTimepickerConfig"></ngbd-api-docs-config>
<ngbd-example-box demoTitle="Timepicker" [htmlSnippet]="snippets.basic.markup" [tsSnippet]="snippets.basic.code">
<ngbd-timepicker-basic></ngbd-timepicker-basic>
</ngbd-example-box>
Expand All @@ -24,6 +25,11 @@ import {DEMO_SNIPPETS} from './demos';
<ngbd-example-box demoTitle="Custom validation" [htmlSnippet]="snippets.validation.markup" [tsSnippet]="snippets.validation.code">
<ngbd-timepicker-validation></ngbd-timepicker-validation>
</ngbd-example-box>
<ngbd-example-box demoTitle="Global configuration of timepickers"
[htmlSnippet]="snippets.config.markup"
[tsSnippet]="snippets.config.code">
<ngbd-timepicker-config></ngbd-timepicker-config>
</ngbd-example-box>
</ngbd-content-wrapper>
`
})
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export {NgbCarouselConfig} from './carousel/carousel.module';
export {NgbPaginationConfig} from './pagination/pagination.module';
export {NgbProgressbarConfig} from './progressbar/progressbar.module';
export {NgbRatingConfig} from './rating/rating.module';
export {NgbTimepickerConfig} from './timepicker/timepicker.module';

@NgModule({
exports: [
Expand Down
16 changes: 16 additions & 0 deletions src/timepicker/timepicker-config.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {NgbTimepickerConfig} from './timepicker-config';

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

expect(config.meridian).toBe(false);
expect(config.spinners).toBe(true);
expect(config.seconds).toBe(false);
expect(config.hourStep).toBe(1);
expect(config.minuteStep).toBe(1);
expect(config.secondStep).toBe(1);
expect(config.disabled).toBe(false);
expect(config.readonlyInputs).toBe(false);
});
});
18 changes: 18 additions & 0 deletions src/timepicker/timepicker-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {Injectable} from '@angular/core';

/**
* Configuration service for the NgbTimepicker 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 timepickers used in the application.
*/
@Injectable()
export class NgbTimepickerConfig {
meridian = false;
spinners = true;
seconds = false;
hourStep = 1;
minuteStep = 1;
secondStep = 1;
disabled = false;
readonlyInputs = false;
}
10 changes: 9 additions & 1 deletion src/timepicker/timepicker.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';

import {NGB_TIMEPICKER_DIRECTIVES} from './timepicker';
import {NgbTimepickerConfig} from './timepicker-config';

@NgModule({declarations: NGB_TIMEPICKER_DIRECTIVES, exports: NGB_TIMEPICKER_DIRECTIVES, imports: [CommonModule]})
export {NgbTimepickerConfig} from './timepicker-config';

@NgModule({
declarations: NGB_TIMEPICKER_DIRECTIVES,
exports: NGB_TIMEPICKER_DIRECTIVES,
imports: [CommonModule],
providers: [NgbTimepickerConfig]
})
export class NgbTimepickerModule {
}
72 changes: 71 additions & 1 deletion src/timepicker/timepicker.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import {TestBed, ComponentFixture, async} from '@angular/core/testing';
import {TestBed, ComponentFixture, async, inject} from '@angular/core/testing';
import {createGenericTestComponent} from '../util/tests';

import {Component} from '@angular/core';
import {By} from '@angular/platform-browser';
import {Validators, FormControl, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms';

import {NgbTimepickerModule} from './timepicker.module';
import {NgbTimepickerConfig} from './timepicker-config';
import {NgbTimepicker} from './timepicker';

const createTestComponent = (html: string) =>
createGenericTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
Expand Down Expand Up @@ -48,13 +50,43 @@ function expectToDisplayTime(el: HTMLElement, time: string) {
expect(timeInInputs.join(':')).toBe(time);
}

function expectSameValues(timepicker: NgbTimepicker, config: NgbTimepickerConfig) {
expect(timepicker.meridian).toBe(config.meridian);
expect(timepicker.spinners).toBe(config.spinners);
expect(timepicker.seconds).toBe(config.seconds);
expect(timepicker.hourStep).toBe(config.hourStep);
expect(timepicker.minuteStep).toBe(config.minuteStep);
expect(timepicker.secondStep).toBe(config.secondStep);
expect(timepicker.disabled).toBe(config.disabled);
expect(timepicker.readonlyInputs).toBe(config.readonlyInputs);
}

function customizeConfig(config: NgbTimepickerConfig) {
config.meridian = true;
config.spinners = false;
config.seconds = true;
config.hourStep = 2;
config.minuteStep = 3;
config.secondStep = 4;
config.disabled = true;
config.readonlyInputs = true;
}

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

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

describe('initialization', () => {
it('should initialize inputs with provided config', () => {
const defaultConfig = new NgbTimepickerConfig();
const timepicker = new NgbTimepicker(new NgbTimepickerConfig());
expectSameValues(timepicker, defaultConfig);
});
});

describe('rendering based on model', () => {

it('should render hour and minute inputs', async(() => {
Expand Down Expand Up @@ -759,6 +791,44 @@ describe('ngb-timepicker', () => {
expect(buttons.length).toBe(0);
});
});

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

beforeEach(() => {
TestBed.configureTestingModule({imports: [NgbTimepickerModule]});
TestBed.overrideComponent(NgbTimepicker, {set: {template: ''}});
});

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

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

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

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

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

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

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


Expand Down
28 changes: 20 additions & 8 deletions src/timepicker/timepicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';

import {isNumber, padNumber, toInteger} from '../util/util';
import {NgbTime} from './ngb-time';
import {NgbTimepickerConfig} from './timepicker-config';

const NGB_TIMEPICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
Expand Down Expand Up @@ -139,42 +140,53 @@ export class NgbTimepicker implements ControlValueAccessor {
/**
* Whether to display 12H or 24H mode.
*/
@Input() meridian = false;
@Input() meridian: boolean;

/**
* Whether to display the spinners above and below the inputs.
*/
@Input() spinners = true;
@Input() spinners: boolean;

/**
* Whether to display seconds input.
*/
@Input() seconds = false;
@Input() seconds: boolean;

/**
* Number of hours to increase or decrease when using a button.
*/
@Input() hourStep = 1;
@Input() hourStep: number;

/**
* Number of minutes to increase or decrease when using a button.
*/
@Input() minuteStep = 1;
@Input() minuteStep: number;

/**
* Number of seconds to increase or decrease when using a button.
*/
@Input() secondStep = 1;
@Input() secondStep: number;

/**
* To disable timepicker
*/
@Input() disabled = false;
@Input() disabled: boolean;

/**
* To make timepicker readonly
*/
@Input() readonlyInputs = false;
@Input() readonlyInputs: boolean;

constructor(config: NgbTimepickerConfig) {
this.meridian = config.meridian;
this.spinners = config.spinners;
this.seconds = config.seconds;
this.hourStep = config.hourStep;
this.minuteStep = config.minuteStep;
this.secondStep = config.secondStep;
this.disabled = config.disabled;
this.readonlyInputs = config.readonlyInputs;
}

onChange = (_: any) => {};
onTouched = () => {};
Expand Down

0 comments on commit ca40f27

Please sign in to comment.