├── .gitignore
├── Gemfile
├── lib
├── bootstrap-timepicker-rails
│ ├── version.rb
│ ├── railtie.rb
│ └── engine.rb
└── bootstrap-timepicker-rails.rb
├── bootstrap-timepicker-rails.gemspec
├── Rakefile
├── README.md
└── vendor
└── assets
├── stylesheets
└── bootstrap-timepicker.css
└── javascripts
├── bootstrap-timepicker.js
└── ]
/.gitignore:
--------------------------------------------------------------------------------
1 | Gemfile.lock
2 | *.gem
3 | bootstrap-timepicker-src
4 | *.swp
5 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'http://rubygems.org'
2 |
3 | # Specify your gem's dependencies in bootstrap-rails.gemspec
4 | gemspec
5 |
--------------------------------------------------------------------------------
/lib/bootstrap-timepicker-rails/version.rb:
--------------------------------------------------------------------------------
1 | module BootstrapTimepickerRails
2 | module Rails
3 | VERSION = "0.1.3"
4 | end
5 | end
--------------------------------------------------------------------------------
/lib/bootstrap-timepicker-rails/railtie.rb:
--------------------------------------------------------------------------------
1 | module BootstrapTimepickerRails
2 | module Rails
3 | class Railtie < ::Rails::Railtie; end
4 | end
5 | end
--------------------------------------------------------------------------------
/lib/bootstrap-timepicker-rails/engine.rb:
--------------------------------------------------------------------------------
1 | module BootstrapTimepickerRails
2 | module Rails
3 | class Engine < ::Rails::Engine
4 | end
5 | end
6 | end
--------------------------------------------------------------------------------
/lib/bootstrap-timepicker-rails.rb:
--------------------------------------------------------------------------------
1 | require "rails"
2 | require "bootstrap-timepicker-rails/version"
3 |
4 | module BootstrapTimepickerRails
5 | module Rails
6 | if ::Rails.version < "3.1"
7 | require "bootstrap-timepicker-rails/railtie"
8 | else
9 | require "bootstrap-timepicker-rails/engine"
10 | end
11 | end
12 | end
--------------------------------------------------------------------------------
/bootstrap-timepicker-rails.gemspec:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | require File.expand_path('../lib/bootstrap-timepicker-rails/version', __FILE__)
3 |
4 | Gem::Specification.new do |gem|
5 | gem.authors = ["Pratik Khadloya"]
6 | gem.email = ["tispratik@gmail.com"]
7 | gem.description = %q{Gemified https://github.com/jdewit/bootstrap-timepicker}
8 | gem.homepage = "https://github.com/jdewit/bootstrap-timepicker"
9 | gem.summary = gem.description
10 |
11 | gem.name = "bootstrap-timepicker-rails"
12 | gem.require_paths = ["lib"]
13 | gem.files = `git ls-files`.split("\n")
14 | gem.version = BootstrapTimepickerRails::Rails::VERSION
15 |
16 | gem.add_dependency "railties", ">= 3.0"
17 | gem.add_development_dependency "bundler", ">= 1.0"
18 | gem.add_development_dependency "rake"
19 | end
20 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env rake
2 | require File.expand_path('../lib/bootstrap-timepicker-rails/version', __FILE__)
3 |
4 | desc "Update assets"
5 | task 'update' do
6 |
7 | system("rm -rf bootstrap-timepicker-src")
8 | system("git clone git://github.com/jdewit/bootstrap-timepicker.git bootstrap-timepicker-src")
9 |
10 | system("cp bootstrap-timepicker-src/css/bootstrap-timepicker.min.css vendor/assets/stylesheets/bootstrap-timepicker.css")
11 | system("cp bootstrap-timepicker-src/js/bootstrap-timepicker.js vendor/assets/javascripts/bootstrap-timepicker.js")
12 | system("git status")
13 | end
14 |
15 | desc "Build the gem"
16 | task "build" do
17 | system("gem build bootstrap-timepicker-rails.gemspec")
18 | end
19 |
20 | desc "Publish the gem"
21 | task 'publish' do
22 | system("gem push bootstrap-timepicker-rails-#{BootstrapTimepickerRails::Rails::VERSION}.gem")
23 | system("git push")
24 | end
25 |
26 | desc "Build and publish the gem"
27 | task "release" do
28 | system("gem build bootstrap-timepicker-rails.gemspec")
29 | system("gem push bootstrap-timepicker-rails-#{BootstrapTimepickerRails::Rails::VERSION}.gem")
30 | system("git push")
31 | end
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Bootstrap Timepicker for Rails
2 | This is the gemified version of https://github.com/jdewit/bootstrap-timepicker
3 |
4 | bootstrap-timepicker-rails project integrates Timepicker with Rails 3 assets pipeline.
5 |
6 | ## Rails > 3.1
7 | Include bootstrap-timepicker-rails in Gemfile;
8 |
9 | ``` ruby
10 | gem 'bootstrap-timepicker-rails'
11 | ```
12 |
13 | or you can install from latest build;
14 |
15 | ``` ruby
16 | gem 'bootstrap-timepicker-rails', :require => 'bootstrap-timepicker-rails',
17 | :git => 'git://github.com/tispratik/bootstrap-timepicker-rails.git'
18 | ```
19 |
20 | and run bundle install.
21 |
22 | ## Configuration
23 |
24 | Add this line to app/assets/stylesheets/application.css
25 |
26 | ``` css
27 | *= require bootstrap-timepicker
28 | ```
29 |
30 | Add this line to app/assets/javascripts/application.js
31 |
32 | ``` javascript
33 | //= require bootstrap-timepicker
34 | ```
35 |
36 | ## Using bootstrap-timepicker-rails
37 |
38 | Just call timepicker() with any selector.
39 |
40 | ```javascript
41 | $('.timepicker').timepicker()
42 | ```
43 |
44 | Callback for time picked.
45 |
46 | ```javascript
47 | $('.timepicker').timepicker()
48 | .on('changeTime', function(ev) {
49 | alert('time has changed');
50 | });
51 | ```
52 | Set time via data-time attribute.
53 |
54 | ```html
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/bootstrap-timepicker.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Timepicker Component for Twitter Bootstrap
3 | *
4 | * Copyright 2013 Joris de Wit
5 | *
6 | * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */.bootstrap-timepicker{position:relative}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu{left:auto;right:0}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:before{left:auto;right:12px}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:after{left:auto;right:13px}.bootstrap-timepicker .add-on{cursor:pointer}.bootstrap-timepicker .add-on i{display:inline-block;width:16px;height:16px}.bootstrap-timepicker-widget.dropdown-menu{padding:2px 3px 2px 2px}.bootstrap-timepicker-widget.dropdown-menu.open{display:inline-block}.bootstrap-timepicker-widget.dropdown-menu:before{border-bottom:7px solid rgba(0,0,0,0.2);border-left:7px solid transparent;border-right:7px solid transparent;content:"";display:inline-block;left:9px;position:absolute;top:-7px}.bootstrap-timepicker-widget.dropdown-menu:after{border-bottom:6px solid #fff;border-left:6px solid transparent;border-right:6px solid transparent;content:"";display:inline-block;left:10px;position:absolute;top:-6px}.bootstrap-timepicker-widget a.btn,.bootstrap-timepicker-widget input{border-radius:4px}.bootstrap-timepicker-widget table{width:100%;margin:0}.bootstrap-timepicker-widget table td{text-align:center;height:30px;margin:0;padding:2px}.bootstrap-timepicker-widget table td:not(.separator){min-width:30px}.bootstrap-timepicker-widget table td span{width:100%}.bootstrap-timepicker-widget table td a{border:1px transparent solid;width:100%;display:inline-block;margin:0;padding:8px 0;outline:0;color:#333}.bootstrap-timepicker-widget table td a:hover{text-decoration:none;background-color:#eee;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;border-color:#ddd}.bootstrap-timepicker-widget table td a i{margin-top:2px}.bootstrap-timepicker-widget table td input{width:25px;margin:0;text-align:center}.bootstrap-timepicker-widget .modal-content{padding:4px}@media(min-width:767px){.bootstrap-timepicker-widget.modal{width:200px;margin-left:-100px}}@media(max-width:767px){.bootstrap-timepicker{width:100%}.bootstrap-timepicker .dropdown-menu{width:100%}}
--------------------------------------------------------------------------------
/vendor/assets/javascripts/bootstrap-timepicker.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Timepicker Component for Twitter Bootstrap
3 | *
4 | * Copyright 2013 Joris de Wit
5 | *
6 | * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 | ;(function($, window, document, undefined) {
12 |
13 | 'use strict'; // jshint ;_;
14 |
15 | // TIMEPICKER PUBLIC CLASS DEFINITION
16 | var Timepicker = function(element, options) {
17 | this.widget = '';
18 | this.$element = $(element);
19 | this.defaultTime = options.defaultTime;
20 | this.disableFocus = options.disableFocus;
21 | this.isOpen = options.isOpen;
22 | this.minuteStep = options.minuteStep;
23 | this.modalBackdrop = options.modalBackdrop;
24 | this.secondStep = options.secondStep;
25 | this.showInputs = options.showInputs;
26 | this.showMeridian = options.showMeridian;
27 | this.showSeconds = options.showSeconds;
28 | this.template = options.template;
29 | this.appendWidgetTo = options.appendWidgetTo;
30 |
31 | this._init();
32 | };
33 |
34 | Timepicker.prototype = {
35 |
36 | constructor: Timepicker,
37 |
38 | _init: function() {
39 | var self = this;
40 |
41 | if (this.$element.parent().hasClass('input-append') || this.$element.parent().hasClass('input-prepend')) {
42 | this.$element.parent('.input-append, .input-prepend').find('.add-on').on({
43 | 'click.timepicker': $.proxy(this.showWidget, this)
44 | });
45 | this.$element.on({
46 | 'focus.timepicker': $.proxy(this.highlightUnit, this),
47 | 'click.timepicker': $.proxy(this.highlightUnit, this),
48 | 'keydown.timepicker': $.proxy(this.elementKeydown, this),
49 | 'blur.timepicker': $.proxy(this.blurElement, this)
50 | });
51 | } else {
52 | if (this.template) {
53 | this.$element.on({
54 | 'focus.timepicker': $.proxy(this.showWidget, this),
55 | 'click.timepicker': $.proxy(this.showWidget, this),
56 | 'blur.timepicker': $.proxy(this.blurElement, this)
57 | });
58 | } else {
59 | this.$element.on({
60 | 'focus.timepicker': $.proxy(this.highlightUnit, this),
61 | 'click.timepicker': $.proxy(this.highlightUnit, this),
62 | 'keydown.timepicker': $.proxy(this.elementKeydown, this),
63 | 'blur.timepicker': $.proxy(this.blurElement, this)
64 | });
65 | }
66 | }
67 |
68 | if (this.template !== false) {
69 | this.$widget = $(this.getTemplate()).prependTo(this.$element.parents(this.appendWidgetTo)).on('click', $.proxy(this.widgetClick, this));
70 | } else {
71 | this.$widget = false;
72 | }
73 |
74 | if (this.showInputs && this.$widget !== false) {
75 | this.$widget.find('input').each(function() {
76 | $(this).on({
77 | 'click.timepicker': function() { $(this).select(); },
78 | 'keydown.timepicker': $.proxy(self.widgetKeydown, self)
79 | });
80 | });
81 | }
82 |
83 | this.setDefaultTime(this.defaultTime);
84 | },
85 |
86 | blurElement: function() {
87 | this.highlightedUnit = undefined;
88 | this.updateFromElementVal();
89 | },
90 |
91 | decrementHour: function() {
92 | if (this.showMeridian) {
93 | if (this.hour === 1) {
94 | this.hour = 12;
95 | } else if (this.hour === 12) {
96 | this.hour--;
97 |
98 | return this.toggleMeridian();
99 | } else if (this.hour === 0) {
100 | this.hour = 11;
101 |
102 | return this.toggleMeridian();
103 | } else {
104 | this.hour--;
105 | }
106 | } else {
107 | if (this.hour === 0) {
108 | this.hour = 23;
109 | } else {
110 | this.hour--;
111 | }
112 | }
113 | this.update();
114 | },
115 |
116 | decrementMinute: function(step) {
117 | var newVal;
118 |
119 | if (step) {
120 | newVal = this.minute - step;
121 | } else {
122 | newVal = this.minute - this.minuteStep;
123 | }
124 |
125 | if (newVal < 0) {
126 | this.decrementHour();
127 | this.minute = newVal + 60;
128 | } else {
129 | this.minute = newVal;
130 | }
131 | this.update();
132 | },
133 |
134 | decrementSecond: function() {
135 | var newVal = this.second - this.secondStep;
136 |
137 | if (newVal < 0) {
138 | this.decrementMinute(true);
139 | this.second = newVal + 60;
140 | } else {
141 | this.second = newVal;
142 | }
143 | this.update();
144 | },
145 |
146 | elementKeydown: function(e) {
147 | switch (e.keyCode) {
148 | case 9: //tab
149 | this.updateFromElementVal();
150 |
151 | switch (this.highlightedUnit) {
152 | case 'hour':
153 | e.preventDefault();
154 | this.highlightNextUnit();
155 | break;
156 | case 'minute':
157 | if (this.showMeridian || this.showSeconds) {
158 | e.preventDefault();
159 | this.highlightNextUnit();
160 | }
161 | break;
162 | case 'second':
163 | if (this.showMeridian) {
164 | e.preventDefault();
165 | this.highlightNextUnit();
166 | }
167 | break;
168 | }
169 | break;
170 | case 27: // escape
171 | this.updateFromElementVal();
172 | break;
173 | case 37: // left arrow
174 | e.preventDefault();
175 | this.highlightPrevUnit();
176 | this.updateFromElementVal();
177 | break;
178 | case 38: // up arrow
179 | e.preventDefault();
180 | switch (this.highlightedUnit) {
181 | case 'hour':
182 | this.incrementHour();
183 | this.highlightHour();
184 | break;
185 | case 'minute':
186 | this.incrementMinute();
187 | this.highlightMinute();
188 | break;
189 | case 'second':
190 | this.incrementSecond();
191 | this.highlightSecond();
192 | break;
193 | case 'meridian':
194 | this.toggleMeridian();
195 | this.highlightMeridian();
196 | break;
197 | }
198 | break;
199 | case 39: // right arrow
200 | e.preventDefault();
201 | this.updateFromElementVal();
202 | this.highlightNextUnit();
203 | break;
204 | case 40: // down arrow
205 | e.preventDefault();
206 | switch (this.highlightedUnit) {
207 | case 'hour':
208 | this.decrementHour();
209 | this.highlightHour();
210 | break;
211 | case 'minute':
212 | this.decrementMinute();
213 | this.highlightMinute();
214 | break;
215 | case 'second':
216 | this.decrementSecond();
217 | this.highlightSecond();
218 | break;
219 | case 'meridian':
220 | this.toggleMeridian();
221 | this.highlightMeridian();
222 | break;
223 | }
224 | break;
225 | }
226 | },
227 |
228 | formatTime: function(hour, minute, second, meridian) {
229 | hour = hour < 10 ? '0' + hour : hour;
230 | minute = minute < 10 ? '0' + minute : minute;
231 | second = second < 10 ? '0' + second : second;
232 |
233 | return hour + ':' + minute + (this.showSeconds ? ':' + second : '') + (this.showMeridian ? ' ' + meridian : '');
234 | },
235 |
236 | getCursorPosition: function() {
237 | var input = this.$element.get(0);
238 |
239 | if ('selectionStart' in input) {// Standard-compliant browsers
240 |
241 | return input.selectionStart;
242 | } else if (document.selection) {// IE fix
243 | input.focus();
244 | var sel = document.selection.createRange(),
245 | selLen = document.selection.createRange().text.length;
246 |
247 | sel.moveStart('character', - input.value.length);
248 |
249 | return sel.text.length - selLen;
250 | }
251 | },
252 |
253 | getTemplate: function() {
254 | var template,
255 | hourTemplate,
256 | minuteTemplate,
257 | secondTemplate,
258 | meridianTemplate,
259 | templateContent;
260 |
261 | if (this.showInputs) {
262 | hourTemplate = '';
263 | minuteTemplate = '';
264 | secondTemplate = '';
265 | meridianTemplate = '';
266 | } else {
267 | hourTemplate = '';
268 | minuteTemplate = '';
269 | secondTemplate = '';
270 | meridianTemplate = '';
271 | }
272 |
273 | templateContent = ''+
274 | ''+
275 | ' | '+
276 | ' | '+
277 | ' | '+
278 | (this.showSeconds ?
279 | ' | '+
280 | ' | '
281 | : '') +
282 | (this.showMeridian ?
283 | ' | '+
284 | ' | '
285 | : '') +
286 | '
'+
287 | ''+
288 | '| '+ hourTemplate +' | '+
289 | ': | '+
290 | ''+ minuteTemplate +' | '+
291 | (this.showSeconds ?
292 | ': | '+
293 | ''+ secondTemplate +' | '
294 | : '') +
295 | (this.showMeridian ?
296 | ' | '+
297 | ''+ meridianTemplate +' | '
298 | : '') +
299 | '
'+
300 | ''+
301 | ' | '+
302 | ' | '+
303 | ' | '+
304 | (this.showSeconds ?
305 | ' | '+
306 | ' | '
307 | : '') +
308 | (this.showMeridian ?
309 | ' | '+
310 | ' | '
311 | : '') +
312 | '
'+
313 | '
';
314 |
315 | switch(this.template) {
316 | case 'modal':
317 | template = '';
329 | break;
330 | case 'dropdown':
331 | template = '';
332 | break;
333 | }
334 |
335 | return template;
336 | },
337 |
338 | getTime: function() {
339 | return this.formatTime(this.hour, this.minute, this.second, this.meridian);
340 | },
341 |
342 | hideWidget: function() {
343 | if (this.isOpen === false) {
344 | return;
345 | }
346 |
347 | if (this.showInputs) {
348 | this.updateFromWidgetInputs();
349 | }
350 |
351 | this.$element.trigger({
352 | 'type': 'hide.timepicker',
353 | 'time': {
354 | 'value': this.getTime(),
355 | 'hours': this.hour,
356 | 'minutes': this.minute,
357 | 'seconds': this.second,
358 | 'meridian': this.meridian
359 | }
360 | });
361 |
362 | if (this.template === 'modal') {
363 | this.$widget.modal('hide');
364 | } else {
365 | this.$widget.removeClass('open');
366 | }
367 |
368 | $(document).off('mousedown.timepicker');
369 |
370 | this.isOpen = false;
371 | },
372 |
373 | highlightUnit: function() {
374 | this.position = this.getCursorPosition();
375 | if (this.position >= 0 && this.position <= 2) {
376 | this.highlightHour();
377 | } else if (this.position >= 3 && this.position <= 5) {
378 | this.highlightMinute();
379 | } else if (this.position >= 6 && this.position <= 8) {
380 | if (this.showSeconds) {
381 | this.highlightSecond();
382 | } else {
383 | this.highlightMeridian();
384 | }
385 | } else if (this.position >= 9 && this.position <= 11) {
386 | this.highlightMeridian();
387 | }
388 | },
389 |
390 | highlightNextUnit: function() {
391 | switch (this.highlightedUnit) {
392 | case 'hour':
393 | this.highlightMinute();
394 | break;
395 | case 'minute':
396 | if (this.showSeconds) {
397 | this.highlightSecond();
398 | } else if (this.showMeridian){
399 | this.highlightMeridian();
400 | } else {
401 | this.highlightHour();
402 | }
403 | break;
404 | case 'second':
405 | if (this.showMeridian) {
406 | this.highlightMeridian();
407 | } else {
408 | this.highlightHour();
409 | }
410 | break;
411 | case 'meridian':
412 | this.highlightHour();
413 | break;
414 | }
415 | },
416 |
417 | highlightPrevUnit: function() {
418 | switch (this.highlightedUnit) {
419 | case 'hour':
420 | this.highlightMeridian();
421 | break;
422 | case 'minute':
423 | this.highlightHour();
424 | break;
425 | case 'second':
426 | this.highlightMinute();
427 | break;
428 | case 'meridian':
429 | if (this.showSeconds) {
430 | this.highlightSecond();
431 | } else {
432 | this.highlightMinute();
433 | }
434 | break;
435 | }
436 | },
437 |
438 | highlightHour: function() {
439 | var $element = this.$element.get(0);
440 |
441 | this.highlightedUnit = 'hour';
442 |
443 | if ($element.setSelectionRange) {
444 | setTimeout(function() {
445 | $element.setSelectionRange(0,2);
446 | }, 0);
447 | }
448 | },
449 |
450 | highlightMinute: function() {
451 | var $element = this.$element.get(0);
452 |
453 | this.highlightedUnit = 'minute';
454 |
455 | if ($element.setSelectionRange) {
456 | setTimeout(function() {
457 | $element.setSelectionRange(3,5);
458 | }, 0);
459 | }
460 | },
461 |
462 | highlightSecond: function() {
463 | var $element = this.$element.get(0);
464 |
465 | this.highlightedUnit = 'second';
466 |
467 | if ($element.setSelectionRange) {
468 | setTimeout(function() {
469 | $element.setSelectionRange(6,8);
470 | }, 0);
471 | }
472 | },
473 |
474 | highlightMeridian: function() {
475 | var $element = this.$element.get(0);
476 |
477 | this.highlightedUnit = 'meridian';
478 |
479 | if ($element.setSelectionRange) {
480 | if (this.showSeconds) {
481 | setTimeout(function() {
482 | $element.setSelectionRange(9,11);
483 | }, 0);
484 | } else {
485 | setTimeout(function() {
486 | $element.setSelectionRange(6,8);
487 | }, 0);
488 | }
489 | }
490 | },
491 |
492 | incrementHour: function() {
493 | if (this.showMeridian) {
494 | if (this.hour === 11) {
495 | this.hour++;
496 | return this.toggleMeridian();
497 | } else if (this.hour === 12) {
498 | this.hour = 0;
499 | }
500 | }
501 | if (this.hour === 23) {
502 | return this.hour = 0;
503 | }
504 | this.hour++;
505 | this.update();
506 | },
507 |
508 | incrementMinute: function(step) {
509 | var newVal;
510 |
511 | if (step) {
512 | newVal = this.minute + step;
513 | } else {
514 | newVal = this.minute + this.minuteStep - (this.minute % this.minuteStep);
515 | }
516 |
517 | if (newVal > 59) {
518 | this.incrementHour();
519 | this.minute = newVal - 60;
520 | } else {
521 | this.minute = newVal;
522 | }
523 | this.update();
524 | },
525 |
526 | incrementSecond: function() {
527 | var newVal = this.second + this.secondStep - (this.second % this.secondStep);
528 |
529 | if (newVal > 59) {
530 | this.incrementMinute(true);
531 | this.second = newVal - 60;
532 | } else {
533 | this.second = newVal;
534 | }
535 | this.update();
536 | },
537 |
538 | remove: function() {
539 | $('document').off('.timepicker');
540 | if (this.$widget) {
541 | this.$widget.remove();
542 | }
543 | delete this.$element.data().timepicker;
544 | },
545 |
546 | setDefaultTime: function(defaultTime){
547 | if (!this.$element.val()) {
548 | if (defaultTime === 'current') {
549 | var dTime = new Date(),
550 | hours = dTime.getHours(),
551 | minutes = Math.floor(dTime.getMinutes() / this.minuteStep) * this.minuteStep,
552 | seconds = Math.floor(dTime.getSeconds() / this.secondStep) * this.secondStep,
553 | meridian = 'AM';
554 |
555 | if (this.showMeridian) {
556 | if (hours === 0) {
557 | hours = 12;
558 | } else if (hours >= 12) {
559 | if (hours > 12) {
560 | hours = hours - 12;
561 | }
562 | meridian = 'PM';
563 | } else {
564 | meridian = 'AM';
565 | }
566 | }
567 |
568 | this.hour = hours;
569 | this.minute = minutes;
570 | this.second = seconds;
571 | this.meridian = meridian;
572 |
573 | this.update();
574 |
575 | } else if (defaultTime === false) {
576 | this.hour = 0;
577 | this.minute = 0;
578 | this.second = 0;
579 | this.meridian = 'AM';
580 | } else {
581 | this.setTime(defaultTime);
582 | }
583 | } else {
584 | this.updateFromElementVal();
585 | }
586 | },
587 |
588 | setTime: function(time) {
589 | var arr,
590 | timeArray;
591 |
592 | if (this.showMeridian) {
593 | arr = time.split(' ');
594 | timeArray = arr[0].split(':');
595 | this.meridian = arr[1];
596 | } else {
597 | timeArray = time.split(':');
598 | }
599 |
600 | this.hour = parseInt(timeArray[0], 10);
601 | this.minute = parseInt(timeArray[1], 10);
602 | this.second = parseInt(timeArray[2], 10);
603 |
604 | if (isNaN(this.hour)) {
605 | this.hour = 0;
606 | }
607 | if (isNaN(this.minute)) {
608 | this.minute = 0;
609 | }
610 |
611 | if (this.showMeridian) {
612 | if (this.hour > 12) {
613 | this.hour = 12;
614 | } else if (this.hour < 1) {
615 | this.hour = 12;
616 | }
617 |
618 | if (this.meridian === 'am' || this.meridian === 'a') {
619 | this.meridian = 'AM';
620 | } else if (this.meridian === 'pm' || this.meridian === 'p') {
621 | this.meridian = 'PM';
622 | }
623 |
624 | if (this.meridian !== 'AM' && this.meridian !== 'PM') {
625 | this.meridian = 'AM';
626 | }
627 | } else {
628 | if (this.hour >= 24) {
629 | this.hour = 23;
630 | } else if (this.hour < 0) {
631 | this.hour = 0;
632 | }
633 | }
634 |
635 | if (this.minute < 0) {
636 | this.minute = 0;
637 | } else if (this.minute >= 60) {
638 | this.minute = 59;
639 | }
640 |
641 | if (this.showSeconds) {
642 | if (isNaN(this.second)) {
643 | this.second = 0;
644 | } else if (this.second < 0) {
645 | this.second = 0;
646 | } else if (this.second >= 60) {
647 | this.second = 59;
648 | }
649 | }
650 |
651 | this.update();
652 | },
653 |
654 | showWidget: function() {
655 | if (this.isOpen) {
656 | return;
657 | }
658 |
659 | var self = this;
660 | $(document).on('mousedown.timepicker', function (e) {
661 | // Clicked outside the timepicker, hide it
662 | if ($(e.target).closest('.bootstrap-timepicker-widget').length === 0) {
663 | self.hideWidget();
664 | }
665 | });
666 |
667 | this.$element.trigger({
668 | 'type': 'show.timepicker',
669 | 'time': {
670 | 'value': this.getTime(),
671 | 'hours': this.hour,
672 | 'minutes': this.minute,
673 | 'seconds': this.second,
674 | 'meridian': this.meridian
675 | }
676 | });
677 |
678 | if (this.disableFocus) {
679 | this.$element.blur();
680 | }
681 |
682 | this.updateFromElementVal();
683 |
684 | if (this.template === 'modal') {
685 | this.$widget.modal('show').on('hidden', $.proxy(this.hideWidget, this));
686 | } else {
687 | if (this.isOpen === false) {
688 | this.$widget.addClass('open');
689 | }
690 | }
691 |
692 | this.isOpen = true;
693 | },
694 |
695 | toggleMeridian: function() {
696 | this.meridian = this.meridian === 'AM' ? 'PM' : 'AM';
697 | this.update();
698 | },
699 |
700 | update: function() {
701 | this.$element.trigger({
702 | 'type': 'changeTime.timepicker',
703 | 'time': {
704 | 'value': this.getTime(),
705 | 'hours': this.hour,
706 | 'minutes': this.minute,
707 | 'seconds': this.second,
708 | 'meridian': this.meridian
709 | }
710 | });
711 |
712 | this.updateElement();
713 | this.updateWidget();
714 | },
715 |
716 | updateElement: function() {
717 | this.$element.val(this.getTime()).change();
718 | },
719 |
720 | updateFromElementVal: function() {
721 | var val = this.$element.val();
722 |
723 | if (val) {
724 | this.setTime(val);
725 | }
726 | },
727 |
728 | updateWidget: function() {
729 | if (this.$widget === false) {
730 | return;
731 | }
732 |
733 | var hour = this.hour < 10 ? '0' + this.hour : this.hour,
734 | minute = this.minute < 10 ? '0' + this.minute : this.minute,
735 | second = this.second < 10 ? '0' + this.second : this.second;
736 |
737 | if (this.showInputs) {
738 | this.$widget.find('input.bootstrap-timepicker-hour').val(hour);
739 | this.$widget.find('input.bootstrap-timepicker-minute').val(minute);
740 |
741 | if (this.showSeconds) {
742 | this.$widget.find('input.bootstrap-timepicker-second').val(second);
743 | }
744 | if (this.showMeridian) {
745 | this.$widget.find('input.bootstrap-timepicker-meridian').val(this.meridian);
746 | }
747 | } else {
748 | this.$widget.find('span.bootstrap-timepicker-hour').text(hour);
749 | this.$widget.find('span.bootstrap-timepicker-minute').text(minute);
750 |
751 | if (this.showSeconds) {
752 | this.$widget.find('span.bootstrap-timepicker-second').text(second);
753 | }
754 | if (this.showMeridian) {
755 | this.$widget.find('span.bootstrap-timepicker-meridian').text(this.meridian);
756 | }
757 | }
758 | },
759 |
760 | updateFromWidgetInputs: function() {
761 | if (this.$widget === false) {
762 | return;
763 | }
764 | var time = $('input.bootstrap-timepicker-hour', this.$widget).val() + ':' +
765 | $('input.bootstrap-timepicker-minute', this.$widget).val() +
766 | (this.showSeconds ? ':' + $('input.bootstrap-timepicker-second', this.$widget).val() : '') +
767 | (this.showMeridian ? ' ' + $('input.bootstrap-timepicker-meridian', this.$widget).val() : '');
768 |
769 | this.setTime(time);
770 | },
771 |
772 | widgetClick: function(e) {
773 | e.stopPropagation();
774 | e.preventDefault();
775 |
776 | var action = $(e.target).closest('a').data('action');
777 | if (action) {
778 | this[action]();
779 | }
780 | },
781 |
782 | widgetKeydown: function(e) {
783 | var $input = $(e.target).closest('input'),
784 | name = $input.attr('name');
785 |
786 | switch (e.keyCode) {
787 | case 9: //tab
788 | if (this.showMeridian) {
789 | if (name === 'meridian') {
790 | return this.hideWidget();
791 | }
792 | } else {
793 | if (this.showSeconds) {
794 | if (name === 'second') {
795 | return this.hideWidget();
796 | }
797 | } else {
798 | if (name === 'minute') {
799 | return this.hideWidget();
800 | }
801 | }
802 | }
803 |
804 | this.updateFromWidgetInputs();
805 | break;
806 | case 27: // escape
807 | this.hideWidget();
808 | break;
809 | case 38: // up arrow
810 | e.preventDefault();
811 | switch (name) {
812 | case 'hour':
813 | this.incrementHour();
814 | break;
815 | case 'minute':
816 | this.incrementMinute();
817 | break;
818 | case 'second':
819 | this.incrementSecond();
820 | break;
821 | case 'meridian':
822 | this.toggleMeridian();
823 | break;
824 | }
825 | break;
826 | case 40: // down arrow
827 | e.preventDefault();
828 | switch (name) {
829 | case 'hour':
830 | this.decrementHour();
831 | break;
832 | case 'minute':
833 | this.decrementMinute();
834 | break;
835 | case 'second':
836 | this.decrementSecond();
837 | break;
838 | case 'meridian':
839 | this.toggleMeridian();
840 | break;
841 | }
842 | break;
843 | }
844 | }
845 | };
846 |
847 |
848 | //TIMEPICKER PLUGIN DEFINITION
849 | $.fn.timepicker = function(option) {
850 | var args = Array.apply(null, arguments);
851 | args.shift();
852 | return this.each(function() {
853 | var $this = $(this),
854 | data = $this.data('timepicker'),
855 | options = typeof option === 'object' && option;
856 |
857 | if (!data) {
858 | $this.data('timepicker', (data = new Timepicker(this, $.extend({}, $.fn.timepicker.defaults, options, $(this).data()))));
859 | }
860 |
861 | if (typeof option === 'string') {
862 | data[option].apply(data, args);
863 | }
864 | });
865 | };
866 |
867 | $.fn.timepicker.defaults = {
868 | defaultTime: 'current',
869 | disableFocus: false,
870 | isOpen: false,
871 | minuteStep: 15,
872 | modalBackdrop: false,
873 | secondStep: 15,
874 | showSeconds: false,
875 | showInputs: true,
876 | showMeridian: true,
877 | template: 'dropdown',
878 | appendWidgetTo: '.bootstrap-timepicker'
879 | };
880 |
881 | $.fn.timepicker.Constructor = Timepicker;
882 |
883 | })(jQuery, window, document);
884 |
--------------------------------------------------------------------------------
/vendor/assets/javascripts/]:
--------------------------------------------------------------------------------
1 | /* =========================================================
2 | * bootstrap-timepicker.js
3 | * http://www.github.com/jdewit/bootstrap-timepicker
4 | * =========================================================
5 | * Copyright 2012
6 | *
7 | * Created By:
8 | * Joris de Wit @joris_dewit
9 | *
10 | * Contributions By:
11 | * Gilbert @mindeavor
12 | * Koen Punt info@koenpunt.nl
13 | * Nek
14 | * Chris Martin
15 | * Dominic Barnes contact@dominicbarnes.us
16 | *
17 | * Licensed under the Apache License, Version 2.0 (the "License");
18 | * you may not use this file except in compliance with the License.
19 | * You may obtain a copy of the License at
20 | *
21 | * http://www.apache.org/licenses/LICENSE-2.0
22 | *
23 | * Unless required by applicable law or agreed to in writing, software
24 | * distributed under the License is distributed on an "AS IS" BASIS,
25 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 | * See the License for the specific language governing permissions and
27 | * limitations under the License.
28 | * ========================================================= */
29 |
30 | !function($) {
31 |
32 | "use strict"; // jshint ;_;
33 |
34 | /* TIMEPICKER PUBLIC CLASS DEFINITION
35 | * ================================== */
36 | var Timepicker = function(element, options) {
37 | this.$element = $(element);
38 | this.options = $.extend({}, $.fn.timepicker.defaults, options, this.$element.data());
39 | this.minuteStep = this.options.minuteStep || this.minuteStep;
40 | this.secondStep = this.options.secondStep || this.secondStep;
41 | this.showMeridian = this.options.showMeridian || this.showMeridian;
42 | this.showSeconds = this.options.showSeconds || this.showSeconds;
43 | this.showInputs = this.options.showInputs || this.showInputs;
44 | this.disableFocus = this.options.disableFocus || this.disableFocus;
45 | this.template = this.options.template || this.template;
46 | this.modalBackdrop = this.options.modalBackdrop || this.modalBackdrop;
47 | this.defaultTime = this.$element.time || this.options.defaultTime || this.defaultTime;
48 | console.log(this.$element.time)
49 | console.log(this.options)
50 | this.open = false;
51 | this.init();
52 | };
53 |
54 | Timepicker.prototype = {
55 |
56 | constructor: Timepicker
57 |
58 | , init: function () {
59 | if (this.$element.parent().hasClass('input-append')) {
60 | this.$element.parent('.input-append').find('.add-on').on('click', $.proxy(this.showWidget, this));
61 | this.$element.on({
62 | focus: $.proxy(this.highlightUnit, this),
63 | click: $.proxy(this.highlightUnit, this),
64 | keypress: $.proxy(this.elementKeypress, this),
65 | blur: $.proxy(this.blurElement, this)
66 | });
67 |
68 | } else {
69 | if (this.template) {
70 | this.$element.on({
71 | focus: $.proxy(this.showWidget, this),
72 | click: $.proxy(this.showWidget, this),
73 | blur: $.proxy(this.blurElement, this)
74 | });
75 | } else {
76 | this.$element.on({
77 | focus: $.proxy(this.highlightUnit, this),
78 | click: $.proxy(this.highlightUnit, this),
79 | keypress: $.proxy(this.elementKeypress, this),
80 | blur: $.proxy(this.blurElement, this)
81 | });
82 | }
83 | }
84 |
85 |
86 | this.$widget = $(this.getTemplate()).appendTo('body');
87 |
88 | this.$widget.on('click', $.proxy(this.widgetClick, this));
89 |
90 | if (this.showInputs) {
91 | this.$widget.find('input').on({
92 | click: function() { this.select(); },
93 | keypress: $.proxy(this.widgetKeypress, this),
94 | change: $.proxy(this.updateFromWidgetInputs, this)
95 | });
96 | }
97 |
98 | this.setDefaultTime(this.defaultTime);
99 | }
100 |
101 | , showWidget: function(e) {
102 | e.stopPropagation();
103 | e.preventDefault();
104 |
105 | if (this.open) {
106 | return;
107 | }
108 |
109 | this.$element.trigger('show');
110 |
111 | if (this.disableFocus) {
112 | this.$element.blur();
113 | }
114 |
115 | var pos = $.extend({}, this.$element.offset(), {
116 | height: this.$element[0].offsetHeight
117 | });
118 |
119 | this.updateFromElementVal();
120 |
121 | $('html')
122 | .trigger('click.timepicker.data-api')
123 | .one('click.timepicker.data-api', $.proxy(this.hideWidget, this));
124 |
125 | if (this.template === 'modal') {
126 | this.$widget.modal('show').on('hidden', $.proxy(this.hideWidget, this));
127 | } else {
128 | this.$widget.css({
129 | top: pos.top + pos.height
130 | , left: pos.left
131 | })
132 |
133 | if (!this.open) {
134 | this.$widget.addClass('open');
135 | }
136 | }
137 |
138 | this.open = true;
139 | this.$element.trigger('shown');
140 | }
141 |
142 | , hideWidget: function(){
143 | this.$element.trigger('hide');
144 |
145 | if (this.template === 'modal') {
146 | this.$widget.modal('hide');
147 | } else {
148 | this.$widget.removeClass('open');
149 | }
150 | this.open = false;
151 | this.$element.trigger('hidden');
152 | }
153 |
154 | , widgetClick: function(e) {
155 | e.stopPropagation();
156 | e.preventDefault();
157 |
158 | var action = $(e.target).closest('a').data('action');
159 | if (action) {
160 | this[action]();
161 | this.update();
162 | }
163 | }
164 |
165 | , widgetKeypress: function(e) {
166 | var input = $(e.target).closest('input').attr('name');
167 |
168 | switch (e.keyCode) {
169 | case 9: //tab
170 | if (this.showMeridian) {
171 | if (input == 'meridian') {
172 | this.hideWidget();
173 | }
174 | } else {
175 | if (this.showSeconds) {
176 | if (input == 'second') {
177 | this.hideWidget();
178 | }
179 | } else {
180 | if (input == 'minute') {
181 | this.hideWidget();
182 | }
183 | }
184 | }
185 | break;
186 | case 27: // escape
187 | this.hideWidget();
188 | break;
189 | case 38: // up arrow
190 | switch (input) {
191 | case 'hour':
192 | this.incrementHour();
193 | break;
194 | case 'minute':
195 | this.incrementMinute();
196 | break;
197 | case 'second':
198 | this.incrementSecond();
199 | break;
200 | case 'meridian':
201 | this.toggleMeridian();
202 | break;
203 | }
204 | this.update();
205 | break;
206 | case 40: // down arrow
207 | switch (input) {
208 | case 'hour':
209 | this.decrementHour();
210 | break;
211 | case 'minute':
212 | this.decrementMinute();
213 | break;
214 | case 'second':
215 | this.decrementSecond();
216 | break;
217 | case 'meridian':
218 | this.toggleMeridian();
219 | break;
220 | }
221 | this.update();
222 | break;
223 | }
224 | }
225 |
226 | , elementKeypress: function(e) {
227 | var input = this.$element.get(0);
228 | switch (e.keyCode) {
229 | case 0: //input
230 | break;
231 | case 9: //tab
232 | this.updateFromElementVal();
233 | if (this.showMeridian) {
234 | if (this.highlightedUnit != 'meridian') {
235 | e.preventDefault();
236 | this.highlightNextUnit();
237 | }
238 | } else {
239 | if (this.showSeconds) {
240 | if (this.highlightedUnit != 'second') {
241 | e.preventDefault();
242 | this.highlightNextUnit();
243 | }
244 | } else {
245 | if (this.highlightedUnit != 'minute') {
246 | e.preventDefault();
247 | this.highlightNextUnit();
248 | }
249 | }
250 | }
251 | break;
252 | case 27: // escape
253 | this.updateFromElementVal();
254 | break;
255 | case 37: // left arrow
256 | this.updateFromElementVal();
257 | this.highlightPrevUnit();
258 | break;
259 | case 38: // up arrow
260 | switch (this.highlightedUnit) {
261 | case 'hour':
262 | this.incrementHour();
263 | break;
264 | case 'minute':
265 | this.incrementMinute();
266 | break;
267 | case 'second':
268 | this.incrementSecond();
269 | break;
270 | case 'meridian':
271 | this.toggleMeridian();
272 | break;
273 | }
274 | this.updateElement();
275 | break;
276 | case 39: // right arrow
277 | this.updateFromElementVal();
278 | this.highlightNextUnit();
279 | break;
280 | case 40: // down arrow
281 | switch (this.highlightedUnit) {
282 | case 'hour':
283 | this.decrementHour();
284 | break;
285 | case 'minute':
286 | this.decrementMinute();
287 | break;
288 | case 'second':
289 | this.decrementSecond();
290 | break;
291 | case 'meridian':
292 | this.toggleMeridian();
293 | break;
294 | }
295 | this.updateElement();
296 | break;
297 | }
298 |
299 | if (e.keyCode !== 0 && e.keyCode !== 8 && e.keyCode !== 9 && e.keyCode !== 46) {
300 | e.preventDefault();
301 | }
302 | }
303 |
304 | , setValues: function(time) {
305 | if (this.showMeridian) {
306 | var arr = time.split(' ');
307 | var timeArray = arr[0].split(':');
308 | this.meridian = arr[1];
309 | } else {
310 | var timeArray = time.split(':');
311 | }
312 |
313 | this.hour = parseInt(timeArray[0], 10);
314 | this.minute = parseInt(timeArray[1], 10);
315 | this.second = parseInt(timeArray[2], 10);
316 |
317 | if (isNaN(this.hour)) {
318 | this.hour = 0;
319 | }
320 | if (isNaN(this.minute)) {
321 | this.minute = 0;
322 | }
323 |
324 | if (this.showMeridian) {
325 | if (this.hour > 12) {
326 | this.hour = 12;
327 | } else if (this.hour < 1) {
328 | this.hour = 1;
329 | }
330 |
331 | if (this.meridian == 'am' || this.meridian == 'a') {
332 | this.meridian = 'AM';
333 | } else if (this.meridian == 'pm' || this.meridian == 'p') {
334 | this.meridian = 'PM';
335 | }
336 |
337 | if (this.meridian != 'AM' && this.meridian != 'PM') {
338 | this.meridian = 'AM';
339 | }
340 | } else {
341 | if (this.hour >= 24) {
342 | this.hour = 23;
343 | } else if (this.hour < 0) {
344 | this.hour = 0;
345 | }
346 | }
347 |
348 | if (this.minute < 0) {
349 | this.minute = 0;
350 | } else if (this.minute >= 60) {
351 | this.minute = 59;
352 | }
353 |
354 | if (this.showSeconds) {
355 | if (isNaN(this.second)) {
356 | this.second = 0;
357 | } else if (this.second < 0) {
358 | this.second = 0;
359 | } else if (this.second >= 60) {
360 | this.second = 59;
361 | }
362 | }
363 |
364 | this.updateElement();
365 | this.updateWidget();
366 | }
367 |
368 | , setMeridian: function(meridian) {
369 | if (meridian == 'a' || meridian == 'am' || meridian == 'AM' ) {
370 | this.meridian = 'AM';
371 | } else if (meridian == 'p' || meridian == 'pm' || meridian == 'PM' ) {
372 | this.meridian = 'PM';
373 | } else {
374 | this.updateWidget();
375 | }
376 |
377 | this.updateElement();
378 | }
379 |
380 | , setDefaultTime: function(defaultTime){
381 | if (defaultTime) {
382 | if (defaultTime === 'current') {
383 | var dTime = new Date();
384 | var hours = dTime.getHours();
385 | var minutes = Math.floor(dTime.getMinutes() / this.minuteStep) * this.minuteStep;
386 | var seconds = Math.floor(dTime.getSeconds() / this.secondStep) * this.secondStep;
387 | var meridian = "AM";
388 | if (this.showMeridian) {
389 | if (hours === 0) {
390 | hours = 12;
391 | } else if (hours >= 12) {
392 | if (hours > 12) {
393 | hours = hours - 12;
394 | }
395 | meridian = "PM";
396 | } else {
397 | meridian = "AM";
398 | }
399 | }
400 | this.hour = hours;
401 | this.minute = minutes;
402 | this.second = seconds;
403 | this.meridian = meridian;
404 | } else if (defaultTime === 'value') {
405 | this.setValues(this.$element.val());
406 | } else {
407 | this.setValues(defaultTime);
408 | }
409 | this.update();
410 | } else {
411 | this.hour = 0;
412 | this.minute = 0;
413 | this.second = 0;
414 | }
415 | }
416 |
417 | , formatTime: function(hour, minute, second, meridian) {
418 | hour = hour < 10 ? '0' + hour : hour;
419 | minute = minute < 10 ? '0' + minute : minute;
420 | second = second < 10 ? '0' + second : second;
421 |
422 | return hour + ':' + minute + (this.showSeconds ? ':' + second : '') + (this.showMeridian ? ' ' + meridian : '');
423 | }
424 |
425 | , getTime: function() {
426 | return this.formatTime(this.hour, this.minute, this.second, this.meridian);
427 | }
428 |
429 | , setTime: function(time) {
430 | this.setValues(time);
431 | this.update();
432 | }
433 |
434 | , update: function() {
435 | this.updateElement();
436 | this.updateWidget();
437 | this.$element.trigger({
438 | type: 'changeTime',
439 | time: this.time
440 | });
441 | }
442 |
443 | , blurElement: function() {
444 | this.highlightedUnit = undefined;
445 | this.updateFromElementVal();
446 | }
447 |
448 | , updateElement: function() {
449 | var time = this.getTime();
450 |
451 | this.$element.val(time).change();
452 |
453 | switch (this.highlightedUnit) {
454 | case 'hour':
455 | this.highlightHour();
456 | break;
457 | case 'minute':
458 | this.highlightMinute();
459 | break;
460 | case 'second':
461 | this.highlightSecond();
462 | break;
463 | case 'meridian':
464 | this.highlightMeridian();
465 | break;
466 | }
467 | }
468 |
469 | , updateWidget: function() {
470 | if (this.showInputs) {
471 | this.$widget.find('input.bootstrap-timepicker-hour').val(this.hour < 10 ? '0' + this.hour : this.hour);
472 | this.$widget.find('input.bootstrap-timepicker-minute').val(this.minute < 10 ? '0' + this.minute : this.minute);
473 | if (this.showSeconds) {
474 | this.$widget.find('input.bootstrap-timepicker-second').val(this.second < 10 ? '0' + this.second : this.second);
475 | }
476 | if (this.showMeridian) {
477 | this.$widget.find('input.bootstrap-timepicker-meridian').val(this.meridian);
478 | }
479 | } else {
480 | this.$widget.find('span.bootstrap-timepicker-hour').text(this.hour);
481 | this.$widget.find('span.bootstrap-timepicker-minute').text(this.minute < 10 ? '0' + this.minute : this.minute);
482 | if (this.showSeconds) {
483 | this.$widget.find('span.bootstrap-timepicker-second').text(this.second < 10 ? '0' + this.second : this.second);
484 | }
485 | if (this.showMeridian) {
486 | this.$widget.find('span.bootstrap-timepicker-meridian').text(this.meridian);
487 | }
488 | }
489 | }
490 |
491 | , updateFromElementVal: function (e) {
492 | var time = this.$element.val();
493 | if (time) {
494 | this.setValues(time);
495 | this.updateWidget();
496 | }
497 | }
498 |
499 | , updateFromWidgetInputs: function () {
500 | var time = $('input.bootstrap-timepicker-hour', this.$widget).val() + ':' +
501 | $('input.bootstrap-timepicker-minute', this.$widget).val() +
502 | (this.showSeconds ?
503 | ':' + $('input.bootstrap-timepicker-second', this.$widget).val()
504 | : '') +
505 | (this.showMeridian ?
506 | ' ' + $('input.bootstrap-timepicker-meridian', this.$widget).val()
507 | : '');
508 |
509 | this.setValues(time);
510 | }
511 |
512 | , getCursorPosition: function() {
513 | var input = this.$element.get(0);
514 |
515 | if ('selectionStart' in input) {
516 | // Standard-compliant browsers
517 | return input.selectionStart;
518 | } else if (document.selection) {
519 | // IE fix
520 | input.focus();
521 | var sel = document.selection.createRange();
522 | var selLen = document.selection.createRange().text.length;
523 | sel.moveStart('character', - input.value.length);
524 |
525 | return sel.text.length - selLen;
526 | }
527 | }
528 |
529 | , highlightUnit: function () {
530 | var input = this.$element.get(0);
531 |
532 | this.position = this.getCursorPosition();
533 | if (this.position >= 0 && this.position <= 2) {
534 | this.highlightHour();
535 | } else if (this.position >= 3 && this.position <= 5) {
536 | this.highlightMinute();
537 | } else if (this.position >= 6 && this.position <= 8) {
538 | if (this.showSeconds) {
539 | this.highlightSecond();
540 | } else {
541 | this.highlightMeridian();
542 | }
543 | } else if (this.position >= 9 && this.position <= 11) {
544 | this.highlightMeridian();
545 | }
546 | }
547 |
548 | , highlightNextUnit: function() {
549 | switch (this.highlightedUnit) {
550 | case 'hour':
551 | this.highlightMinute();
552 | break;
553 | case 'minute':
554 | if (this.showSeconds) {
555 | this.highlightSecond();
556 | } else {
557 | this.highlightMeridian();
558 | }
559 | break;
560 | case 'second':
561 | this.highlightMeridian();
562 | break;
563 | case 'meridian':
564 | this.highlightHour();
565 | break;
566 | }
567 | }
568 |
569 | , highlightPrevUnit: function() {
570 | switch (this.highlightedUnit) {
571 | case 'hour':
572 | this.highlightMeridian();
573 | break;
574 | case 'minute':
575 | this.highlightHour();
576 | break;
577 | case 'second':
578 | this.highlightMinute();
579 | break;
580 | case 'meridian':
581 | if (this.showSeconds) {
582 | this.highlightSecond();
583 | } else {
584 | this.highlightMinute();
585 | }
586 | break;
587 | }
588 | }
589 |
590 | , highlightHour: function() {
591 | this.highlightedUnit = 'hour';
592 | this.$element.get(0).setSelectionRange(0,2);
593 | }
594 |
595 | , highlightMinute: function() {
596 | this.highlightedUnit = 'minute';
597 | this.$element.get(0).setSelectionRange(3,5);
598 | }
599 |
600 | , highlightSecond: function() {
601 | this.highlightedUnit = 'second';
602 | this.$element.get(0).setSelectionRange(6,8);
603 | }
604 |
605 | , highlightMeridian: function() {
606 | this.highlightedUnit = 'meridian';
607 | if (this.showSeconds) {
608 | this.$element.get(0).setSelectionRange(9,11);
609 | } else {
610 | this.$element.get(0).setSelectionRange(6,8);
611 | }
612 | }
613 |
614 | , incrementHour: function() {
615 | if (this.showMeridian) {
616 | if (this.hour === 11) {
617 | this.toggleMeridian();
618 | } else if (this.hour === 12) {
619 | return this.hour = 1;
620 | }
621 | }
622 | if (this.hour === 23) {
623 | return this.hour = 0;
624 | }
625 | this.hour = this.hour + 1;
626 | }
627 |
628 | , decrementHour: function() {
629 | if (this.showMeridian) {
630 | if (this.hour === 1) {
631 | return this.hour = 12;
632 | }
633 | else if (this.hour === 12) {
634 | this.toggleMeridian();
635 | }
636 | }
637 | if (this.hour === 0) {
638 | return this.hour = 23;
639 | }
640 | this.hour = this.hour - 1;
641 | }
642 |
643 | , incrementMinute: function() {
644 | var newVal = this.minute + this.minuteStep - (this.minute % this.minuteStep);
645 | if (newVal > 59) {
646 | this.incrementHour();
647 | this.minute = newVal - 60;
648 | } else {
649 | this.minute = newVal;
650 | }
651 | }
652 |
653 | , decrementMinute: function() {
654 | var newVal = this.minute - this.minuteStep;
655 | if (newVal < 0) {
656 | this.decrementHour();
657 | this.minute = newVal + 60;
658 | } else {
659 | this.minute = newVal;
660 | }
661 | }
662 |
663 | , incrementSecond: function() {
664 | var newVal = this.second + this.secondStep - (this.second % this.secondStep);
665 | if (newVal > 59) {
666 | this.incrementMinute();
667 | this.second = newVal - 60;
668 | } else {
669 | this.second = newVal;
670 | }
671 | }
672 |
673 | , decrementSecond: function() {
674 | var newVal = this.second - this.secondStep;
675 | if (newVal < 0) {
676 | this.decrementMinute();
677 | this.second = newVal + 60;
678 | } else {
679 | this.second = newVal;
680 | }
681 | }
682 |
683 | , toggleMeridian: function() {
684 | this.meridian = this.meridian === 'AM' ? 'PM' : 'AM';
685 |
686 | this.update();
687 | }
688 |
689 | , getTemplate: function() {
690 | if (this.options.templates[this.options.template]) {
691 | return this.options.templates[this.options.template];
692 | }
693 | if (this.showInputs) {
694 | var hourTemplate = '';
695 | var minuteTemplate = '';
696 | var secondTemplate = '';
697 | var meridianTemplate = '';
698 | } else {
699 | var hourTemplate = '';
700 | var minuteTemplate = '';
701 | var secondTemplate = '';
702 | var meridianTemplate = '';
703 | }
704 | var templateContent = ''+
705 | ''+
706 | ' | '+
707 | ' | '+
708 | ' | '+
709 | (this.showSeconds ?
710 | ' | '+
711 | ' | '
712 | : '') +
713 | (this.showMeridian ?
714 | ' | '+
715 | ' | '
716 | : '') +
717 | '
'+
718 | ''+
719 | '| '+ hourTemplate +' | '+
720 | ': | '+
721 | ''+ minuteTemplate +' | '+
722 | (this.showSeconds ?
723 | ': | '+
724 | ''+ secondTemplate +' | '
725 | : '') +
726 | (this.showMeridian ?
727 | ' | '+
728 | ''+ meridianTemplate +' | '
729 | : '') +
730 | '
'+
731 | ''+
732 | ' | '+
733 | ' | '+
734 | ' | '+
735 | (this.showSeconds ?
736 | ' | '+
737 | ' | '
738 | : '') +
739 | (this.showMeridian ?
740 | ' | '+
741 | ' | '
742 | : '') +
743 | '
'+
744 | '
';
745 |
746 | var template;
747 | switch(this.options.template) {
748 | case 'modal':
749 | template = ''+
750 | ''+
754 | '
'+
755 | templateContent +
756 | '
'+
757 | ''+
760 | '
';
761 |
762 | break;
763 | case 'dropdown':
764 | template = '';
767 | break;
768 |
769 | }
770 | return template;
771 | }
772 | };
773 |
774 |
775 | /* TIMEPICKER PLUGIN DEFINITION
776 | * =========================== */
777 |
778 | $.fn.timepicker = function (option) {
779 | return this.each(function () {
780 | var $this = $(this)
781 | , data = $this.data('timepicker')
782 | , options = typeof option == 'object' && option;
783 | if (!data) {
784 | $this.data('timepicker', (data = new Timepicker(this, options)));
785 | }
786 | if (typeof option == 'string') {
787 | data[option]();
788 | }
789 | })
790 | }
791 |
792 | $.fn.timepicker.defaults = {
793 | minuteStep: 15
794 | , secondStep: 15
795 | , disableFocus: false
796 | , defaultTime: 'current'
797 | , showSeconds: false
798 | , showInputs: true
799 | , showMeridian: true
800 | , template: 'dropdown'
801 | , modalBackdrop: false
802 | , templates: {} // set custom templates
803 | }
804 |
805 | $.fn.timepicker.Constructor = Timepicker
806 | }(window.jQuery);
807 |
--------------------------------------------------------------------------------