-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(timepicker): add custom time adapter support
This makes the timepicker consistent with the datepicker, by allowing to use something other than an NgbTimeStruct as the model. fix #545 Closes #2347
- Loading branch information
1 parent
8d54cac
commit 7eaa7e7
Showing
10 changed files
with
277 additions
and
12 deletions.
There are no files selected for viewing
6 changes: 6 additions & 0 deletions
6
demo/src/app/components/timepicker/demos/adapter/timepicker-adapter.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<p>This timepicker uses a custom Time adapter that lets you use your own model implementation. | ||
In this example we are converting from and to an ISO string (with the format <code>HH:mm:ss</code>)</p> | ||
|
||
<ngb-timepicker [(ngModel)]="time"></ngb-timepicker> | ||
<hr> | ||
<pre>Selected time: {{ time }}</pre> |
44 changes: 44 additions & 0 deletions
44
demo/src/app/components/timepicker/demos/adapter/timepicker-adapter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import {Component, Injectable} from '@angular/core'; | ||
import {NgbTimeStruct, NgbTimeAdapter} from '@ng-bootstrap/ng-bootstrap'; | ||
import {NgbDateNativeAdapter} from '../../../datepicker/demos/adapter/datepicker-adapter'; | ||
|
||
/** | ||
* Example of a String Time adapter | ||
*/ | ||
@Injectable() | ||
export class NgbTimeStringAdapter extends NgbTimeAdapter<string> { | ||
|
||
fromModel(value: string): NgbTimeStruct { | ||
if (!value) { | ||
return null; | ||
} | ||
const split = value.split(':'); | ||
return { | ||
hour: parseInt(split[0], 10), | ||
minute: parseInt(split[1], 10), | ||
second: parseInt(split[2], 10) | ||
}; | ||
} | ||
|
||
toModel(time: NgbTimeStruct): string { | ||
if (!time) { | ||
return null; | ||
} | ||
return `${this.pad(time.hour)}:${this.pad(time.minute)}:${this.pad(time.second)}`; | ||
} | ||
|
||
private pad(i: number): string { | ||
return i < 10 ? `0${i}` : `${i}`; | ||
} | ||
} | ||
|
||
@Component({ | ||
selector: 'ngbd-timepicker-adapter', | ||
templateUrl: './timepicker-adapter.html', | ||
// NOTE: For this example we are only providing current component, but probably | ||
// NOTE: you will want to provide your main App Module | ||
providers: [{provide: NgbTimeAdapter, useClass: NgbTimeStringAdapter}] | ||
}) | ||
export class NgbdTimepickerAdapter { | ||
time: '13:30:00'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import {NgbTimeStructAdapter} from './ngb-time-adapter'; | ||
|
||
describe('ngb-time model adapter', () => { | ||
let adapter: NgbTimeStructAdapter; | ||
|
||
beforeEach(() => { adapter = new NgbTimeStructAdapter(); }); | ||
|
||
describe('fromModel', () => { | ||
|
||
it('should convert invalid and incomplete values to null', () => { | ||
expect(adapter.fromModel(null)).toBeNull(); | ||
expect(adapter.fromModel(undefined)).toBeNull(); | ||
expect(adapter.fromModel(<any>'')).toBeNull(); | ||
expect(adapter.fromModel(<any>'s')).toBeNull(); | ||
expect(adapter.fromModel(<any>2)).toBeNull(); | ||
expect(adapter.fromModel(<any>{})).toBeNull(); | ||
expect(adapter.fromModel(<any>new Date())).toBeNull(); | ||
expect(adapter.fromModel(<any>{hour: 20})).toBeNull(); | ||
}); | ||
|
||
it('should convert valid time', () => { | ||
expect(adapter.fromModel({hour: 19, minute: 5, second: 1})).toEqual({hour: 19, minute: 5, second: 1}); | ||
expect(adapter.fromModel(<any>{hour: 19, minute: 5})).toEqual({hour: 19, minute: 5, second: null}); | ||
expect(adapter.fromModel(<any>{hour: 19, minute: 5, second: null})).toEqual({hour: 19, minute: 5, second: null}); | ||
}); | ||
}); | ||
|
||
describe('toModel', () => { | ||
|
||
it('should convert invalid and incomplete values to null', () => { | ||
expect(adapter.toModel(null)).toBeNull(); | ||
expect(adapter.toModel(undefined)).toBeNull(); | ||
expect(adapter.toModel(<any>'')).toBeNull(); | ||
expect(adapter.toModel(<any>'s')).toBeNull(); | ||
expect(adapter.toModel(<any>2)).toBeNull(); | ||
expect(adapter.toModel(<any>{})).toBeNull(); | ||
expect(adapter.toModel(<any>new Date())).toBeNull(); | ||
expect(adapter.toModel(<any>{hour: 20})).toBeNull(); | ||
}); | ||
|
||
it('should convert a valid time', () => { | ||
expect(adapter.toModel({hour: 19, minute: 5, second: 1})).toEqual({hour: 19, minute: 5, second: 1}); | ||
expect(adapter.toModel(<any>{hour: 19, minute: 5})).toEqual({hour: 19, minute: 5, second: null}); | ||
expect(adapter.toModel(<any>{hour: 19, minute: 5, second: null})).toEqual({hour: 19, minute: 5, second: null}); | ||
}); | ||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import {Injectable} from '@angular/core'; | ||
import {NgbTimeStruct} from './ngb-time-struct'; | ||
import {isInteger} from '../util/util'; | ||
|
||
/** | ||
* Abstract type serving as a DI token for the service converting from your application Time model to internal | ||
* NgbTimeStruct model. | ||
* A default implementation converting from and to NgbTimeStruct is provided for retro-compatibility, | ||
* but you can provide another implementation to use an alternative format, ie for using with native Date Object. | ||
*/ | ||
@Injectable() | ||
export abstract class NgbTimeAdapter<T> { | ||
/** | ||
* Converts user-model date into an NgbTimeStruct for internal use in the library | ||
* @param {any} value any value that end user uses as the time model, ie: NgbTimeStruct, Date, "HH:mm:ss" | ||
* @return {NgbTimeStruct} | ||
*/ | ||
abstract fromModel(value: T): NgbTimeStruct; | ||
|
||
/** | ||
* Converts internal time value NgbTimeStruct to user-model date | ||
* The returned type is suposed to be of the same type as fromModel() input-value param | ||
* @param {NgbTimeStruct} time internal NgbTimeStruct date representation | ||
* @return {any} | ||
*/ | ||
abstract toModel(time: NgbTimeStruct): T; | ||
} | ||
|
||
@Injectable() | ||
export class NgbTimeStructAdapter extends NgbTimeAdapter<NgbTimeStruct> { | ||
/** | ||
* Converts a NgbTimeStruct value into NgbTimeStruct value | ||
* @param {NgbTimeStruct} value | ||
* @return {NgbTimeStruct} | ||
*/ | ||
fromModel(time: NgbTimeStruct): NgbTimeStruct { | ||
return (time && isInteger(time.hour) && isInteger(time.minute)) ? | ||
{hour: time.hour, minute: time.minute, second: isInteger(time.second) ? time.second : null} : | ||
null; | ||
} | ||
|
||
/** | ||
* Converts a NgbTimeStruct value into NgbTimeStruct value | ||
* @param {NgbTimeStruct} value | ||
* @return {NgbTimeStruct} | ||
*/ | ||
toModel(time: NgbTimeStruct): NgbTimeStruct { | ||
return (time && isInteger(time.hour) && isInteger(time.minute)) ? | ||
{hour: time.hour, minute: time.minute, second: isInteger(time.second) ? time.second : null} : | ||
null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.