[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 /************************ 2 jquery-timepicker 3 http://jonthornton.github.com/jquery-timepicker/ 4 5 requires jQuery 1.7+ 6 ************************/ 7 8 9 (function (factory) { 10 if (typeof define === 'function' && define.amd) { 11 // AMD. Register as an anonymous module. 12 define(['jquery'], factory); 13 } else { 14 // Browser globals 15 factory(jQuery); 16 } 17 }(function ($) { 18 var _baseDate = _generateBaseDate(); 19 var _ONE_DAY = 86400; 20 var _closeEvent = 'ontouchstart' in document ? 'touchstart' : 'mousedown'; 21 var _defaults = { 22 className: null, 23 minTime: null, 24 maxTime: null, 25 durationTime: null, 26 step: 30, 27 showDuration: false, 28 timeFormat: 'g:ia', 29 scrollDefaultNow: false, 30 scrollDefaultTime: false, 31 selectOnBlur: false, 32 appendTo: 'body' 33 }; 34 var _lang = { 35 decimal: '.', 36 mins: 'mins', 37 hr: 'hr', 38 hrs: 'hrs' 39 }; 40 var globalInit = false; 41 42 var methods = 43 { 44 init: function(options) 45 { 46 return this.each(function() 47 { 48 var self = $(this); 49 50 // convert dropdowns to text input 51 if (self[0].tagName == 'SELECT') { 52 var input = $('<input />'); 53 var attrs = { 'type': 'text', 'value': self.val() }; 54 var raw_attrs = self[0].attributes; 55 56 for (var i=0; i < raw_attrs.length; i++) { 57 attrs[raw_attrs[i].nodeName] = raw_attrs[i].nodeValue; 58 } 59 60 input.attr(attrs); 61 self.replaceWith(input); 62 self = input; 63 } 64 65 var settings = $.extend({}, _defaults); 66 67 if (options) { 68 settings = $.extend(settings, options); 69 } 70 71 if (settings.minTime) { 72 settings.minTime = _time2int(settings.minTime); 73 } 74 75 if (settings.maxTime) { 76 settings.maxTime = _time2int(settings.maxTime); 77 } 78 79 if (settings.durationTime) { 80 settings.durationTime = _time2int(settings.durationTime); 81 } 82 83 if (settings.lang) { 84 _lang = $.extend(_lang, settings.lang); 85 } 86 87 self.data('timepicker-settings', settings); 88 self.attr('autocomplete', 'off'); 89 self.on('click.timepicker focus.timepicker', methods.show); 90 self.on('blur.timepicker', _formatValue); 91 self.on('keydown.timepicker', _keyhandler); 92 self.addClass('ui-timepicker-input'); 93 94 _formatValue.call(self.get(0)); 95 96 if (!globalInit) { 97 // close the dropdown when container loses focus 98 $('body').on(_closeEvent, function(e) { 99 var target = $(e.target); 100 var input = target.closest('.ui-timepicker-input'); 101 if (input.length === 0 && target.closest('.ui-timepicker-list').length === 0) { 102 methods.hide(); 103 } 104 }); 105 globalInit = true; 106 } 107 }); 108 }, 109 110 show: function(e) 111 { 112 var self = $(this); 113 114 if ('ontouchstart' in document) { 115 // block the keyboard on mobile devices 116 self.blur(); 117 } 118 119 var list = self.data('timepicker-list'); 120 121 // check if input is readonly 122 if (self.attr('readonly')) { 123 return; 124 } 125 126 // check if list needs to be rendered 127 if (!list || list.length === 0) { 128 _render(self); 129 list = self.data('timepicker-list'); 130 } 131 132 // check if a flag was set to close this picker 133 if (self.hasClass('ui-timepicker-hideme')) { 134 self.removeClass('ui-timepicker-hideme'); 135 list.hide(); 136 return; 137 } 138 139 if (list.is(':visible')) { 140 return; 141 } 142 143 // make sure other pickers are hidden 144 methods.hide(); 145 146 if ((self.offset().top + self.outerHeight(true) + list.outerHeight()) > $(window).height() + $(window).scrollTop()) { 147 // position the dropdown on top 148 list.css({ 'left':(self.offset().left), 'top': self.offset().top - list.outerHeight() }); 149 } else { 150 // put it under the input 151 list.css({ 'left':(self.offset().left), 'top': self.offset().top + self.outerHeight() }); 152 } 153 154 list.show(); 155 156 var settings = self.data('timepicker-settings'); 157 // position scrolling 158 var selected = list.find('.ui-timepicker-selected'); 159 160 if (!selected.length) { 161 if (self.val()) { 162 selected = _findRow(self, list, _time2int(self.val())); 163 } else if (settings.scrollDefaultNow) { 164 selected = _findRow(self, list, _time2int(new Date())); 165 } else if (settings.scrollDefaultTime !== false) { 166 selected = _findRow(self, list, _time2int(settings.scrollDefaultTime)); 167 } 168 } 169 170 if (selected && selected.length) { 171 var topOffset = list.scrollTop() + selected.position().top - selected.outerHeight(); 172 list.scrollTop(topOffset); 173 } else { 174 list.scrollTop(0); 175 } 176 177 self.trigger('showTimepicker'); 178 }, 179 180 hide: function(e) 181 { 182 $('.ui-timepicker-list:visible').each(function() { 183 var list = $(this); 184 var self = list.data('timepicker-input'); 185 var settings = self.data('timepicker-settings'); 186 187 if (settings && settings.selectOnBlur) { 188 _selectValue(self); 189 } 190 191 list.hide(); 192 self.trigger('hideTimepicker'); 193 }); 194 }, 195 196 option: function(key, value) 197 { 198 var self = $(this); 199 var settings = self.data('timepicker-settings'); 200 var list = self.data('timepicker-list'); 201 202 if (typeof key == 'object') { 203 settings = $.extend(settings, key); 204 205 } else if (typeof key == 'string' && typeof value != 'undefined') { 206 settings[key] = value; 207 208 } else if (typeof key == 'string') { 209 return settings[key]; 210 } 211 212 if (settings.minTime) { 213 settings.minTime = _time2int(settings.minTime); 214 } 215 216 if (settings.maxTime) { 217 settings.maxTime = _time2int(settings.maxTime); 218 } 219 220 if (settings.durationTime) { 221 settings.durationTime = _time2int(settings.durationTime); 222 } 223 224 self.data('timepicker-settings', settings); 225 226 if (list) { 227 list.remove(); 228 self.data('timepicker-list', false); 229 } 230 231 }, 232 233 getSecondsFromMidnight: function() 234 { 235 return _time2int($(this).val()); 236 }, 237 238 getTime: function() 239 { 240 return new Date(_baseDate.valueOf() + (_time2int($(this).val())*1000)); 241 }, 242 243 setTime: function(value) 244 { 245 var self = $(this); 246 var prettyTime = _int2time(_time2int(value), self.data('timepicker-settings').timeFormat); 247 self.val(prettyTime); 248 }, 249 250 remove: function() 251 { 252 var self = $(this); 253 254 // check if this element is a timepicker 255 if (!self.hasClass('ui-timepicker-input')) { 256 return; 257 } 258 259 self.removeAttr('autocomplete', 'off'); 260 self.removeClass('ui-timepicker-input'); 261 self.removeData('timepicker-settings'); 262 self.off('.timepicker'); 263 264 // timepicker-list won't be present unless the user has interacted with this timepicker 265 if (self.data('timepicker-list')) { 266 self.data('timepicker-list').remove(); 267 } 268 269 self.removeData('timepicker-list'); 270 } 271 }; 272 273 // private methods 274 275 function _render(self) 276 { 277 var settings = self.data('timepicker-settings'); 278 var list = self.data('timepicker-list'); 279 280 if (list && list.length) { 281 list.remove(); 282 self.data('timepicker-list', false); 283 } 284 285 list = $('<ul />'); 286 list.attr('tabindex', -1); 287 list.addClass('ui-timepicker-list'); 288 if (settings.className) { 289 list.addClass(settings.className); 290 } 291 292 list.css({'display':'none', 'position': 'absolute' }); 293 294 if (settings.minTime !== null && settings.showDuration) { 295 list.addClass('ui-timepicker-with-duration'); 296 } 297 298 var durStart = (settings.durationTime !== null) ? settings.durationTime : settings.minTime; 299 var start = (settings.minTime !== null) ? settings.minTime : 0; 300 var end = (settings.maxTime !== null) ? settings.maxTime : (start + _ONE_DAY - 1); 301 302 if (end <= start) { 303 // make sure the end time is greater than start time, otherwise there will be no list to show 304 end += _ONE_DAY; 305 } 306 307 for (var i=start; i <= end; i += settings.step*60) { 308 var timeInt = i%_ONE_DAY; 309 var row = $('<li />'); 310 row.data('time', timeInt); 311 row.text(_int2time(timeInt, settings.timeFormat)); 312 313 if (settings.minTime !== null && settings.showDuration) { 314 var duration = $('<span />'); 315 duration.addClass('ui-timepicker-duration'); 316 duration.text(' ('+_int2duration(i - durStart)+')'); 317 row.append(duration); 318 } 319 320 list.append(row); 321 } 322 323 list.data('timepicker-input', self); 324 self.data('timepicker-list', list); 325 326 var appendTo = settings.appendTo; 327 if (typeof appendTo === 'string') { 328 appendTo = $(appendTo); 329 } else if (typeof appendTo === 'function') { 330 appendTo = appendTo(self); 331 } 332 appendTo.append(list); 333 _setSelected(self, list); 334 335 list.on('click', 'li', function(e) { 336 self.addClass('ui-timepicker-hideme'); 337 self[0].focus(); 338 339 // make sure only the clicked row is selected 340 list.find('li').removeClass('ui-timepicker-selected'); 341 $(this).addClass('ui-timepicker-selected'); 342 343 _selectValue(self); 344 list.hide(); 345 }); 346 } 347 348 function _generateBaseDate() 349 { 350 var _baseDate = new Date(); 351 var _currentTimezoneOffset = _baseDate.getTimezoneOffset()*60000; 352 _baseDate.setHours(0); _baseDate.setMinutes(0); _baseDate.setSeconds(0); 353 var _baseDateTimezoneOffset = _baseDate.getTimezoneOffset()*60000; 354 355 return new Date(_baseDate.valueOf() - _baseDateTimezoneOffset + _currentTimezoneOffset); 356 } 357 358 function _findRow(self, list, value) 359 { 360 if (!value && value !== 0) { 361 return false; 362 } 363 364 var settings = self.data('timepicker-settings'); 365 var out = false; 366 367 // loop through the menu items 368 list.find('li').each(function(i, obj) { 369 var jObj = $(obj); 370 371 // check if the value is less than half a step from each row 372 if (Math.abs(jObj.data('time') - value) <= settings.step*30) { 373 out = jObj; 374 return false; 375 } 376 }); 377 378 return out; 379 } 380 381 function _setSelected(self, list) 382 { 383 var timeValue = _time2int(self.val()); 384 385 var selected = _findRow(self, list, timeValue); 386 if (selected) selected.addClass('ui-timepicker-selected'); 387 } 388 389 390 function _formatValue() 391 { 392 if (this.value === '') { 393 return; 394 } 395 396 var self = $(this); 397 var timeInt = _time2int(this.value); 398 399 if (timeInt === null) { 400 self.trigger('timeFormatError'); 401 return; 402 } 403 404 var prettyTime = _int2time(timeInt, self.data('timepicker-settings').timeFormat); 405 self.val(prettyTime); 406 } 407 408 function _keyhandler(e) 409 { 410 var self = $(this); 411 var list = self.data('timepicker-list'); 412 413 if (!list.is(':visible')) { 414 if (e.keyCode == 40) { 415 self.focus(); 416 } else { 417 return true; 418 } 419 } 420 421 switch (e.keyCode) { 422 423 case 13: // return 424 _selectValue(self); 425 methods.hide.apply(this); 426 e.preventDefault(); 427 return false; 428 429 case 38: // up 430 var selected = list.find('.ui-timepicker-selected'); 431 432 if (!selected.length) { 433 list.children().each(function(i, obj) { 434 if ($(obj).position().top > 0) { 435 selected = $(obj); 436 return false; 437 } 438 }); 439 selected.addClass('ui-timepicker-selected'); 440 441 } else if (!selected.is(':first-child')) { 442 selected.removeClass('ui-timepicker-selected'); 443 selected.prev().addClass('ui-timepicker-selected'); 444 445 if (selected.prev().position().top < selected.outerHeight()) { 446 list.scrollTop(list.scrollTop() - selected.outerHeight()); 447 } 448 } 449 450 break; 451 452 case 40: // down 453 selected = list.find('.ui-timepicker-selected'); 454 455 if (selected.length === 0) { 456 list.children().each(function(i, obj) { 457 if ($(obj).position().top > 0) { 458 selected = $(obj); 459 return false; 460 } 461 }); 462 463 selected.addClass('ui-timepicker-selected'); 464 } else if (!selected.is(':last-child')) { 465 selected.removeClass('ui-timepicker-selected'); 466 selected.next().addClass('ui-timepicker-selected'); 467 468 if (selected.next().position().top + 2*selected.outerHeight() > list.outerHeight()) { 469 list.scrollTop(list.scrollTop() + selected.outerHeight()); 470 } 471 } 472 473 break; 474 475 case 27: // escape 476 list.find('li').removeClass('ui-timepicker-selected'); 477 list.hide(); 478 break; 479 480 case 9: //tab 481 methods.hide(); 482 break; 483 484 case 16: 485 case 17: 486 case 18: 487 case 19: 488 case 20: 489 case 33: 490 case 34: 491 case 35: 492 case 36: 493 case 37: 494 case 39: 495 case 45: 496 return; 497 498 default: 499 list.find('li').removeClass('ui-timepicker-selected'); 500 return; 501 } 502 } 503 504 function _selectValue(self) 505 { 506 var settings = self.data('timepicker-settings'); 507 var list = self.data('timepicker-list'); 508 var timeValue = null; 509 510 var cursor = list.find('.ui-timepicker-selected'); 511 512 if (cursor.length) { 513 // selected value found 514 timeValue = cursor.data('time'); 515 516 } else if (self.val()) { 517 518 // no selected value; fall back on input value 519 timeValue = _time2int(self.val()); 520 521 _setSelected(self, list); 522 } 523 524 if (timeValue !== null) { 525 var timeString = _int2time(timeValue, settings.timeFormat); 526 self.attr('value', timeString); 527 } 528 529 self.trigger('change').trigger('changeTime'); 530 } 531 532 function _int2duration(seconds) 533 { 534 var minutes = Math.round(seconds/60); 535 var duration; 536 537 if (minutes < 60) { 538 duration = [minutes, _lang.mins]; 539 } else if (minutes == 60) { 540 duration = ['1', _lang.hr]; 541 } else { 542 var hours = (minutes/60).toFixed(1); 543 if (_lang.decimal != '.') hours = hours.replace('.', _lang.decimal); 544 duration = [hours, _lang.hrs]; 545 } 546 547 return duration.join(' '); 548 } 549 550 function _int2time(seconds, format) 551 { 552 if (seconds === null) { 553 return; 554 } 555 556 var time = new Date(_baseDate.valueOf() + (seconds*1000)); 557 var output = ''; 558 var hour, code; 559 560 for (var i=0; i<format.length; i++) { 561 562 code = format.charAt(i); 563 switch (code) { 564 565 case 'a': 566 output += (time.getHours() > 11) ? 'pm' : 'am'; 567 break; 568 569 case 'A': 570 output += (time.getHours() > 11) ? 'PM' : 'AM'; 571 break; 572 573 case 'g': 574 hour = time.getHours() % 12; 575 output += (hour === 0) ? '12' : hour; 576 break; 577 578 case 'G': 579 output += time.getHours(); 580 break; 581 582 case 'h': 583 hour = time.getHours() % 12; 584 585 if (hour !== 0 && hour < 10) { 586 hour = '0'+hour; 587 } 588 589 output += (hour === 0) ? '12' : hour; 590 break; 591 592 case 'H': 593 hour = time.getHours(); 594 output += (hour > 9) ? hour : '0'+hour; 595 break; 596 597 case 'i': 598 var minutes = time.getMinutes(); 599 output += (minutes > 9) ? minutes : '0'+minutes; 600 break; 601 602 case 's': 603 seconds = time.getSeconds(); 604 output += (seconds > 9) ? seconds : '0'+seconds; 605 break; 606 607 default: 608 output += code; 609 } 610 } 611 612 return output; 613 } 614 615 function _time2int(timeString) 616 { 617 if (timeString === '') return null; 618 if (timeString+0 == timeString) return timeString; 619 620 if (typeof(timeString) == 'object') { 621 timeString = timeString.getHours()+':'+timeString.getMinutes()+':'+timeString.getSeconds(); 622 } 623 624 var d = new Date(0); 625 var time = timeString.toLowerCase().match(/(\d{1,2})(?::(\d{1,2}))?(?::(\d{2}))?\s*([pa]?)/); 626 627 if (!time) { 628 return null; 629 } 630 631 var hour = parseInt(time[1]*1, 10); 632 var hours; 633 634 if (time[4]) { 635 if (hour == 12) { 636 hours = (time[4] == 'p') ? 12 : 0; 637 } else { 638 hours = (hour + (time[4] == 'p' ? 12 : 0)); 639 } 640 641 } else { 642 hours = hour; 643 } 644 645 var minutes = ( time[2]*1 || 0 ); 646 var seconds = ( time[3]*1 || 0 ); 647 return hours*3600 + minutes*60 + seconds; 648 } 649 650 // Plugin entry 651 $.fn.timepicker = function(method) 652 { 653 if(methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } 654 else if(typeof method === "object" || !method) { return methods.init.apply(this, arguments); } 655 else { $.error("Method "+ method + " does not exist on jQuery.timepicker"); } 656 }; 657 }));
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |