forked from mishguruorg/angular-timezone-selector
-
Notifications
You must be signed in to change notification settings - Fork 0
/
angular-timezone-selector.js
111 lines (98 loc) · 3.39 KB
/
angular-timezone-selector.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*global angular, _, moment, $*/
/**
* angular-timezone-selector
*
* A simple directive that allows a user to pick their timezone
*
* Author: Ashok Fernandez <[email protected]>
* 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')
})
}
}
}])