src/timezone-picker.component.ts
selector | ng2-timezone-picker |
template |
|
Properties |
Methods |
|
Inputs |
Outputs |
Accessors |
constructor(service: TimezonePickerService)
|
||||||||
Defined in src/timezone-picker.component.ts:112
|
||||||||
Contructor function to define all the timezones
Parameters :
|
allowClear
|
Input (optional) bound to [allowClear]
Default value: |
Defined in src/timezone-picker.component.ts:45
|
country
|
Type: |
Defined in src/timezone-picker.component.ts:93
|
disabled
|
Input (optional) bound to [disabled]
Default value: |
Defined in src/timezone-picker.component.ts:54
|
guess
|
Default value: |
Defined in src/timezone-picker.component.ts:49
|
placeholder
|
Input (optional) bound to [placeholder]
Type: |
Defined in src/timezone-picker.component.ts:62
|
showOffset
|
Default value: |
Defined in src/timezone-picker.component.ts:47
|
timezone
|
Input: string (required) bound to [timezone]
Type: |
Defined in src/timezone-picker.component.ts:82
|
change
|
Output event bound to (change) $event type: EventEmitter
|
Defined in src/timezone-picker.component.ts:111
|
countryChange
|
$event type: EventEmitter
|
Defined in src/timezone-picker.component.ts:112
|
timezoneChange
|
Output event bound to (timezone) $event type: EventEmitter
|
Defined in src/timezone-picker.component.ts:106
|
formatTimezoneString | ||||||||
formatTimezoneString(zone: string)
|
||||||||
Defined in src/timezone-picker.component.ts:156
|
||||||||
Parameters :
Returns :
string
|
Private matcher | ||||||||||||
matcher(params: , data: )
|
||||||||||||
Defined in src/timezone-picker.component.ts:190
|
||||||||||||
Matcher function to search in the select options
Parameters :
Returns :
any
|
ngAfterViewInit |
ngAfterViewInit()
|
Defined in src/timezone-picker.component.ts:124
|
$ bounding of select2 framework in the selectElement
Returns :
void
|
offsetOfTimezone | ||||||||
offsetOfTimezone(zone: string)
|
||||||||
Defined in src/timezone-picker.component.ts:161
|
||||||||
Parameters :
Returns :
string
|
Private onChange | ||||||||
onChange(timezone: )
|
||||||||
Defined in src/timezone-picker.component.ts:179
|
||||||||
onChange function called by the "select" element
Parameters :
Returns :
void
|
Private rjust |
rjust(string: string, width: number, padding: )
|
Defined in src/timezone-picker.component.ts:234
|
Returns :
string
|
Private triggerChangeEvent |
triggerChangeEvent()
|
Defined in src/timezone-picker.component.ts:144
|
Returns :
void
|
allTimezones |
allTimezones:
|
Type : Timezone[]
|
Defined in src/timezone-picker.component.ts:36
|
all time zones combined in one array, for each country |
currentTimezone |
currentTimezone:
|
Type : string
|
Defined in src/timezone-picker.component.ts:77
|
The current selected timezone. |
placeholderString |
placeholderString:
|
Default value : 'Select timezone'
|
Defined in src/timezone-picker.component.ts:56
|
select |
select:
|
Type : ElementRef
|
Decorators : ViewChild
|
Defined in src/timezone-picker.component.ts:40
|
ElementRef for the select element |
Public service |
service:
|
Type : TimezonePickerService
|
Defined in src/timezone-picker.component.ts:117
|
placeholder | ||||||||
setplaceholder(placeholder: string)
|
||||||||
Defined in src/timezone-picker.component.ts:62
|
||||||||
Input (optional) bound to [placeholder]
Parameters :
Returns :
void
|
timezone | ||||||||
settimezone(timezone: string)
|
||||||||
Defined in src/timezone-picker.component.ts:82
|
||||||||
Input: string (required) bound to [timezone]
Parameters :
Returns :
void
|
country |
setcountry(isoCode: string)
|
Defined in src/timezone-picker.component.ts:93
|
import { TimezonePickerService, Timezone } from './timezone-picker.service';
import {
Component,
AfterViewInit,
Input,
ViewChild,
ElementRef,
EventEmitter,
Output
} from '@angular/core';
import * as moment from 'moment-timezone';
import $ from 'jquery';
import 'select2';
@Component({
selector: 'ng2-timezone-picker',
template: `
<select #select id="select" style="width: 100%" class="form-control" [disabled]="disabled">
<option></option>
<ng-template let-c ngFor [ngForOf]="allTimezones">
<optgroup *ngIf="c.zones.length > 1" [label]="c.iso | iso2CountryPipe">
<option *ngFor="let t of c.zones" [value]="t">{{c.iso | iso2CountryPipe}} - {{formatTimezoneString(t)}}
<span *ngIf="showOffset">{{offsetOfTimezone(t)}}</span>
</option>
</optgroup>
<option *ngIf="c.zones.length === 1" [value]="c.zones[0]">{{c.iso | iso2CountryPipe}}
<span *ngIf="showOffset">{{offsetOfTimezone(c.zones[0])}}</span>
</option>
</ng-template>
</select>`
})
export class TimezonePickerComponent implements AfterViewInit {
/**
* all time zones combined in one array, for each country
*/
allTimezones: Timezone[];
/**
* ElementRef for the select element
*/
@ViewChild('select') select: ElementRef;
/**
* Input (optional) bound to [allowClear]
*/
@Input() allowClear = false;
@Input() showOffset = false;
@Input() guess = false;
/**
* Input (optional) bound to [disabled]
*/
@Input() disabled = false;
placeholderString = 'Select timezone';
/**
* Input (optional) bound to [placeholder]
*/
@Input()
set placeholder(placeholder: string) {
if (placeholder) {
this.placeholderString = placeholder;
const placeholderElem = $(this.select.nativeElement.parentElement).find(
'.select2-selection__placeholder'
);
if (placeholderElem.length > 0) {
placeholderElem[0].innerText = placeholder;
}
}
}
/**
* The current selected timezone.
*/
currentTimezone: string;
/**
* Input: string (required) bound to [timezone]
*/
@Input()
set timezone(timezone: string) {
if (timezone) {
this.currentTimezone = timezone;
this.triggerChangeEvent();
} else if (this.guess) {
this.currentTimezone = moment.tz.guess();
this.triggerChangeEvent();
}
}
@Input()
set country(isoCode: string) {
if (isoCode && !this.currentTimezone && !this.guess) {
const res = this.allTimezones.find(x => x.iso === isoCode);
if (res) {
this.currentTimezone = res.zones[0];
this.triggerChangeEvent();
}
}
}
/**
* Output event bound to (timezone)
*/
@Output() timezoneChange = new EventEmitter<string>();
/**
* Output event bound to (change)
*/
@Output() change = new EventEmitter<string>();
@Output() countryChange = new EventEmitter<string>();
/**
* Contructor function to define all the timezones
*/
constructor(public service: TimezonePickerService) {
this.allTimezones = service.getZones();
}
/**
* $ bounding of select2 framework in the selectElement
*/
ngAfterViewInit() {
const selectElement = $(this.select.nativeElement);
selectElement.select2({
placeholder: this.placeholderString,
allowClear: this.allowClear,
matcher: (term, text) => this.matcher(term, text)
});
if (this.currentTimezone) {
$(selectElement)
.val(this.currentTimezone)
.trigger('change');
}
selectElement.on('change', (e: any) => {
this.onChange($(e.target).val());
});
}
private triggerChangeEvent(): void {
$(this.select.nativeElement)
.val(this.currentTimezone)
.trigger('change');
this.timezoneChange.emit(this.currentTimezone);
this.change.emit(this.currentTimezone);
this.countryChange.emit(
this.allTimezones.find(x => x.zones.indexOf(this.currentTimezone) >= 0)
.iso
);
}
formatTimezoneString(zone: string): string {
const arr = zone.split('/');
return arr[arr.length - 1].replace('_', ' ');
}
offsetOfTimezone(zone: string): string {
let offset = moment.tz(zone).utcOffset();
const neg = offset < 0;
if (neg) {
offset = -1 * offset;
}
const hours = Math.floor(offset / 60);
const minutes = (offset / 60 - hours) * 60;
return `(GMT${neg ? '-' : '+'}${this.rjust(
hours.toString(),
2
)}:${this.rjust(minutes.toString(), 2)})`;
}
/**
* onChange function called by the "select" element
* @param timezone The timezone string selected
*/
private onChange(timezone) {
this.currentTimezone = timezone;
this.timezoneChange.emit(timezone);
this.change.emit(timezone);
}
/**
* Matcher function to search in the select options
* @param params contains the search term
* @param data contains the data of each row
*/
private matcher(params, data) {
// Always return the object if there is nothing to compare
if ($.trim(params.term) === '') {
return data;
}
let original = data.text.toUpperCase();
const term = params.term.toUpperCase();
// Replace '_' with ' ' to be able to search for 'New York'
if (original.indexOf('_') !== -1) {
original += original.replace('_', ' ');
}
// Check if the text contains the term
if (original.indexOf(term) > -1) {
return data;
}
// Do a recursive check for options with children
if (data.children && data.children.length > 0) {
// Clone the data object if there are children
// This is required as we modify the object to remove any non-matches
const match = $.extend(true, {}, data);
// Check each child of the option
for (let c = data.children.length - 1; c >= 0; c--) {
const child = data.children[c];
const matches = this.matcher(params, child);
// If there wasn't a match, remove the object in the array
if (matches == null) {
match.children.splice(c, 1);
}
}
// If any children matched, return the new object
if (match.children.length > 0) {
return match;
}
// If there were no matching children, check just the plain object
return this.matcher(params, match);
}
// If it doesn't contain the term, don't return anything
return null;
}
private rjust(string: string, width: number, padding = '0'): string {
padding = padding || ' ';
padding = padding.substr(0, 1);
if (string.length < width) {
return padding.repeat(width - string.length) + string;
} else {
return string;
}
}
}