ngx-timezones
Version:
An Angular module for timezones (based on moment.js)
163 lines • 19 kB
JavaScript
import { countryZones } from './ngx-timezones.data';
import { Component, Input, Output, EventEmitter, ChangeDetectorRef, } from '@angular/core';
import { FormControl } from '@angular/forms';
import * as moment from 'moment-timezone';
import { startWith, map } from 'rxjs/operators';
export class NgxTimezonesComponent {
constructor(cdRef) {
this.cdRef = cdRef;
this.timezoneCtrl = new FormControl();
this.searchControl = new FormControl();
this.timezoneChange = new EventEmitter();
this.guess = false;
this.showOffset = false;
this.placeholder = 'Select timezone';
this.searchPlaceholder = 'Search';
this.noResultsLabel = 'No results';
this.offsetName = 'UTC';
}
set timezone(timezone) {
this.timezoneCtrl.setValue(timezone);
}
set disabled(value) {
if (value) {
this.timezoneCtrl.disable();
}
else {
this.timezoneCtrl.enable();
}
}
ngOnInit() {
this.initData();
this.timezoneGroupsOptions = this.searchControl.valueChanges.pipe(startWith(''), map((query) => (query ? this.filter(query) : this.timezoneGroups.slice())));
this.timezoneCtrl.valueChanges.subscribe((value) => {
this.emitTimezone(value);
});
if (!this.timezoneCtrl.value && this.guess) {
this.guessedTimezone();
this.cdRef.detectChanges();
}
}
guessedTimezone() {
const zone = moment.tz.guess();
this.timezone = zone;
this.emitTimezone(zone);
}
emitTimezone(zone) {
this.timezoneChange.emit(zone);
}
initData() {
this.timezoneGroups = Object.keys(countryZones).map((iso) => {
const val = countryZones[iso];
const hasMultiple = val.zones.length > 1;
const zones = val.zones.map((x) => {
return hasMultiple
? {
zone: x,
name: `${this.formatTimezoneString(x)}`,
offset: this.offsetOfTimezone(x),
}
: {
zone: x,
name: val.name,
offset: this.offsetOfTimezone(x),
};
});
return { iso, country: val.name, zones };
});
}
filter(query) {
const result = [];
for (const z of this.timezoneGroups) {
if (z.country && z.country.toLowerCase().includes(query.toLowerCase())) {
result.push(z);
}
else {
const results = z.zones.filter((x) => x.name.toLowerCase().includes(query.toLowerCase()));
if (results.length > 0) {
z.zones = results;
z.showGroup = z.zones.length > 1;
result.push(z);
}
}
}
return result;
}
formatTimezoneString(zone) {
const arr = zone.split('/');
return arr[arr.length - 1].split('_').join(' ');
}
offsetOfTimezone(zone) {
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 `${neg ? '-' : '+'}${this.rjust(hours.toString(), 2)}:${this.rjust(minutes.toString(), 2)}`;
}
formatOffset(offset) {
return `(${this.offsetName}${offset})`;
}
rjust(value, width, padding = '0') {
padding = padding || ' ';
padding = padding.substr(0, 1);
if (value.length < width) {
return padding.repeat(width - value.length) + value;
}
else {
return value;
}
}
}
NgxTimezonesComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-timezones',
template: ` <mat-form-field style="width: 100%"
><mat-select [formControl]="timezoneCtrl" [placeholder]="placeholder">
<mat-option>
<ngx-mat-select-search
[formControl]="searchControl"
[placeholderLabel]="searchPlaceholder"
[noEntriesFoundLabel]="noResultsLabel"
></ngx-mat-select-search>
</mat-option>
<ng-template let-option ngFor [ngForOf]="timezoneGroupsOptions | async">
<mat-optgroup
*ngIf="option.showGroup || option.zones.length > 1; else singleOption"
[label]="option.country + ' (' + option.zones.length + ')'"
>
<mat-option *ngFor="let zone of option.zones" [value]="zone.zone">
{{ zone.name }}
<span>{{ showOffset ? formatOffset(zone.offset) : '' }}</span>
</mat-option>
</mat-optgroup>
<ng-template #singleOption>
<mat-option [value]="option.zones[0].zone">
{{ option.zones[0].name }}
<span>{{
showOffset ? formatOffset(option.zones[0].offset) : ''
}}</span>
</mat-option>
</ng-template>
</ng-template>
</mat-select>
</mat-form-field>`
},] }
];
NgxTimezonesComponent.ctorParameters = () => [
{ type: ChangeDetectorRef }
];
NgxTimezonesComponent.propDecorators = {
timezoneChange: [{ type: Output }],
timezone: [{ type: Input }],
disabled: [{ type: Input }],
guess: [{ type: Input }],
showOffset: [{ type: Input }],
placeholder: [{ type: Input }],
searchPlaceholder: [{ type: Input }],
noResultsLabel: [{ type: Input }],
offsetName: [{ type: Input }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXRpbWV6b25lcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdGltZXpvbmVzL3NyYy9saWIvbmd4LXRpbWV6b25lcy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3BELE9BQU8sRUFDTCxTQUFTLEVBRVQsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBQ1osaUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUEwQ2hELE1BQU0sT0FBTyxxQkFBcUI7SUE0QmhDLFlBQW9CLEtBQXdCO1FBQXhCLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBM0I1QyxpQkFBWSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7UUFHakMsa0JBQWEsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBRXhCLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQWM3QyxVQUFLLEdBQUcsS0FBSyxDQUFDO1FBRWQsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUNuQixnQkFBVyxHQUFHLGlCQUFpQixDQUFDO1FBQ2hDLHNCQUFpQixHQUFHLFFBQVEsQ0FBQztRQUM3QixtQkFBYyxHQUFHLFlBQVksQ0FBQztRQUM5QixlQUFVLEdBQUcsS0FBSyxDQUFDO0lBRW1CLENBQUM7SUFwQmhELElBQWEsUUFBUSxDQUFDLFFBQWdCO1FBQ3BDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxJQUFhLFFBQVEsQ0FBQyxLQUFj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NkJBQ0wsS0FBSzt5QkFDTCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY291bnRyeVpvbmVzIH0gZnJvbSAnLi9uZ3gtdGltZXpvbmVzLmRhdGEnO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBPbkluaXQsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUNvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgKiBhcyBtb21lbnQgZnJvbSAnbW9tZW50LXRpbWV6b25lJztcbmltcG9ydCB7IHN0YXJ0V2l0aCwgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbnRlcmZhY2UgVGltZXpvbmVHcm91cCB7XG4gIGNvdW50cnk6IHN0cmluZztcbiAgaXNvOiBzdHJpbmc7XG4gIHNob3dHcm91cD86IGJvb2xlYW47XG4gIHpvbmVzOiB7IHpvbmU6IHN0cmluZzsgbmFtZTogc3RyaW5nOyBvZmZzZXQ6IHN0cmluZyB9W107XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC10aW1lem9uZXMnLFxuICB0ZW1wbGF0ZTogYCA8bWF0LWZvcm0tZmllbGQgc3R5bGU9XCJ3aWR0aDogMTAwJVwiXG4gICAgPjxtYXQtc2VsZWN0IFtmb3JtQ29udHJvbF09XCJ0aW1lem9uZUN0cmxcIiBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIj5cbiAgICAgIDxtYXQtb3B0aW9uPlxuICAgICAgICA8bmd4LW1hdC1zZWxlY3Qtc2VhcmNoXG4gICAgICAgICAgW2Zvcm1Db250cm9sXT1cInNlYXJjaENvbnRyb2xcIlxuICAgICAgICAgIFtwbGFjZWhvbGRlckxhYmVsXT1cInNlYXJjaFBsYWNlaG9sZGVyXCJcbiAgICAgICAgICBbbm9FbnRyaWVzRm91bmRMYWJlbF09XCJub1Jlc3VsdHNMYWJlbFwiXG4gICAgICAgID48L25neC1tYXQtc2VsZWN0LXNlYXJjaD5cbiAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtb3B0aW9uIG5nRm9yIFtuZ0Zvck9mXT1cInRpbWV6b25lR3JvdXBzT3B0aW9ucyB8IGFzeW5jXCI+XG4gICAgICAgIDxtYXQtb3B0Z3JvdXBcbiAgICAgICAgICAqbmdJZj1cIm9wdGlvbi5zaG93R3JvdXAgfHwgb3B0aW9uLnpvbmVzLmxlbmd0aCA+IDE7IGVsc2Ugc2luZ2xlT3B0aW9uXCJcbiAgICAgICAgICBbbGFiZWxdPVwib3B0aW9uLmNvdW50cnkgKyAnICgnICsgb3B0aW9uLnpvbmVzLmxlbmd0aCArICcpJ1wiXG4gICAgICAgID5cbiAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgem9uZSBvZiBvcHRpb24uem9uZXNcIiBbdmFsdWVdPVwiem9uZS56b25lXCI+XG4gICAgICAgICAgICB7eyB6b25lLm5hbWUgfX1cbiAgICAgICAgICAgIDxzcGFuPnt7IHNob3dPZmZzZXQgPyBmb3JtYXRPZmZzZXQoem9uZS5vZmZzZXQpIDogJycgfX08L3NwYW4+XG4gICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICA8L21hdC1vcHRncm91cD5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNzaW5nbGVPcHRpb24+XG4gICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi56b25lc1swXS56b25lXCI+XG4gICAgICAgICAgICB7eyBvcHRpb24uem9uZXNbMF0ubmFtZSB9fVxuICAgICAgICAgICAgPHNwYW4+e3tcbiAgICAgICAgICAgICAgc2hvd09mZnNldCA/IGZvcm1hdE9mZnNldChvcHRpb24uem9uZXNbMF0ub2Zmc2V0KSA6ICcnXG4gICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvbWF0LXNlbGVjdD5cbiAgPC9tYXQtZm9ybS1maWVsZD5gLFxufSlcbmV4cG9ydCBjbGFzcyBOZ3hUaW1lem9uZXNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICB0aW1lem9uZUN0cmwgPSBuZXcgRm9ybUNvbnRyb2woKTtcbiAgdGltZXpvbmVHcm91cHMhOiBUaW1lem9uZUdyb3VwW107XG4gIHRpbWV6b25lR3JvdXBzT3B0aW9ucyE6IE9ic2VydmFibGU8VGltZXpvbmVHcm91cFtdPjtcbiAgc2VhcmNoQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbCgpO1xuXG4gIEBPdXRwdXQoKSB0aW1lem9uZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIEBJbnB1dCgpIHNldCB0aW1lem9uZSh0aW1lem9uZTogc3RyaW5nKSB7XG4gICAgdGhpcy50aW1lem9uZUN0cmwuc2V0VmFsdWUodGltZXpvbmUpO1xuICB9XG5cbiAgQElucHV0KCkgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnRpbWV6b25lQ3RybC5kaXNhYmxlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGltZXpvbmVDdHJsLmVuYWJsZSgpO1xuICAgIH1cbiAgfVxuXG4gIEBJbnB1dCgpIGd1ZXNzID0gZmFsc2U7XG5cbiAgQElucHV0KCkgc2hvd09mZnNldCA9IGZhbHNlO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICdTZWxlY3QgdGltZXpvbmUnO1xuICBASW5wdXQoKSBzZWFyY2hQbGFjZWhvbGRlciA9ICdTZWFyY2gnO1xuICBASW5wdXQoKSBub1Jlc3VsdHNMYWJlbCA9ICdObyByZXN1bHRzJztcbiAgQElucHV0KCkgb2Zmc2V0TmFtZSA9ICdVVEMnO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2RSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdERhdGEoKTtcbiAgICB0aGlzLnRpbWV6b25lR3JvdXBzT3B0aW9ucyA9IHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZUNoYW5nZXMucGlwZShcbiAgICAgIHN0YXJ0V2l0aCgnJyksXG4gICAgICBtYXAoKHF1ZXJ5KSA9PiAocXVlcnkgPyB0aGlzLmZpbHRlcihxdWVyeSkgOiB0aGlzLnRpbWV6b25lR3JvdXBzLnNsaWNlKCkpKVxuICAgICk7XG4gICAgdGhpcy50aW1lem9uZUN0cmwudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgIHRoaXMuZW1pdFRpbWV6b25lKHZhbHVlKTtcbiAgICB9KTtcblxuICAgIGlmICghdGhpcy50aW1lem9uZUN0cmwudmFsdWUgJiYgdGhpcy5ndWVzcykge1xuICAgICAgdGhpcy5ndWVzc2VkVGltZXpvbmUoKTtcbiAgICAgIHRoaXMuY2RSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIGd1ZXNzZWRUaW1lem9uZSgpOiB2b2lkIHtcbiAgICBjb25zdCB6b25lID0gbW9tZW50LnR6Lmd1ZXNzKCk7XG4gICAgdGhpcy50aW1lem9uZSA9IHpvbmU7XG4gICAgdGhpcy5lbWl0VGltZXpvbmUoem9uZSk7XG4gIH1cblxuICBlbWl0VGltZXpvbmUoem9uZSk6IHZvaWQge1xuICAgIHRoaXMudGltZXpvbmVDaGFuZ2UuZW1pdCh6b25lKTtcbiAgfVxuXG4gIGluaXREYXRhKCk6IHZvaWQge1xuICAgIHRoaXMudGltZXpvbmVHcm91cHMgPSBPYmplY3Qua2V5cyhjb3VudHJ5Wm9uZXMpLm1hcCgoaXNvOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHZhbCA9IGNvdW50cnlab25lc1tpc29dO1xuICAgICAgY29uc3QgaGFzTXVsdGlwbGUgPSB2YWwuem9uZXMubGVuZ3RoID4gMTtcbiAgICAgIGNvbnN0IHpvbmVzID0gdmFsLnpvbmVzLm1hcCgoeCkgPT4ge1xuICAgICAgICByZXR1cm4gaGFzTXVsdGlwbGVcbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgem9uZTogeCxcbiAgICAgICAgICAgICAgbmFtZTogYCR7dGhpcy5mb3JtYXRUaW1lem9uZVN0cmluZyh4KX1gLFxuICAgICAgICAgICAgICBvZmZzZXQ6IHRoaXMub2Zmc2V0T2ZUaW1lem9uZSh4KSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgem9uZTogeCxcbiAgICAgICAgICAgICAgbmFtZTogdmFsLm5hbWUsXG4gICAgICAgICAgICAgIG9mZnNldDogdGhpcy5vZmZzZXRPZlRpbWV6b25lKHgpLFxuICAgICAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHsgaXNvLCBjb3VudHJ5OiB2YWwubmFtZSwgem9uZXMgfTtcbiAgICB9KTtcbiAgfVxuXG4gIGZpbHRlcihxdWVyeTogc3RyaW5nKTogVGltZXpvbmVHcm91cFtdIHtcbiAgICBjb25zdCByZXN1bHQ6IFRpbWV6b25lR3JvdXBbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCB6IG9mIHRoaXMudGltZXpvbmVHcm91cHMpIHtcbiAgICAgIGlmICh6LmNvdW50cnkgJiYgei5jb3VudHJ5LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocXVlcnkudG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goeik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCByZXN1bHRzID0gei56b25lcy5maWx0ZXIoKHgpID0+XG4gICAgICAgICAgeC5uYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocXVlcnkudG9Mb3dlckNhc2UoKSlcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHouem9uZXMgPSByZXN1bHRzO1xuICAgICAgICAgIHouc2hvd0dyb3VwID0gei56b25lcy5sZW5ndGggPiAxO1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHopO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZvcm1hdFRpbWV6b25lU3RyaW5nKHpvbmU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgYXJyID0gem9uZS5zcGxpdCgnLycpO1xuICAgIHJldHVybiBhcnJbYXJyLmxlbmd0aCAtIDFdLnNwbGl0KCdfJykuam9pbignICcpO1xuICB9XG5cbiAgb2Zmc2V0T2ZUaW1lem9uZSh6b25lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGxldCBvZmZzZXQgPSBtb21lbnQudHooem9uZSkudXRjT2Zmc2V0KCk7XG4gICAgY29uc3QgbmVnID0gb2Zmc2V0IDwgMDtcbiAgICBpZiAobmVnKSB7XG4gICAgICBvZmZzZXQgPSAtMSAqIG9mZnNldDtcbiAgICB9XG4gICAgY29uc3QgaG91cnMgPSBNYXRoLmZsb29yKG9mZnNldCAvIDYwKTtcbiAgICBjb25zdCBtaW51dGVzID0gKG9mZnNldCAvIDYwIC0gaG91cnMpICogNjA7XG4gICAgcmV0dXJuIGAke25lZyA/ICctJyA6ICcrJ30ke3RoaXMucmp1c3QoaG91cnMudG9TdHJpbmcoKSwgMil9OiR7dGhpcy5yanVzdChcbiAgICAgIG1pbnV0ZXMudG9TdHJpbmcoKSxcbiAgICAgIDJcbiAgICApfWA7XG4gIH1cblxuICBmb3JtYXRPZmZzZXQob2Zmc2V0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBgKCR7dGhpcy5vZmZzZXROYW1lfSR7b2Zmc2V0fSlgO1xuICB9XG5cbiAgcHJpdmF0ZSByanVzdCh2YWx1ZTogc3RyaW5nLCB3aWR0aDogbnVtYmVyLCBwYWRkaW5nID0gJzAnKTogc3RyaW5nIHtcbiAgICBwYWRkaW5nID0gcGFkZGluZyB8fCAnICc7XG4gICAgcGFkZGluZyA9IHBhZGRpbmcuc3Vic3RyKDAsIDEpO1xuICAgIGlmICh2YWx1ZS5sZW5ndGggPCB3aWR0aCkge1xuICAgICAgcmV0dXJuIHBhZGRpbmcucmVwZWF0KHdpZHRoIC0gdmFsdWUubGVuZ3RoKSArIHZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9XG59XG4iXX0=