Нет описания

jquery.grp_timepicker.js 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /**
  2. * GRAPPELLI TIMEPICKER
  3. * works pretty similar to ui.datepicker:
  4. * adds a button to the element
  5. * creates a node (div) at the bottom called ui-timepicker
  6. * element.onClick fills the ui-timepicker node with the time_list (all times you can select)
  7. */
  8. (function($) {
  9. $.widget("ui.grp_timepicker", {
  10. // default options
  11. options: {
  12. // template for the container of the timepicker
  13. template: '<div id="ui-timepicker" class="module" style="position: absolute; display: none;"></div>',
  14. // selector to get the ui-timepicker once it's added to the dom
  15. timepicker_selector: "#ui-timepicker",
  16. // needed offset of the container from the element
  17. offset: {
  18. top: 0
  19. },
  20. // if time_list wasn't sent when calling the timepicker we use this
  21. default_time_list: [
  22. 'now',
  23. '00:00',
  24. '01:00',
  25. '02:00',
  26. '03:00',
  27. '04:00',
  28. '05:00',
  29. '06:00',
  30. '07:00',
  31. '08:00',
  32. '09:00',
  33. '10:00',
  34. '11:00',
  35. '12:00',
  36. '13:00',
  37. '14:00',
  38. '15:00',
  39. '16:00',
  40. '17:00',
  41. '18:00',
  42. '19:00',
  43. '20:00',
  44. '21:00',
  45. '22:00',
  46. '23:00'
  47. ],
  48. // leave this empty!!!
  49. // NOTE: you can't set a default for time_list because if you call:
  50. // $("node").timepicker({time_list: ["01:00", "02:00"]})
  51. // ui.widget will extend/merge the options.time_list with the one you sent.
  52. time_list: []
  53. },
  54. // init timepicker for a specific element
  55. _create: function() {
  56. // for the events
  57. var self = this;
  58. // to close timpicker if you click somewhere in the document
  59. $(document).on("mousedown", function(evt) {
  60. if (self.timepicker.is(":visible")) {
  61. var $target = $(evt.target);
  62. if ($target[0].id != self.timepicker[0].id && $target.parents(self.options.timepicker_selector).length === 0 && !$target.hasClass('hasTimepicker') && !$target.hasClass('ui-timepicker-trigger')) {
  63. self.timepicker.hide();
  64. }
  65. }
  66. });
  67. // close on esc
  68. $(document).on("keyup", function(e) {
  69. if (e.keyCode == 27) {
  70. self.timepicker.hide();
  71. }
  72. });
  73. // get/create timepicker's container
  74. if ($(this.options.timepicker_selector).length === 0) {
  75. $(this.options.template).appendTo('body');
  76. }
  77. this.timepicker = $(this.options.timepicker_selector);
  78. this.timepicker.hide();
  79. // modify the element and create the button
  80. this.element.addClass("hasTimepicker");
  81. this.button = $('<button type="button" class="ui-timepicker-trigger"></button>');
  82. this.element.after(this.button);
  83. // disable button if element is disabled
  84. if (this.element.prop("disabled")) {
  85. this.button.prop("disabled", true);
  86. } else {
  87. // register event
  88. this.button.on("click", function() {
  89. self._toggleTimepicker();
  90. });
  91. }
  92. },
  93. // called when button is clicked
  94. _toggleTimepicker: function() {
  95. if (this.timepicker.is(":visible")) {
  96. this.timepicker.hide();
  97. } else {
  98. this.element.trigger("focus");
  99. this._generateTimepickerContents();
  100. this._showTimepicker();
  101. }
  102. },
  103. // fills timepicker with time_list of element and shows it.
  104. // called by _toggleTimepicker
  105. _generateTimepickerContents: function() {
  106. var self = this,
  107. template_str = "<ul>";
  108. // there is no time_list for this instance so use the default one
  109. if (this.options.time_list.length === 0) {
  110. this.options.time_list = this.options.default_time_list;
  111. }
  112. for (var i = 0; i < this.options.time_list.length; i++) {
  113. if (this.options.time_list[i] == "now") {
  114. var now = new Date(),
  115. hours = now.getHours(),
  116. minutes = now.getMinutes();
  117. hours = ((hours < 10) ? "0" + hours : hours);
  118. minutes = ((minutes < 10) ? "0" + minutes : minutes);
  119. template_str += '<li class="ui-state-active row">' + hours + ":" + minutes + '</li>';
  120. } else {
  121. template_str += '<li class="ui-state-default row">' + this.options.time_list[i] + '</li>';
  122. }
  123. }
  124. template_str += "</ul>";
  125. // fill timepicker container
  126. this.timepicker.html(template_str);
  127. // click handler for items (times) in timepicker
  128. this.timepicker.find('li').on("click", function() {
  129. // remove active class from all items
  130. $(this).parent().children('li').removeClass("ui-state-active");
  131. // mark clicked item as active
  132. $(this).addClass("ui-state-active");
  133. // set the new value and hide the timepicker
  134. self.element.val($(this).html());
  135. self.timepicker.hide();
  136. });
  137. },
  138. // sets offset and shows timepicker container
  139. _showTimepicker: function() {
  140. var browserHeight = document.documentElement.clientHeight;
  141. var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
  142. var tpInputHeight = this.element.outerHeight();
  143. var tpDialogHeight = this.timepicker.outerHeight() + tpInputHeight;
  144. var offsetTop = this.element.offset().top;
  145. var offsetLeft = this.element.offset().left;
  146. // check the remaining space within the viewport
  147. // 60 counts for fixed header/footer
  148. var checkSpace = offsetTop - scrollY + tpDialogHeight + 60;
  149. // position timepicker below or above the input
  150. if (checkSpace < browserHeight) {
  151. // place the timepicker below input
  152. var below = offsetTop + tpInputHeight;
  153. this.timepicker.css('left', offsetLeft + 'px').css('top', below + 'px');
  154. } else {
  155. // place timepicker above input
  156. var above = offsetTop - tpDialogHeight + tpInputHeight;
  157. this.timepicker.css('left', offsetLeft + 'px').css('top', above + 'px');
  158. }
  159. // show timepicker
  160. this.timepicker.show();
  161. },
  162. destroy: function() {
  163. $.Widget.prototype.destroy.apply(this, arguments); // default destroy
  164. // now do other stuff particular to this widget
  165. }
  166. });
  167. })(grp.jQuery);