mirror of
https://github.com/wassname/angular-timezone-selector.git
synced 2026-06-27 21:05:49 +08:00
112 lines
3.4 KiB
JavaScript
112 lines
3.4 KiB
JavaScript
/*global angular, _, moment, $*/
|
|
|
|
/**
|
|
* angular-timezone-selector
|
|
*
|
|
* A simple directive that allows a user to pick their timezone
|
|
*
|
|
* Author: Ashok Fernandez <ashok@mish.guru>
|
|
* Date: 12/06/2015
|
|
* License: MIT
|
|
*/
|
|
|
|
angular.module('angular-timezone-selector', [])
|
|
.constant('_', _)
|
|
.constant('moment', moment)
|
|
.factory('timezones', ['_', 'moment', function (_, moment) {
|
|
var timezoneMap = {}
|
|
_.forEach(moment.tz.names(), function (zoneName) {
|
|
timezoneMap[zoneName] = {
|
|
id: zoneName,
|
|
name: zoneName.replace(/_/g, ' '),
|
|
offset: 'UTC' + moment().tz(zoneName).format('Z')
|
|
}
|
|
})
|
|
return timezoneMap
|
|
}])
|
|
|
|
// Timezone name to country codemap
|
|
.factory('zoneToCC', ['_', function (_) {
|
|
// Note: zones is populated with the data from 'data/zone.csv' when this file is built
|
|
var zones = []
|
|
var zoneMap = {}
|
|
_.forEach(zones, function (zone) {
|
|
zoneMap[zone.name] = zone.cca2
|
|
})
|
|
return zoneMap
|
|
|
|
}])
|
|
|
|
// Country code to country name map
|
|
.factory('CCToCountryName', ['_', function (_) {
|
|
// Note: codes is populated with the data from 'data/cca2_to_country_name.csv' when this file is built
|
|
var codes = []
|
|
var codeMap = {}
|
|
_.forEach(codes, function (code) {
|
|
codeMap[code.cca2] = code.name
|
|
})
|
|
return codeMap
|
|
}])
|
|
|
|
.directive('timezoneSelector', ['_', 'timezones', 'zoneToCC', 'CCToCountryName', function (_, timezones, zoneToCC, CCToCountryName) {
|
|
return {
|
|
restrict: 'E',
|
|
replace: true,
|
|
template: '<select style="min-width:300px;"></select>',
|
|
scope: {
|
|
ngModel: '='
|
|
},
|
|
link: function ($scope, elem, attrs) {
|
|
var data = []
|
|
|
|
// Group the timezones by their country code
|
|
var timezonesGroupedByCC = {}
|
|
_.forEach(timezones, function (timezone) {
|
|
if (_.has(zoneToCC, timezone.id)) {
|
|
var CC = zoneToCC[timezone.id]
|
|
timezonesGroupedByCC[CC] = !timezonesGroupedByCC[CC] ? [] : timezonesGroupedByCC[CC]
|
|
timezonesGroupedByCC[CC].push(timezone)
|
|
}
|
|
})
|
|
|
|
// Add the grouped countries to the data array with their country name as the group option
|
|
_.forEach(timezonesGroupedByCC, function (zonesByCountry, CC) {
|
|
var zonesForCountry = {
|
|
text: CCToCountryName[CC] + ': ',
|
|
children: zonesByCountry
|
|
}
|
|
|
|
data.push(zonesForCountry)
|
|
})
|
|
|
|
// Sort by country name
|
|
data = _.sortBy(data, 'text')
|
|
|
|
// Construct a select box with the timezones grouped by country
|
|
_.forEach(data, function (group) {
|
|
var $optgroup = $('<optgroup label="' + group.text + '">')
|
|
group.children.forEach(function (option) {
|
|
$optgroup.append('<option value="' + option.id + '">' +
|
|
option.name + '</option>')
|
|
})
|
|
elem.append($optgroup)
|
|
})
|
|
|
|
// Initialise the chosen box
|
|
elem.chosen({
|
|
width: '300px',
|
|
include_group_label_in_selected: true,
|
|
search_contains: true,
|
|
no_results_text: 'No results, try searching for the name of your country or nearest major city.',
|
|
placeholder_text_single: 'Choose a timezone'
|
|
})
|
|
|
|
// Update the box if ngModel changes
|
|
$scope.$watch('ngModel', function () {
|
|
elem.val($scope.ngModel)
|
|
elem.trigger('chosen:updated')
|
|
})
|
|
}
|
|
}
|
|
}])
|