├── .gitignore ├── LICENSE.md ├── README.md ├── dist ├── styles │ └── timezone-picker.css └── timezone-picker.min.js ├── example └── index-external-vendor.html ├── package-lock.json ├── package.json ├── src ├── TimezonePicker.js ├── index-external-vendor.ejs ├── index.ejs ├── styles │ ├── _colors.scss │ └── style.scss ├── timezones.json └── utils │ ├── Plugin.js │ └── Utils.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_store 2 | node_modules/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Keval Bhatt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # timezone-picker 2 | 3 | timezone-picker is the plugin to select and get timezone value of selected area(country) from WorldMap. 4 | 5 | [![NPM version](https://badge.fury.io/js/timezone-picker.svg)](https://www.npmjs.com/package/timezone-picker) 6 | [![NPM Dependency](https://david-dm.org/kevalbhatt/timezone-picker.svg)](https://www.npmjs.com/package/timezone-picker) 7 | [![](https://data.jsdelivr.com/v1/package/npm/timezone-picker/badge)](https://www.jsdelivr.com/package/npm/timezone-picker) 8 | [![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php) 9 | [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)]() 10 | [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/kevalbhatt/timezone-picker/issues) 11 | [![HitCount](http://hits.dwyl.com/kevalbhatt/timezone-picker.svg)](http://github.com/kevalbhatt/timezone-picker) 12 | 13 | 14 | ### Live Demo: http://kevalbhatt.github.io/timezone-picker/ 15 | --------------------- 16 | 17 | ![Imgur](https://i.imgur.com/YrGdPv2.png) 18 | 19 | # Dependency 20 | --------------------- 21 | * moment-timezone 22 | * jquery 23 | * select2 (optional) 24 | 25 | 26 | # Installation 27 | --------------------- 28 | 29 | ### Use package Using npm 30 | 31 | ```sh 32 | npm install --save timezone-picker 33 | ``` 34 | or 35 | 36 | ### Use package Using CDN 37 | 38 | ```html 39 | 40 | ``` 41 | 42 | Include the following lines of code in the section of your HTML. 43 | 44 | ```html 45 | 46 | 47 | 48 | 49 | 50 | 51 | ``` 52 | 53 | 54 | # Usage 55 | --------------------- 56 | 57 | ## Select any dom element where you want to create the map. 58 | 59 | ```js 60 | $(selector).timezonePicker(); 61 | ``` 62 | 63 | ## defaultValue 64 | 65 | Set a custom value on load 66 | 67 | If defaultValue is null then system timezone is selected 68 | 69 | * ### Select value based on zonename. 70 | 71 | ```js 72 | $(selector).timezonePicker({ defaultValue: { value: "EAT", attribute: "zonename" }}); 73 | ``` 74 | 75 | * ### Select value based on country code. 76 | 77 | ```js 78 | $(selector).timezonePicker({ defaultValue: { value: "IN", attribute: "country" }}); 79 | ``` 80 | 81 | * ### Select value based on timezone. 82 | 83 | ```js 84 | $(selector).timezonePicker({ defaultValue: { value: "Asia/Calcutta", attribute: "timezone" }}); 85 | ``` 86 | 87 | * ### Select value based on offset. 88 | 89 | ```js 90 | $(selector).timezonePicker({ defaultValue: { value: "5.5", attribute: "offset" }}); 91 | ``` 92 | 93 | ## quickLink 94 | 95 | You can create custom shortcuts link using quickLink options. 96 | 97 | ```js 98 | $(selector).timezonePicker({ 99 | quickLink: [{ 100 | "IST": "IST", 101 | "LONDON": "Europe/London" 102 | }] 103 | }); 104 | ``` 105 | 106 | * "LONDON": This key is used as a display string for shortcut button. 107 | * "Europe/London": This value is used when user click on a button and based on value, map is highlighted 108 | 109 | 110 | Example: 111 | 112 | You can pass following value. 113 | 114 | * **timezone** : Europe/London 115 | * **zonename** : GMT 116 | * **country code** : GB 117 | 118 | ```js 119 | $(selector).timezonePicker({ 120 | quickLink: [{ 121 | "LONDON1": "Europe/London" 122 | }] 123 | }); 124 | 125 | $(selector).timezonePicker({ 126 | quickLink: [{ 127 | "LONDON2": "GB" 128 | }] 129 | }); 130 | 131 | $(selector).timezonePicker({ 132 | quickLink: [{ 133 | "LONDON3": "GMT" 134 | }] 135 | }); 136 | 137 | $(selector).timezonePicker({ 138 | quickLink: [{ 139 | "GMT": "GMT" 140 | }] 141 | }); 142 | ``` 143 | 144 | ## hoverText 145 | 146 | ```js 147 | $(selector).timezonePicker({ 148 | hoverText: function(e, data){ 149 | return (data.timezone + " (" + data.zonename + ")"); 150 | } 151 | }); 152 | ``` 153 | 154 | ## quickLinkClass 155 | 156 | Class name for the quickLink container. 157 | 158 | ```js 159 | $(selector).timezonePicker({ 160 | quickLinkClass: "quick-class" 161 | }); 162 | ``` 163 | 164 | **Output** 165 | 166 | ```diff 167 |
168 | 169 | + 170 |
171 |
172 | ``` 173 | ## selectClass 174 | 175 | Class name for the country drop-down. 176 | 177 | ```js 178 | $('body').timezonePicker({ 179 | selectClass: "select-class" 180 | }); 181 | ``` 182 | **Output** 183 | 184 | ```diff 185 |
186 | + 187 | 188 |
189 |
190 | ``` 191 | 192 | ## filterBoxClass 193 | 194 | Class name for the filter box container. 195 | 196 | ```js 197 | $('body').timezonePicker({ 198 | filterBoxClass: "filter-class" 199 | }); 200 | ``` 201 | **Output** 202 | 203 | ```diff 204 | +
205 | 206 | 207 |
208 |
209 | ``` 210 | 211 | ## hoverTextClass 212 | 213 | Class name for the hover text container. 214 | 215 | ```js 216 | $('body').timezonePicker({ 217 | hoverTextClass: "hover-class" 218 | }); 219 | ``` 220 | **Output** 221 | 222 | ```diff 223 |
224 | 225 | 226 | +
227 |
228 | ``` 229 | 230 | # Options 231 | --------------------- 232 | 233 | | Parameter | Type | Default | Description | 234 | | :---------|:---- |:--------|:----------- | 235 | | **width** | `Number` | `500` | width of map | 236 | | **height** | `Number` | `250` | height of map | 237 | | [**defaultValue**](#defaultvalue) | `Object` | System timezone | Set custome value on load `{ value: "EAT", attribute: "zonename" }` | 238 | | [**quickLink**](#quicklink) | `Array` | `[{"IST": "IST","LONDON": "Europe/London"}]` | Creates shortcuts to select zone | 239 | | [**quickLinkClass**](#quicklinkclass) | `String` | `quick-link` | quickLinkClass will be appended with the default value | 240 | | [**filterBoxClass**](#filterboxclass) | `String` | `filter-box` | filterBoxClass will be appended with the default value | 241 | | **selectBox** | `Boolean` | `true` | If it is set to false select box will not be created | 242 | | [**selectClass**](#selectclass) | `String` | `country-lov` | selectClass is appended with the default value | 243 | | **showHoverText** | `Boolean` | `true` | If it is set to false hover text will not be shown | 244 | | [**hoverText**](#hovertext) | `Function` | `timezone(zonename)` | Called on hover of country (works only if showHoverText is true) | 245 | | [**hoverTextClass**](#hovertextclass) | `String` | `hover-text` | hoverTextClass is appended with the default value | 246 | | **hoverTextEl** | `Jquery selector` | `Appened in filter-box` | hover text element is appended in selector | 247 | | **mapHoverType** | `String` | hover polygon(area) | by default it will show hovered polygon(area) on which mouse is pointed [other hover options](#maphovertype-options) | 248 | 249 | 250 | 251 | ### mapHoverType options 252 | | Parameter | Type | Description | 253 | | :---------|:---- |:----------- | 254 | | **timezone** | `String`| when you hover on the map it will highlight all country with the same timezone 255 | | **country** | `String`| when you hover on the map it will highlight all country with same country code | 256 | | **zonename** | `String`| when you hover on the map it will highlight all country with the same zone name | 257 | 258 | 259 | # Methods 260 | --------------------- 261 | 262 | ### .setValue(value[String-required],attribute[String-optional]) 263 | 264 | Select the value(country) based on value and attribute parameter. 265 | 266 | 267 | * Set timezone string as a first parameter for example: 'Asia/Kolkata'. 268 | * Default attribute is "timezone"; 269 | 270 | ```js 271 | $(selector).data('timezonePicker').setValue('Asia/Kolkata') 272 | ``` 273 | 274 | * If you want to set value based on offset then set the 1st parameter as an offset string("5.5") and 2nd parameter to 'offset' 275 | 276 | ```js 277 | $(selector).data('timezonePicker').setValue('5.5','offset') 278 | ``` 279 | 280 | * If you want to set value based country code then set the 1st parameter as country code and 2nd parameter to 'country' 281 | 282 | ```js 283 | $(selector).data('timezonePicker').setValue('IN','country') 284 | ``` 285 | 286 | * If you want to set value based zonename then set the 1st parameter as zonename(IST) and 2nd parameter to 'zonename' 287 | 288 | ```js 289 | $(selector).data('timezonePicker').setValue('IST','zonename') 290 | ``` 291 | 292 | ### .getValue() 293 | 294 | It returns object containing timezone details of seleted area: 295 | 296 | ```js 297 | $(selector).data('timezonePicker').getValue() 298 | ``` 299 | 300 | Sample returned Object 301 | 302 | ```js 303 | [ 304 | { 305 | "selected":true, 306 | "zonename":"IST", 307 | "offset":5.5, 308 | "pin":"361,115", 309 | "country":"LK", 310 | "timezone": "Asia/Colombo", 311 | }, 312 | { 313 | "zonename":"IST", 314 | "offset":5.5, 315 | "pin": "373,94", 316 | "country":"IN", 317 | "timezone": "Asia/Kolkata", 318 | } 319 | ] 320 | ``` 321 | 322 | ### .getSystemTimezone() 323 | 324 | It returns an object containing system timezone details. 325 | 326 | ### .getTimeZoneObject(value[String-required],attribute[String-optional]) 327 | 328 | It returns an object containing timezone details based on value and attribute. 329 | 330 | * Get timezone `Object` using timezone string example: 'Asia/Kolkata'. 331 | * Default attribute is "timezone"; 332 | 333 | ```js 334 | $(selector).data('timezonePicker').getTimeZoneObject('Asia/Kolkata'); 335 | ``` 336 | 337 | * If you want to get Object based on offset then set the 1st parameter as an offset string("5.5") and 2nd parameter to 'offset' 338 | 339 | ```js 340 | $(selector).data('timezonePicker').getTimeZoneObject('5.5','offset'); 341 | ``` 342 | 343 | * If you want to get Object based country code then set the 1st parameter as country code and 2nd parameter to 'country' 344 | 345 | ```js 346 | $(selector).data('timezonePicker').getTimeZoneObject('IN','country'); 347 | ``` 348 | 349 | * If you want to get Object based zonename then set the 1st parameter as zonename(IST) and 2nd parameter to 'zonename' 350 | 351 | ```js 352 | $(selector).data('timezonePicker').getTimeZoneObject('IST','zonename'); 353 | ``` 354 | 355 | ### .getZoneName(value[String-required],attribute[String-optional]) 356 | 357 | It returns an zonename based on value and attribute. 358 | 359 | * Get zonename `String` using timezone string example: 'Asia/Kolkata'. 360 | * Default attribute is "timezone"; 361 | 362 | ```js 363 | $(selector).data('timezonePicker').getZoneName('Asia/Kolkata'); 364 | ``` 365 | 366 | * If you want to get zonename based on offset then set the 1st parameter as an offset string("5.5") and 2nd parameter to 'offset' 367 | 368 | ```js 369 | $(selector).data('timezonePicker').getZoneName('5.5','offset'); 370 | ``` 371 | 372 | * If you want to get zonename based country code then set the 1st parameter as country code and 2nd parameter to 'country' 373 | 374 | ```js 375 | $(selector).data('timezonePicker').getZoneName('IN','country'); 376 | ``` 377 | 378 | 379 | ### .getTimeZoneString(value[String-required],attribute[String-optional]) 380 | 381 | It returns an timezone string based on value and attribute. 382 | 383 | * Get timezone `String` using country code example: 'IN'. 384 | * Default attribute is "country"; 385 | 386 | ```js 387 | $(selector).data('timezonePicker').getZoneName('IN'); 388 | ``` 389 | 390 | * If you want to get timezone string based on offset then set the 1st parameter as an offset string("5.5") and 2nd parameter to 'offset' 391 | 392 | ```js 393 | $(selector).data('timezonePicker').getTimeZoneString('5.5','offset'); 394 | ``` 395 | 396 | * If you want to get timezone string based zonename then set the 1st parameter as zonename(IST) and 2nd parameter to 'zonename' 397 | 398 | ```js 399 | $(selector).data('timezonePicker').getTimeZoneString('IST','zonename'); 400 | ``` 401 | 402 | # Events 403 | --------------------- 404 | 405 | ## map:loaded 406 | 407 | As soon as the map is loaded and ready the **map:loaded** is fired. 408 | To catch it you can use: 409 | ``` 410 | $(selector).on("map:loaded" , function(){ 411 | console.log("Map is loaded, have fun!"); 412 | }); 413 | ``` 414 | 415 | ## map:value:changed 416 | 417 | Whenever the value of the timezone changes, the event **map:value:changed** is fired. 418 | To catch it you can use: 419 | ``` 420 | $(selector).on("map:value:changed" , function(){ 421 | console.log($(selector).data('timezonePicker').getValue()); 422 | }); 423 | ``` 424 | 425 | 426 | ## map:country:clicked 427 | 428 | Event **map:country:clicked** is fired, when a user clicks on the country. 429 | To catch it you can use: 430 | ``` 431 | $(selector).on("map:country:clicked" , function(){ 432 | console.log($(selector).data('timezonePicker').getValue()); 433 | }); 434 | ``` 435 | 436 | ## map:quickLink:clicked 437 | 438 | Event **map:quickLink:clicked** is fired, when a user clicks on the quickLink button. 439 | To catch it you can use: 440 | ``` 441 | $(selector).on("map:quickLink:clicked" , function(){ 442 | console.log($(selector).data('timezonePicker').getValue()); 443 | }); 444 | ``` 445 | 446 | ## map:option:changed 447 | 448 | Event **map:option:changed** is fired, when a user changes the value from the country drop-down. 449 | To catch it you can use: 450 | ``` 451 | $(selector).on("map:option:changed" , function(){ 452 | console.log($(selector).data('timezonePicker').getValue()); 453 | }); 454 | ``` 455 | 456 | ## License 457 | --------------------- 458 | It is available under the [MIT LICENSE](LICENSE.md) 459 | -------------------------------------------------------------------------------- /dist/styles/timezone-picker.css: -------------------------------------------------------------------------------- 1 | body.example{background-color:#9ddaf8}.timezone-map polygon{fill:#262626;stroke-width:.5;stroke:#959595}.timezone-map polygon[data-selected=true]{fill:orange;stroke:orange}.timezone-map polygon:hover{stroke:orange;fill:orange;cursor:pointer}.filter-box>*{float:left;height:24px}.filter-box select{width:45%;padding:0 0 0 10px}.filter-box .quick-link{width:52%;overflow-x:auto;white-space:nowrap;overflow-y:hidden}.filter-box .quick-link span{font-weight:300;border-radius:3px;color:#000;background-color:#fff;border:1px solid #000;margin-left:10px;font-size:9px;padding:4px 6px}.filter-box .quick-link span.active{color:#fff;background-color:orange}.filter-box .quick-link span:hover{color:#fff;background-color:orange;cursor:pointer}.filter-box .hover-text{height:20px;width:100%;padding:10px}.filter-box .hover-text p{opacity:0;text-align:center;transform:scale(10);transition:all .3s ease-in-out .2s}.filter-box .hover-text p.active{opacity:1;transform:scale(1);transition:all .3s ease-in-out .1s} -------------------------------------------------------------------------------- /dist/timezone-picker.min.js: -------------------------------------------------------------------------------- 1 | !function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n(require("jQuery"),require("select2"),require("moment-timezone")):"function"==typeof define&&define.amd?define(["jQuery","select2","moment-timezone"],n):"object"==typeof exports?exports.TimezonePicker=n(require("jQuery"),require("select2"),require("moment-timezone")):e.TimezonePicker=n(e.jQuery,e.select2,e["moment-timezone"])}(window,function(e,n,o){return function(e){var n={};function o(t){if(n[t])return n[t].exports;var i=n[t]={i:t,l:!1,exports:{}};return e[t].call(i.exports,i,i.exports,o),i.l=!0,i.exports}return o.m=e,o.c=n,o.d=function(e,n,t){o.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,n){if(1&n&&(e=o(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(o.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var i in e)o.d(t,i,function(n){return e[n]}.bind(null,i));return t},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="",o(o.s=9)}([function(n,o){n.exports=e},function(e,n){e.exports=function(e){var n=[];return n.toString=function(){return this.map(function(n){var o=function(e,n){var o=e[1]||"",t=e[3];if(!t)return o;if(n&&"function"==typeof btoa){var i=function(e){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(e))))+" */"}(t),a=t.sources.map(function(e){return"/*# sourceURL="+t.sourceRoot+e+" */"});return[o].concat(a).concat([i]).join("\n")}return[o].join("\n")}(n,e);return n[2]?"@media "+n[2]+"{"+o+"}":o}).join("")},n.i=function(e,o){"string"==typeof e&&(e=[[null,e,""]]);for(var t={},i=0;i.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:#fff}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top,#fff 50%,#eee);background-image:-o-linear-gradient(top,#fff 50%,#eee 100%);background-image:linear-gradient(180deg,#fff 50%,#eee);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFFFFFFF",endColorstr="#FFEEEEEE",GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:700;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top,#eee 50%,#ccc);background-image:-o-linear-gradient(top,#eee 50%,#ccc 100%);background-image:linear-gradient(180deg,#eee 50%,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFEEEEEE",endColorstr="#FFCCCCCC",GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent;border-style:solid;border-width:5px 4px 0;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir=rtl] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir=rtl] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888;border-width:0 4px 5px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top,#fff,#eee 50%);background-image:-o-linear-gradient(top,#fff 0,#eee 50%);background-image:linear-gradient(180deg,#fff 0,#eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFFFFFFF",endColorstr="#FFEEEEEE",GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top,#eee 50%,#fff);background-image:-o-linear-gradient(top,#eee 50%,#fff 100%);background-image:linear-gradient(180deg,#eee 50%,#fff);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFEEEEEE",endColorstr="#FFFFFFFF",GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:#fff;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:700;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir=rtl] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir=rtl] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}',""])},function(e,o){e.exports=n},function(e,n,o){"use strict";(function(e){Object.defineProperty(n,"__esModule",{value:!0});var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};n.default= 2 | /** 3 | * @version: v2.0.0-1 4 | * @author: Keval Bhatt 5 | * @copyright: Copyright (c) 2015 Keval Bhatt. All rights reserved. 6 | * @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php 7 | * @website: http://kevalbhatt.github.io/timezone-picker/ 8 | */ 9 | function(n){var t=n.pluginName,i=n.classRef,a=n.shortHand,s=void 0!==a&&a,r=""+t,c=e.fn[t];e.fn[t]=function(n){return this.each(function(){var t=e(this),a=t.data(r),s=e.extend({},i.DEFAULTS,t.data(),"object"===(void 0===n?"undefined":o(n))&&n);a||t.data(r,a=new i(t,s)),"string"==typeof n&&a[n]()})},s&&(e[t]=function(n){return e({})[t](n)});e.fn[t].noConflict=function(){return e.fn[t]=c}}}).call(this,o(0))},function(e,n,o){"use strict";(function(e){Object.defineProperty(n,"__esModule",{value:!0});n.generateElement=function(e){var n=e.element,o=e.attr,t=e.chilled,i=void 0!==t&&t,a=e.isSvg;if(void 0!==a&&a)var s=document.createElementNS("http://www.w3.org/2000/svg",n);else s=document.createElement(n);if(o)for(var r in o)s.setAttribute(r,o[r]);if(i)if(i instanceof Array)for(var c in i)s.appendChild(i[c]);else"string"==typeof i?s.innerHTML=i:s.appendChild(i);return s},n.findValue=function(n,o,t){for(var i=[],a=(t.filter(function(t){if(t[n]===o)return i.push(e.extend(!0,{},t)),t}),0);a0){for(var m in n.quickLink[0])a.push((0,p.generateElement)({element:"span",attr:{"data-select":n.quickLink[0][m]},chilled:m}));var z=(0,p.generateElement)({element:"div",attr:{class:(n.quickLinkClass+" quick-link").trim()},chilled:a});s.push(z)}if(n.showHoverText){var d=(0,p.generateElement)({element:"p"}),A=(0,p.generateElement)({element:"div",attr:{class:(n.hoverTextClass+" hover-text").trim()},chilled:d});n.hoverTextEl?n.hoverTextEl.append(A):s.push(A)}var y=(0,p.generateElement)({element:"svg",attr:{class:"timezone-map",viewBox:"0 0 "+n.width+" "+n.height},chilled:o,isSvg:!0});if(s.length>0){var T=(0,p.generateElement)({element:"div",attr:{class:(n.filterBoxClass+" filter-box").trim()},chilled:s});this.$el.append(T),t.fn.select2&&t(".country-lov").select2()}this.$el.append(y),this.bindEvent(n)}},{key:"bindEvent",value:function(e){var n=this;this.$el.on("mouseenter","svg polygon",function(o){var i=t(o.target).data(),a=e.mapHoverType,s=e.hoverText;t(a?".timezone-map polygon[data-"+a+'="'+i[a]+'"]':o.currentTarget),n.$el.find(".hover-text p").addClass("active").text(s&&s instanceof Function?s(o,i):i.timezone+" ("+i.zonename+")")}),this.$el.on("mouseleave","svg polygon",function(e){n.$el.find(".hover-text p").removeClass("active").text("")}),this.$el.on("click","svg polygon",function(e){n.setValue(t(e.target).data("timezone")),n.$el.trigger("map:country:clicked")}),this.$el.on("change","select",function(e,o){o&&o.manually||(n.setValue(t(e.target).val()),n.$el.trigger("map:option:changed"))}),this.$el.on("click",".quick-link span",function(e){var o=t(e.target).data("select");o.search("/")>0?n.setValue(o,"timezone"):n.setValue(o,"zonename"),n.$el.trigger("map:quickLink:clicked")})}}]),n}(),i.DEFAULTS={width:500,height:250,defaultValue:null,mapHoverType:null,quickLinkClass:"",quickLink:[{IST:"IST",LONDON:"Europe/London"}],selectBox:!0,selectClass:"",filterBoxClass:"",showHoverText:!0,hoverTextClass:"",hoverTextEl:null,hoverText:null,dayLightSaving:"function"==typeof e},a);n.default=l,(0,m.default)({pluginName:"timezonePicker",classRef:l})}).call(this,o(7),o(0))},function(e,n,o){e.exports=o(8)},function(e,n){}])}); 18 | -------------------------------------------------------------------------------- /example/index-external-vendor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Select timezone using world map 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "timezone-picker", 3 | "version": "2.0.0-1", 4 | "description": "Select your timezone using world map", 5 | "main": "dist/timezone-picker.min.js", 6 | "scripts": { 7 | "dev": "cross-env NODE_ENV=development webpack-dev-server --progress --inline --hot --open --mode development", 8 | "prod": "cross-env NODE_ENV=production webpack --mode production " 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/kevalbhatt/timezone-picker.git" 13 | }, 14 | "keywords": [ 15 | "jquery-timezone", 16 | "select", 17 | "timezone", 18 | "UI", 19 | "timezone", 20 | "picker" 21 | ], 22 | "author": "Keval Bhatt", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/kevalbhatt/timezone-picker/issues" 26 | }, 27 | "homepage": "https://github.com/kevalbhatt/timezone-picker#readme", 28 | "dependencies": { 29 | "jquery": "^3.3.1", 30 | "moment-timezone": "^0.5.17", 31 | "select2": "^4.0.6-rc.1" 32 | }, 33 | "devDependencies": { 34 | "babel": "^6.23.0", 35 | "babel-core": "^6.26.3", 36 | "babel-loader": "^7.1.4", 37 | "babel-plugin-add-module-exports": "^0.2.1", 38 | "babel-plugin-module-resolver": "^3.1.1", 39 | "babel-plugin-transform-class-properties": "^6.24.1", 40 | "babel-plugin-transform-decorators-legacy": "^1.3.5", 41 | "babel-plugin-transform-flow-strip-types": "^6.22.0", 42 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 43 | "babel-preset-env": "^1.7.0", 44 | "clean-webpack-plugin": "^0.1.19", 45 | "cross-env": "^5.1.6", 46 | "css-loader": "^0.28.11", 47 | "expose-loader": "^0.7.5", 48 | "extract-text-webpack-plugin": "^4.0.0-beta.0", 49 | "html-webpack-plugin": "^3.2.0", 50 | "node-sass": "^4.9.0", 51 | "sass-loader": "^7.0.3", 52 | "webpack": "^4.12.0", 53 | "webpack-cli": "^3.0.3", 54 | "webpack-dev-server": "^3.1.4" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/TimezonePicker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @version: v2.0.0-0 3 | * @author: Keval Bhatt 4 | * @copyright: Copyright (c) 2015 Keval Bhatt. All rights reserved. 5 | * @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php 6 | * @website: http://kevalbhatt.github.io/timezone-picker/ 7 | */ 8 | 'use strict'; 9 | 10 | import timezones from 'timezones.json'; 11 | import { findValue, generateElement } from 'utils/Utils'; 12 | import Plugin from 'utils/Plugin'; 13 | import 'select2'; 14 | import 'select2/dist/css/select2.css'; 15 | 16 | import 'styles/style'; 17 | 18 | export default class TimezonePicker { 19 | static VERSION: "v2.0.0-0" 20 | 21 | static DEFAULTS = { 22 | width: 500, 23 | height: 250, 24 | defaultValue: null, 25 | mapHoverType: null, 26 | quickLinkClass: "", 27 | quickLink: [{ 28 | "IST": "IST", 29 | "LONDON": "Europe/London" 30 | }], 31 | selectBox: true, 32 | selectClass: "", 33 | filterBoxClass: "", 34 | showHoverText: true, 35 | hoverTextClass: "", 36 | hoverTextEl: null, 37 | hoverText: null, 38 | dayLightSaving: ((typeof moment == "function") ? (true) : (false)) 39 | } 40 | 41 | constructor(element, options) { 42 | this.$el = element; 43 | this.generateMap(options); 44 | if (options.defaultValue) { 45 | if (typeof options.defaultValue == "object") { 46 | let { value, attribute } = options.defaultValue; 47 | this.setValue(value, attribute); 48 | } else { 49 | this.setValue(options.defaultValue); 50 | } 51 | } else { 52 | let timezoneObj = this.getSystemTimezone()[0]; 53 | if (timezoneObj) { 54 | this.setValue(timezoneObj.timezone); 55 | } 56 | } 57 | } 58 | /** 59 | * [getTimeZoneObject returns timezone object based on value and attribute, default attribute is timezone] 60 | * @param {[String]} value [description] 61 | * @param {[String]} attribute [description] 62 | * @return {[Array]} [description] 63 | */ 64 | getTimeZoneObject(value, attribute) { 65 | return findValue(attribute ? attribute : 'timezone', value, this.timezone) 66 | } 67 | /** 68 | * [getSystemTimezone return system timezone object] 69 | * @return {[Object]} [description] 70 | */ 71 | getSystemTimezone() { 72 | var timezone = moment.tz.guess(); 73 | return this.getTimeZoneObject(timezone) 74 | } 75 | /** 76 | * [getZoneName return zonename based on value and attribute, default attribute is timezone] 77 | * @param {[String]} value [description] 78 | * @param {[String]} attribute [description] 79 | * @return {[String]} [description] 80 | */ 81 | getZoneName(value, attribute) { 82 | return this.getTimeZoneObject(value, attribute).zonename 83 | } 84 | /** 85 | * [getTimeZoneString return timezone based on value and attribute, default attribute is timezone] 86 | * @param {[String]} value [description] 87 | * @param {[String]} attribute [description] 88 | * @return {[String]} 89 | */ 90 | getTimeZoneString(value, attribute) { 91 | return this.getTimeZoneObject(value, attribute ? attribute : "country").timezone 92 | } 93 | /** 94 | * [setValue set value in map] 95 | * @param {[type]} value [attribute value] 96 | * @param {[type]} attribute [attribute name] 97 | */ 98 | setValue(value, attribute) { 99 | this.$el.find('svg polygon').attr('data-selected', 'false'); 100 | let elements = this.$el.find('svg polygon[data-' + (attribute ? attribute : "timezone") + '="' + value + '"]'); 101 | if (elements && elements.length) { 102 | elements.attr('data-selected', 'true'); 103 | this.$el.find("select.country-lov").val(elements.data('timezone')).trigger('change', { manually: true }); 104 | this.$el.find('.quick-link span').removeClass('active'); 105 | this.$el.find('.quick-link').children('[data-select="' + elements.data('zonename') + '"],[data-select="' + elements.data('timezone') + '"],[data-select="' + elements.data('country') + '"]').addClass('active'); 106 | } 107 | this.$el.trigger("map:value:changed"); 108 | } 109 | /** 110 | * [getValue get selected value array] 111 | * @return {[Array]} [description] 112 | */ 113 | getValue() { 114 | var value = []; 115 | this.$el.find('svg polygon[data-selected="true"]').map(function(index, el) { 116 | value.push($(el).data()); 117 | }); 118 | return value; 119 | } 120 | /** 121 | * [generateMap create element dynamically] 122 | * @param {[Object]} options [depanding on option it will create elements] 123 | * @return {[Null]} [description] 124 | */ 125 | generateMap(options) { 126 | 127 | var polygon = [], 128 | option = [], 129 | quickLink = [], 130 | containerArr = []; 131 | this.timezone = Object.assign([], timezones); 132 | var timezone = this.timezone; 133 | for (var index in timezone) { 134 | 135 | let zoneObj = timezone[index]; 136 | if (moment) { 137 | /** 138 | * [replace zonename and timezone value with moment value 139 | */ 140 | var momentObj = moment().tz(zoneObj.timezone); 141 | zoneObj.zonename = momentObj.zoneName(); 142 | zoneObj.timezone = momentObj._z.name 143 | } 144 | polygon.push(generateElement({ 145 | element: 'polygon', 146 | attr: { 147 | 'data-timezone': timezone[index].timezone, 148 | 'data-country': timezone[index].country, 149 | 'data-pin': timezone[index].pin, 150 | 'data-offset': timezone[index].offset, 151 | 'points': timezone[index].points, 152 | 'data-zonename': timezone[index].zonename 153 | }, 154 | isSvg: true 155 | })); 156 | 157 | option.push(generateElement({ 158 | element: 'option', 159 | attr: { 160 | 'value': timezone[index].timezone 161 | }, 162 | chilled: timezone[index].timezone + " (" + timezone[index].zonename + ")" 163 | })); 164 | } 165 | if (options.selectBox) { 166 | var select = generateElement({ 167 | element: 'select', 168 | attr: { 169 | 'class': (options.selectClass + ' country-lov').trim(), 170 | }, 171 | chilled: option 172 | }); 173 | containerArr.push(select); 174 | } 175 | 176 | 177 | if (options.quickLink.length > 0) { 178 | for (var index in options.quickLink[0]) { 179 | quickLink.push(generateElement({ 180 | element: 'span', 181 | attr: { 182 | 'data-select': options.quickLink[0][index] 183 | }, 184 | chilled: index 185 | })); 186 | } 187 | var qickLinkDiv = generateElement({ 188 | element: 'div', 189 | attr: { 190 | 'class': (options.quickLinkClass + ' quick-link').trim() 191 | }, 192 | chilled: quickLink 193 | }); 194 | containerArr.push(qickLinkDiv); 195 | } 196 | 197 | if (options.showHoverText) { 198 | var content = generateElement({ 199 | element: 'p' 200 | }); 201 | var hoverZone = generateElement({ 202 | element: 'div', 203 | attr: { 204 | 'class': (options.hoverTextClass + ' hover-text').trim(), 205 | }, 206 | chilled: content 207 | }); 208 | if (options.hoverTextEl) { 209 | options.hoverTextEl.append(hoverZone); 210 | } else { 211 | containerArr.push(hoverZone); 212 | } 213 | } 214 | 215 | var svg = generateElement({ 216 | element: 'svg', 217 | attr: { 218 | 'class': 'timezone-map', 219 | 'viewBox': '0 0 ' + options.width + ' ' + options.height 220 | }, 221 | chilled: polygon, 222 | isSvg: true 223 | }); 224 | 225 | if (containerArr.length > 0) { 226 | var container = generateElement({ 227 | element: 'div', 228 | attr: { 229 | 'class': (options.filterBoxClass + ' filter-box').trim() 230 | }, 231 | chilled: containerArr 232 | }); 233 | this.$el.append(container); 234 | if ($.fn.select2) { 235 | $('.country-lov').select2(); 236 | } 237 | } 238 | 239 | this.$el.append(svg); 240 | 241 | this.bindEvent(options); 242 | 243 | } 244 | /** 245 | * [bindEvent bind all event i.e click,mouseenter,mouseleave,change(select)] 246 | * @return {[type]} [description] 247 | */ 248 | bindEvent(options) { 249 | this.$el.on('mouseenter', 'svg polygon', (e) => { 250 | var el = null, 251 | data = $(e.target).data(), 252 | hoverKey = options.mapHoverType, 253 | hoverText = options.hoverText; 254 | if (hoverKey) { 255 | el = $('.timezone-map polygon[data-' + hoverKey + '="' + data[hoverKey] + '"]'); 256 | } else { 257 | el = $(e.currentTarget); 258 | } 259 | this.$el.find('.hover-text p').addClass('active').text(hoverText && hoverText instanceof Function ? hoverText(e, data) : (data.timezone + " (" + data.zonename + ")")); 260 | }); 261 | this.$el.on('mouseleave', 'svg polygon', (e) => { 262 | this.$el.find('.hover-text p').removeClass('active').text(''); 263 | }); 264 | this.$el.on('click', 'svg polygon', (e) => { 265 | this.setValue($(e.target).data('timezone')); 266 | this.$el.trigger("map:country:clicked"); 267 | }); 268 | this.$el.on('change', 'select', (e, options) => { 269 | if (!options || !options.manually) { 270 | this.setValue($(e.target).val()); 271 | this.$el.trigger("map:option:changed"); 272 | } 273 | }); 274 | this.$el.on('click', '.quick-link span', (e) => { 275 | var selectValue = $(e.target).data('select'); 276 | if (selectValue.search('/') > 0) { 277 | this.setValue(selectValue, 'timezone'); 278 | } else { 279 | this.setValue(selectValue, 'zonename'); 280 | } 281 | this.$el.trigger("map:quickLink:clicked"); 282 | }); 283 | } 284 | } 285 | 286 | Plugin({ pluginName: "timezonePicker", classRef: TimezonePicker }); -------------------------------------------------------------------------------- /src/index-external-vendor.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Select timezone using world map 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Select timezone using world map 6 | 7 | 8 | 9 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/styles/_colors.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * @version: v2.0.0-1 3 | * @author: Keval Bhatt 4 | * @copyright: Copyright (c) 2015 Keval Bhatt. All rights reserved. 5 | * @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php 6 | * @website: http://kevalbhatt.github.io/timezone-picker/ 7 | */ 8 | 9 | $light_blue: #9ddaf8; 10 | $country_background:#262626; 11 | $country_stroke:#959595; 12 | $active: #ffa500; 13 | $white: #fff; 14 | $black:#000; -------------------------------------------------------------------------------- /src/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * @version: v2.0.0-1 3 | * @author: Keval Bhatt 4 | * @copyright: Copyright (c) 2015 Keval Bhatt. All rights reserved. 5 | * @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php 6 | * @website: http://kevalbhatt.github.io/timezone-picker/ 7 | */ 8 | 9 | @import 'colors'; 10 | 11 | body.example { 12 | background-color: $light_blue; 13 | } 14 | 15 | .timezone-map { 16 | polygon { 17 | fill: $country_background; 18 | stroke-width: 0.5; 19 | stroke: $country_stroke; 20 | &[data-selected="true"] { 21 | fill: $active; 22 | stroke: $active; 23 | } 24 | &:hover { 25 | stroke: $active; 26 | fill: $active; 27 | cursor: pointer; 28 | } 29 | } 30 | } 31 | 32 | .filter-box { 33 | &>* { 34 | float: left; 35 | height: 24px; 36 | } 37 | select { 38 | width: 45%; 39 | padding: 0px 0px 0px 10px; 40 | } 41 | .quick-link { 42 | width: 52%; 43 | overflow-x: auto; 44 | white-space: nowrap; 45 | overflow-y: hidden; 46 | span { 47 | font-weight: 300; 48 | border-radius: 3px; 49 | color: $black; 50 | background-color: $white; 51 | border: solid 1px $black; 52 | margin-left: 10px; 53 | font-size: 9px; 54 | padding: 4px 6px 4px 6px; 55 | &.active { 56 | color: $white; 57 | background-color: $active; 58 | } 59 | &:hover { 60 | color: $white; 61 | background-color: $active; 62 | cursor: pointer; 63 | } 64 | } 65 | } 66 | .hover-text { 67 | height: 20px; 68 | width: 100%; 69 | padding: 10px; 70 | p { 71 | opacity: 0; 72 | text-align: center; 73 | transform: scale(10); 74 | transition: all 0.3s ease-in-out 0.2s; 75 | &.active { 76 | opacity: 1; 77 | transform: scale(1); 78 | transition: all 0.3s ease-in-out 0.1s; 79 | } 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /src/utils/Plugin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @version: v2.0.0-1 3 | * @author: Keval Bhatt 4 | * @copyright: Copyright (c) 2015 Keval Bhatt. All rights reserved. 5 | * @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php 6 | * @website: http://kevalbhatt.github.io/timezone-picker/ 7 | */ 8 | 9 | /** 10 | * [plugin register jquery plugin] 11 | * @param {[string]} options.name [Plugin name] 12 | * @param {[object]} options.classRef [Class object] 13 | * @param {Boolean} options.shortHand [Generate a shorthand as $.pluginName] 14 | * @return {[type]} [description] 15 | */ 16 | 17 | export default function plugin({ pluginName, classRef, shortHand = false }) { 18 | let dataName = `${pluginName}`; 19 | let old = $.fn[pluginName]; 20 | 21 | $.fn[pluginName] = function(option) { 22 | return this.each(function() { 23 | let $this = $(this); 24 | let data = $this.data(dataName); 25 | let options = $.extend({}, classRef.DEFAULTS, $this.data(), typeof option === 'object' && option); 26 | 27 | if (!data) { 28 | $this.data(dataName, (data = new classRef($this, options))); 29 | } 30 | 31 | if (typeof option === 'string') { 32 | data[option](); 33 | } 34 | }); 35 | }; 36 | 37 | // - Short hand 38 | if (shortHand) { 39 | $[pluginName] = (options) => $({})[pluginName](options); 40 | } 41 | 42 | // - No conflict 43 | $.fn[pluginName].noConflict = () => $.fn[pluginName] = old; 44 | } -------------------------------------------------------------------------------- /src/utils/Utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @version: v2.0.0-1 3 | * @author: Keval Bhatt 4 | * @copyright: Copyright (c) 2015 Keval Bhatt. All rights reserved. 5 | * @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php 6 | * @website: http://kevalbhatt.github.io/timezone-picker/ 7 | */ 8 | 9 | const findValue = function(key, value, data) { 10 | var referObj = []; 11 | var obj = data.filter(function(object) { 12 | if (object[key] === value) { 13 | referObj.push($.extend(true, {}, object)); 14 | return object; 15 | } 16 | }); 17 | for (var i = 0; i < referObj.length; i++) { 18 | delete referObj[i].points; 19 | delete referObj[i].pin; 20 | } 21 | return referObj; 22 | } 23 | 24 | 25 | /** 26 | * [generateElement description] 27 | * @param {[Jquery Object]} element [selector] 28 | * @param {[type]} attr [description] 29 | * @param {[javascript Object or text]} chilled [If we pass javascript object or array it will append all chilled and if you pass string it will add string(value) inside element ] 30 | * @param {Boolean} isSvg [If it is svg then it will create svg element] 31 | * @return {[type]} [description] 32 | */ 33 | const generateElement = function({ element, attr, chilled = false, isSvg = false }) { 34 | if (isSvg) { 35 | var elementObject = document.createElementNS('http://www.w3.org/2000/svg', element); 36 | } else { 37 | var elementObject = document.createElement(element); 38 | } 39 | if (attr) { 40 | for (var key in attr) { 41 | elementObject.setAttribute(key, attr[key]); 42 | } 43 | } 44 | if (chilled) { 45 | if (chilled instanceof Array) { 46 | for (var chilleds in chilled) { 47 | elementObject.appendChild(chilled[chilleds]); 48 | } 49 | } else if (typeof chilled == 'string') { 50 | elementObject.innerHTML = chilled; 51 | } else { 52 | elementObject.appendChild(chilled); 53 | } 54 | 55 | } 56 | return elementObject; 57 | } 58 | 59 | export { 60 | generateElement, 61 | findValue 62 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'), 2 | webpack = require('webpack'), 3 | CleanWebpackPlugin = require('clean-webpack-plugin'), 4 | HtmlWebpackPlugin = require("Html-webpack-plugin"), 5 | ExtractTextPlugin = require('extract-text-webpack-plugin'); 6 | 7 | // Create multiple instances 8 | const extractApp = new ExtractTextPlugin('styles/[name].css'); 9 | const extractVendor = new ExtractTextPlugin('styles/[name]-vendor.css'); 10 | 11 | 12 | var ENV = process.env.NODE_ENV, 13 | buildType = process.env.BUILD_TYPE, 14 | isProd = ( 15 | ENV === "production" ? 16 | true : 17 | false), 18 | BUILD_DIR = path.resolve(__dirname, 'dist'), 19 | ROOT_DIR = path.resolve(__dirname), 20 | EXAMPLE_DIR = path.resolve(__dirname, 'example'), 21 | APP_DIR = path.resolve(__dirname, 'src'), 22 | NODE_MODULES = path.resolve(__dirname, 'node_modules'), 23 | pathsToClean = [BUILD_DIR, EXAMPLE_DIR], 24 | config = { 25 | entry: { 26 | "timezone-picker": [APP_DIR + "/TimezonePicker.js"] 27 | }, 28 | output: { 29 | path: ( 30 | isProd ? 31 | BUILD_DIR : 32 | ROOT_DIR), //<- This path is use at build time 33 | filename: "[name].min.js", //<- This file is created under path which we specified in output.path 34 | chunkFilename: '[name].min.js', 35 | library: "TimezonePicker", 36 | libraryTarget: 'umd' 37 | }, 38 | plugins: [ 39 | new CleanWebpackPlugin(pathsToClean, { 40 | root: ROOT_DIR, 41 | verbose: true 42 | }), 43 | extractApp, 44 | new webpack.DefinePlugin({ 'isProd': isProd }), 45 | new webpack.ProvidePlugin({ 46 | $: 'jquery', 47 | jQuery: 'jquery', 48 | moment: "moment-timezone", 49 | select2: 'select2' 50 | }) 51 | ], 52 | resolve: { 53 | modules: [ 54 | APP_DIR, NODE_MODULES 55 | ], 56 | extensions: [ 57 | '.js', 58 | '.jsx', 59 | '.html', 60 | '.css', 61 | '.scss' 62 | ] 63 | }, 64 | module: { 65 | rules: [{ 66 | test: /\.jsx($|\?)|\.js($|\?)/, 67 | exclude: /node_modules/, 68 | include: [ 69 | APP_DIR, ROOT_DIR 70 | ], 71 | use: [{ 72 | loader: "babel-loader", 73 | query: { 74 | presets: [ 75 | "env" 76 | ], 77 | plugins: ["transform-decorators-legacy", "transform-flow-strip-types", "transform-class-properties", "transform-object-rest-spread"] 78 | } 79 | }] 80 | }, { 81 | test: /\.css$/, 82 | use: extractVendor.extract({ 83 | use: [{ 84 | loader: "css-loader", 85 | options: { 86 | minimize: isProd, 87 | includePaths: [ 88 | NODE_MODULES 89 | ] 90 | } 91 | }] 92 | }) 93 | 94 | }, 95 | { 96 | test: /\.scss$/, 97 | use: extractApp.extract({ 98 | use: [{ 99 | loader: "css-loader", 100 | options: { 101 | minimize: isProd 102 | } 103 | }, { 104 | loader: "sass-loader", 105 | options: { 106 | includePaths: [ 107 | APP_DIR + "/styles" 108 | ] 109 | } 110 | }] 111 | }) 112 | }, 113 | { 114 | test: require.resolve('select2'), 115 | use: [{ 116 | loader: 'expose-loader', 117 | options: 'select2' 118 | }] 119 | }, 120 | { 121 | test: require.resolve('moment'), 122 | use: [{ 123 | loader: 'expose-loader', 124 | options: 'moment' 125 | }] 126 | }, 127 | { 128 | test: require.resolve('jquery'), 129 | use: [{ 130 | loader: 'expose-loader', 131 | options: 'jQuery' 132 | }, { 133 | loader: 'expose-loader', 134 | options: '$' 135 | }] 136 | } 137 | ] 138 | }, 139 | devServer: { 140 | port: 9099, 141 | host: "0.0.0.0", 142 | disableHostCheck: true 143 | } 144 | }; 145 | var mainHtml = new HtmlWebpackPlugin({ 146 | title: 'timezone-picker', 147 | template: (APP_DIR) + '/index.ejs', 148 | chunks: ['timezone-picker'], 149 | filename: ( 150 | isProd ? 151 | BUILD_DIR : 152 | ROOT_DIR) + '/index.html' 153 | }); 154 | var externalVendorHtml = new HtmlWebpackPlugin({ 155 | title: 'timezone-external-vendor', 156 | template: (APP_DIR) + '/index-external-vendor.ejs', 157 | chunks: ['timezone-picker'], 158 | filename: ( 159 | isProd ? 160 | ROOT_DIR + "/example" : 161 | ROOT_DIR) + '/index-external-vendor.html' 162 | }); 163 | if (!isProd) { 164 | config['devtool'] = 'inline-source-map'; 165 | config['cache'] = true; 166 | config.plugins.push(extractVendor, mainHtml, externalVendorHtml); 167 | } else { 168 | config["externals"] = { 169 | jquery: 'jQuery', 170 | "moment-timezone": "moment-timezone", 171 | select2: "select2" 172 | } 173 | config.plugins.push(externalVendorHtml); 174 | } 175 | module.exports = config; --------------------------------------------------------------------------------