undercase 0.2.29 → 0.2.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +30 -4
- data/Rakefile +0 -6
- data/app/assets/images/backgrounds/diag_black.png +0 -0
- data/app/assets/javascripts/undercase/patterns/AbsolutelyPositionTableCells.js +12 -0
- data/app/assets/javascripts/undercase/patterns/Filter.js +6 -0
- data/app/assets/javascripts/undercase/patterns/daterange.js +28 -0
- data/app/assets/javascripts/undercase/patterns/modal.js +1 -4
- data/app/assets/javascripts/undercase/patterns/timepicker.js +6 -1
- data/app/assets/javascripts/undercase/vendor/jquery-extensions/jquery.timepicker.js +1125 -0
- data/app/assets/stylesheets/undercase/libraries/_borders.scss +1 -0
- data/app/assets/stylesheets/undercase/patterns/_borders.scss +9 -0
- data/app/assets/stylesheets/undercase/patterns/_filters.scss +41 -10
- data/app/assets/stylesheets/undercase/patterns/_forms.scss +20 -1
- data/app/assets/stylesheets/undercase/patterns/_layout.scss +14 -0
- data/app/assets/stylesheets/undercase/patterns/_lists.scss +57 -0
- data/app/assets/stylesheets/undercase/patterns/_popovers.scss +5 -0
- data/app/assets/stylesheets/undercase/patterns/_tables.scss +97 -50
- data/app/assets/stylesheets/undercase/patterns/_typography.scss +13 -1
- data/app/assets/stylesheets/undercase/patterns_new_front_end/_cards.scss +45 -0
- data/app/assets/stylesheets/undercase/vendor_static/_all.scss +1 -0
- data/app/assets/stylesheets/undercase/vendor_static/_timepicker.scss +72 -0
- data/app/assets/stylesheets/undercase_frame/_dummy_site.scss +77 -0
- data/app/controllers/undercase/application_controller.rb +1 -0
- data/app/inputs/date_picker_input.rb +2 -2
- data/app/views/layouts/undercase/application.html.haml +6 -1
- data/app/views/undercase/patterns/_definition_list.html.haml +9 -0
- data/app/views/undercase/patterns/_filters.html.haml +13 -0
- data/app/views/undercase/patterns/_filters_show_only.html.haml +5 -0
- data/app/views/undercase/patterns/_grids_basic.html.haml +39 -0
- data/app/views/undercase/patterns/_grids_element_spacing.html.haml +94 -0
- data/app/views/undercase/patterns/_grids_responsive.html.haml +32 -0
- data/app/views/undercase/patterns/_layouts.html.haml +20 -0
- data/app/views/undercase/patterns/_list_long.html.haml +45 -0
- data/app/views/undercase/patterns/_popover.html.haml +23 -6
- data/app/views/undercase/patterns/_tables.html.haml +26 -0
- data/app/views/undercase/patterns/{_tables_small_tablet.html.haml → _tables_unsorted.html.haml} +6 -9
- data/app/views/undercase/patterns/_typography_highlight.html.haml +5 -0
- data/app/views/undercase/patterns/_uc_forms_date_range_picker.html.haml +43 -0
- data/app/views/undercase/patterns/_uc_history_card.html.haml +10 -0
- data/app/views/undercase/patterns/index.html.haml +1 -1
- data/lib/tasks/undercase.rake +53 -0
- data/lib/undercase/patterns/definition_list.yml +4 -0
- data/lib/undercase/patterns/grids_basic.yml +6 -0
- data/lib/undercase/patterns/grids_element_spacing.yml +12 -0
- data/lib/undercase/patterns/grids_responsive.yml +6 -0
- data/lib/undercase/patterns/layouts.yml +6 -0
- data/lib/undercase/patterns/list_long.yml +4 -0
- data/lib/undercase/patterns/tables.yml +4 -0
- data/lib/undercase/patterns/tables_unsorted.yml +4 -0
- data/lib/undercase/patterns/typography_highlight.yml +4 -0
- data/lib/undercase/patterns/uc_forms_date_range_picker.yml +4 -0
- data/lib/undercase/patterns/uc_history_card.yml +4 -0
- data/lib/undercase/version.rb +1 -1
- data/public/undercase-0.2.57.tar.gz +0 -0
- metadata +44 -11
- data/app/views/undercase/patterns/_grid.html.haml +0 -0
- data/app/views/undercase/patterns/_tables_mobile.html.haml +0 -23
- data/app/views/undercase/patterns/_tables_not_desktop.html.haml +0 -21
- data/app/views/undercase/patterns/_tables_small_mobile.html.haml +0 -23
- data/lib/undercase/patterns/grid.yml +0 -4
- data/lib/undercase/patterns/tables_mobile.yml +0 -4
- data/lib/undercase/patterns/tables_not_desktop.yml +0 -4
- data/lib/undercase/patterns/tables_small_tablet.yml +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebced5cd0f92992df799035022405dd789abe974
|
4
|
+
data.tar.gz: 69e298b6c3f0d5231143cde630f5d6130138bfcc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85c75b6c48ffc9fe56b3417887e6096bfbe0118af8f4ed3468286259d01c29711197befc93ab5f8ea0a39da7dab9a578ebdb85d99c2d2fb5afefa961fb3f1f97
|
7
|
+
data.tar.gz: 15a94f93c4f06fb826af88655c2763318bc74d28faa24ad3578b1ed21b69699b4dd486a2ed5410cfdfc5f3355a4862c58df9f5acac673917ecc3e7532e210639
|
data/README.md
CHANGED
@@ -46,13 +46,39 @@ Undercase provides a rake task to easily create the files needed for a new patte
|
|
46
46
|
rake pattern:create[PATTERNNAME,'DISPLAY NAME']
|
47
47
|
|
48
48
|
This will append your new pattern to
|
49
|
-
|
49
|
+
|
50
|
+
* `app/assets/stylesheets/undercase/_patterns.scss`
|
50
51
|
|
51
52
|
This will create new files in:
|
52
|
-
* app/assets/stylesheets/undercase/patterns_PATTERNNAME.scss
|
53
|
-
* app/views/undercase/patterns/PATTERNNAME.html.haml
|
54
|
-
* lib/undercase/patterns/PATTERNNAME.yml
|
55
53
|
|
54
|
+
* `app/assets/stylesheets/undercase/patterns_PATTERNNAME.scss`
|
55
|
+
* `app/views/undercase/patterns/PATTERNNAME.html.haml`
|
56
|
+
* `lib/undercase/patterns/PATTERNNAME.yml`
|
57
|
+
|
58
|
+
## undercase:release rake task
|
59
|
+
|
60
|
+
On master branch at root of undercase:
|
61
|
+
|
62
|
+
Use undercase:release rake task
|
63
|
+
|
64
|
+
* to do a patch release: run `rake undercase:release`
|
65
|
+
* to do a major/minor release run `VERSION=1.2.3 rake undercase:release`
|
66
|
+
|
67
|
+
###Comprised of smaller tasks:
|
68
|
+
|
69
|
+
#### undercase:bump
|
70
|
+
Sets or increments the version in version.rb.
|
71
|
+
|
72
|
+
If given a version, (for major/minor or non-sequential releases) will use that. Otherwise will increment the current version number.
|
73
|
+
|
74
|
+
#### tag
|
75
|
+
Uses current version number to create tag and push tag
|
76
|
+
|
77
|
+
#### undercase:package
|
78
|
+
Compiles assets and adds them to tar file
|
79
|
+
|
80
|
+
#### undercase:deploy
|
81
|
+
Pushes local master branch to github and heroku
|
56
82
|
|
57
83
|
## Contributing
|
58
84
|
Undercase is a container for generalizable patterns. Keep the following criteria in mind when creating and submitting a new pattern.
|
data/Rakefile
CHANGED
@@ -8,14 +8,8 @@ rescue LoadError => ex
|
|
8
8
|
end
|
9
9
|
|
10
10
|
root = File.expand_path('..', __FILE__)
|
11
|
-
gem_helper = Bundler::GemHelper.new(root)
|
12
11
|
Bundler::GemHelper.install_tasks
|
13
12
|
defined?(RSpec) and RSpec::Core::RakeTask.new(:spec)
|
14
13
|
Dir.glob('./lib/tasks/*.rake').each { |r| import r }
|
15
14
|
|
16
15
|
task :default => :spec
|
17
|
-
|
18
|
-
desc "Create and push tag #{gem_helper.send(:version_tag)}"
|
19
|
-
task :tag do
|
20
|
-
gem_helper.send(:tag_version) { gem_helper.send(:git_push) }
|
21
|
-
end
|
Binary file
|
@@ -0,0 +1,12 @@
|
|
1
|
+
(function($) {
|
2
|
+
$(document).on('AbsolutelyPositionTableCells:present', function(event){
|
3
|
+
var ths = $(event.target).find('thead th');
|
4
|
+
var sortableThs = ths.has('a');
|
5
|
+
var unsortableThs = ths.not(sortableThs);
|
6
|
+
var newDiv = $('<div>', {class: 'uc-table__th__inner-wrapper'});
|
7
|
+
var newSortableDiv = $('<div>', {class: 'uc-table__th__inner-wrapper uc-table__th__inner-wrapper--sortable'});
|
8
|
+
|
9
|
+
unsortableThs.wrapInner(newDiv);
|
10
|
+
sortableThs.wrapInner(newSortableDiv);
|
11
|
+
});
|
12
|
+
})(jQuery);
|
@@ -5,6 +5,12 @@
|
|
5
5
|
var facets = $('.js-filter__facet', section);
|
6
6
|
var subFacets = $('.js-filter__sub-facet', section);
|
7
7
|
|
8
|
+
var facetsAndSubFacets = facets.toArray().concat(subFacets.toArray());
|
9
|
+
var facetsOrSubFacetsChecked = _.any(facetsAndSubFacets, function(facet) {
|
10
|
+
return $(facet).is(':checked');
|
11
|
+
});
|
12
|
+
if(facetsOrSubFacetsChecked) { clearLink.show(); }
|
13
|
+
|
8
14
|
// Facet changed
|
9
15
|
facets.on('change', function(event) {
|
10
16
|
var facet = $(event.target);
|
@@ -0,0 +1,28 @@
|
|
1
|
+
(function($) {
|
2
|
+
$(document).on('daterange:present', function(event) {
|
3
|
+
var self = $(event.target);
|
4
|
+
var $checkbox = self.find(".js-present input[type=checkbox]");
|
5
|
+
checkboxDaterangeToggle($checkbox, self);
|
6
|
+
$checkbox.change(function(e) { checkboxDaterangeToggle($(e.target), self); });
|
7
|
+
|
8
|
+
function checkboxDaterangeToggle($checkbox, self) {
|
9
|
+
var $present = self.find('.js-present');
|
10
|
+
var $daterangeEndFields = self.find(".js-daterange-end-fields");
|
11
|
+
var isEnabler = self.data("daterangeToggler") == "enabler";
|
12
|
+
|
13
|
+
if($checkbox.prop("checked") == isEnabler) {
|
14
|
+
$present.removeClass('ongoing');
|
15
|
+
$daterangeEndFields.show();
|
16
|
+
} else {
|
17
|
+
$present.addClass('ongoing');
|
18
|
+
$daterangeEndFields.hide();
|
19
|
+
clearDependentFields();
|
20
|
+
}
|
21
|
+
|
22
|
+
function clearDependentFields() {
|
23
|
+
$daterangeEndFields.find('input').val('');
|
24
|
+
$daterangeEndFields.find('select').val('');
|
25
|
+
}
|
26
|
+
}
|
27
|
+
});
|
28
|
+
})(jQuery);
|
@@ -27,7 +27,6 @@
|
|
27
27
|
modalFixedWrapperFrame.css("background", "none");
|
28
28
|
$("body").addClass("modal-on");
|
29
29
|
$('html, body').animate({ scrollTop: 0 }, 0);
|
30
|
-
self.wasHidden = self.target.hasClass('js-hidden');
|
31
30
|
self.target.removeClass('js-hidden');
|
32
31
|
|
33
32
|
self.target.click(function(event) {
|
@@ -41,9 +40,7 @@
|
|
41
40
|
$("body").removeClass("modal-on");
|
42
41
|
$('.uc-modal-fixed-wrapper').remove();
|
43
42
|
self.target.trigger('closed');
|
44
|
-
|
45
|
-
self.target.addClass('js-hidden');
|
46
|
-
}
|
43
|
+
self.target.addClass('js-hidden');
|
47
44
|
}
|
48
45
|
})
|
49
46
|
};
|
@@ -1,5 +1,10 @@
|
|
1
1
|
(function($, ns) {
|
2
2
|
$(document).on('timepicker:present', function(event) {
|
3
|
-
$(event.target).
|
3
|
+
$(event.target).timepicker({
|
4
|
+
'scrollDefault': 'now',
|
5
|
+
'showOnFocus': false,
|
6
|
+
'step': 15,
|
7
|
+
'timeFormat': 'h:i A'
|
8
|
+
});
|
4
9
|
});
|
5
10
|
})(jQuery);
|
@@ -0,0 +1,1125 @@
|
|
1
|
+
/************************
|
2
|
+
jquery-timepicker v1.4.6
|
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 _lang = {
|
21
|
+
am: 'am',
|
22
|
+
pm: 'pm',
|
23
|
+
AM: 'AM',
|
24
|
+
PM: 'PM',
|
25
|
+
decimal: '.',
|
26
|
+
mins: 'mins',
|
27
|
+
hr: 'hr',
|
28
|
+
hrs: 'hrs'
|
29
|
+
};
|
30
|
+
|
31
|
+
var methods =
|
32
|
+
{
|
33
|
+
init: function(options)
|
34
|
+
{
|
35
|
+
return this.each(function()
|
36
|
+
{
|
37
|
+
var self = $(this);
|
38
|
+
|
39
|
+
// pick up settings from data attributes
|
40
|
+
var attributeOptions = [];
|
41
|
+
for (var key in $.fn.timepicker.defaults) {
|
42
|
+
if (self.data(key)) {
|
43
|
+
attributeOptions[key] = self.data(key);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
var settings = $.extend({}, $.fn.timepicker.defaults, attributeOptions, options);
|
48
|
+
|
49
|
+
if (settings.lang) {
|
50
|
+
_lang = $.extend(_lang, settings.lang);
|
51
|
+
}
|
52
|
+
|
53
|
+
settings = _parseSettings(settings);
|
54
|
+
self.data('timepicker-settings', settings);
|
55
|
+
self.addClass('ui-timepicker-input');
|
56
|
+
|
57
|
+
if (settings.useSelect) {
|
58
|
+
_render(self);
|
59
|
+
} else {
|
60
|
+
self.prop('autocomplete', 'off');
|
61
|
+
self.on('click.timepicker focus.timepicker', methods.show);
|
62
|
+
self.on('change.timepicker', _formatValue);
|
63
|
+
self.on('keydown.timepicker', _keydownhandler);
|
64
|
+
self.on('keyup.timepicker', _keyuphandler);
|
65
|
+
|
66
|
+
_formatValue.call(self.get(0));
|
67
|
+
}
|
68
|
+
});
|
69
|
+
},
|
70
|
+
|
71
|
+
show: function(e)
|
72
|
+
{
|
73
|
+
var self = $(this);
|
74
|
+
var settings = self.data('timepicker-settings');
|
75
|
+
|
76
|
+
if (e) {
|
77
|
+
if (!settings.showOnFocus) {
|
78
|
+
return true;
|
79
|
+
}
|
80
|
+
|
81
|
+
e.preventDefault();
|
82
|
+
}
|
83
|
+
|
84
|
+
if (settings.useSelect) {
|
85
|
+
self.data('timepicker-list').focus();
|
86
|
+
return;
|
87
|
+
}
|
88
|
+
|
89
|
+
if (_hideKeyboard(self)) {
|
90
|
+
// block the keyboard on mobile devices
|
91
|
+
self.blur();
|
92
|
+
}
|
93
|
+
|
94
|
+
var list = self.data('timepicker-list');
|
95
|
+
|
96
|
+
// check if input is readonly
|
97
|
+
if (self.prop('readonly')) {
|
98
|
+
return;
|
99
|
+
}
|
100
|
+
|
101
|
+
// check if list needs to be rendered
|
102
|
+
if (!list || list.length === 0 || typeof settings.durationTime === 'function') {
|
103
|
+
_render(self);
|
104
|
+
list = self.data('timepicker-list');
|
105
|
+
}
|
106
|
+
|
107
|
+
if (list.is(':visible')) {
|
108
|
+
return;
|
109
|
+
}
|
110
|
+
|
111
|
+
// make sure other pickers are hidden
|
112
|
+
methods.hide();
|
113
|
+
|
114
|
+
// position the dropdown relative to the input
|
115
|
+
list.show();
|
116
|
+
var listOffset = {};
|
117
|
+
|
118
|
+
if (settings.orientation == 'rtl') {
|
119
|
+
// right-align the dropdown
|
120
|
+
listOffset.left = self.offset().left + self.outerWidth() - list.outerWidth() + parseInt(list.css('marginLeft').replace('px', ''), 10);
|
121
|
+
} else {
|
122
|
+
// left-align the dropdown
|
123
|
+
listOffset.left = self.offset().left + parseInt(list.css('marginLeft').replace('px', ''), 10);
|
124
|
+
}
|
125
|
+
|
126
|
+
if ((self.offset().top + self.outerHeight(true) + list.outerHeight()) > $(window).height() + $(window).scrollTop()) {
|
127
|
+
// position the dropdown on top
|
128
|
+
listOffset.top = self.offset().top - list.outerHeight() + parseInt(list.css('marginTop').replace('px', ''), 10);
|
129
|
+
} else {
|
130
|
+
// put it under the input
|
131
|
+
listOffset.top = self.offset().top + self.outerHeight() + parseInt(list.css('marginTop').replace('px', ''), 10);
|
132
|
+
}
|
133
|
+
|
134
|
+
list.offset(listOffset);
|
135
|
+
|
136
|
+
// position scrolling
|
137
|
+
var selected = list.find('.ui-timepicker-selected');
|
138
|
+
|
139
|
+
if (!selected.length) {
|
140
|
+
if (_getTimeValue(self)) {
|
141
|
+
selected = _findRow(self, list, _time2int(_getTimeValue(self)));
|
142
|
+
} else if (settings.scrollDefault) {
|
143
|
+
selected = _findRow(self, list, settings.scrollDefault);
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
if (selected && selected.length) {
|
148
|
+
var topOffset = list.scrollTop() + selected.position().top - selected.outerHeight();
|
149
|
+
list.scrollTop(topOffset);
|
150
|
+
} else {
|
151
|
+
list.scrollTop(0);
|
152
|
+
}
|
153
|
+
|
154
|
+
// attach close handlers
|
155
|
+
$(document).on('touchstart.ui-timepicker mousedown.ui-timepicker', _closeHandler);
|
156
|
+
if (settings.closeOnWindowScroll) {
|
157
|
+
$(document).on('scroll.ui-timepicker', _closeHandler);
|
158
|
+
}
|
159
|
+
|
160
|
+
self.trigger('showTimepicker');
|
161
|
+
|
162
|
+
return this;
|
163
|
+
},
|
164
|
+
|
165
|
+
hide: function(e)
|
166
|
+
{
|
167
|
+
var self = $(this);
|
168
|
+
var settings = self.data('timepicker-settings');
|
169
|
+
|
170
|
+
if (settings && settings.useSelect) {
|
171
|
+
self.blur();
|
172
|
+
}
|
173
|
+
|
174
|
+
$('.ui-timepicker-wrapper:visible').each(function() {
|
175
|
+
var list = $(this);
|
176
|
+
var self = list.data('timepicker-input');
|
177
|
+
var settings = self.data('timepicker-settings');
|
178
|
+
|
179
|
+
if (settings && settings.selectOnBlur) {
|
180
|
+
_selectValue(self);
|
181
|
+
}
|
182
|
+
|
183
|
+
list.hide();
|
184
|
+
self.trigger('hideTimepicker');
|
185
|
+
});
|
186
|
+
|
187
|
+
return this;
|
188
|
+
},
|
189
|
+
|
190
|
+
option: function(key, value)
|
191
|
+
{
|
192
|
+
return this.each(function(){
|
193
|
+
var self = $(this);
|
194
|
+
var settings = self.data('timepicker-settings');
|
195
|
+
var list = self.data('timepicker-list');
|
196
|
+
|
197
|
+
if (typeof key == 'object') {
|
198
|
+
settings = $.extend(settings, key);
|
199
|
+
|
200
|
+
} else if (typeof key == 'string' && typeof value != 'undefined') {
|
201
|
+
settings[key] = value;
|
202
|
+
|
203
|
+
} else if (typeof key == 'string') {
|
204
|
+
return settings[key];
|
205
|
+
}
|
206
|
+
|
207
|
+
settings = _parseSettings(settings);
|
208
|
+
|
209
|
+
self.data('timepicker-settings', settings);
|
210
|
+
|
211
|
+
if (list) {
|
212
|
+
list.remove();
|
213
|
+
self.data('timepicker-list', false);
|
214
|
+
}
|
215
|
+
|
216
|
+
if (settings.useSelect) {
|
217
|
+
_render(self);
|
218
|
+
}
|
219
|
+
});
|
220
|
+
},
|
221
|
+
|
222
|
+
getSecondsFromMidnight: function()
|
223
|
+
{
|
224
|
+
return _time2int(_getTimeValue(this));
|
225
|
+
},
|
226
|
+
|
227
|
+
getTime: function(relative_date)
|
228
|
+
{
|
229
|
+
var self = this;
|
230
|
+
|
231
|
+
var time_string = _getTimeValue(self);
|
232
|
+
if (!time_string) {
|
233
|
+
return null;
|
234
|
+
}
|
235
|
+
|
236
|
+
if (!relative_date) {
|
237
|
+
relative_date = new Date();
|
238
|
+
}
|
239
|
+
var offset = _time2int(time_string);
|
240
|
+
|
241
|
+
// construct a Date with today's date, and offset's time
|
242
|
+
var time = new Date(relative_date);
|
243
|
+
time.setHours(offset / 3600);
|
244
|
+
time.setMinutes(offset % 3600 / 60);
|
245
|
+
time.setSeconds(offset % 60);
|
246
|
+
time.setMilliseconds(0);
|
247
|
+
|
248
|
+
return time;
|
249
|
+
},
|
250
|
+
|
251
|
+
setTime: function(value)
|
252
|
+
{
|
253
|
+
var self = this;
|
254
|
+
var settings = self.data('timepicker-settings');
|
255
|
+
|
256
|
+
if (settings.forceRoundTime) {
|
257
|
+
var prettyTime = _roundAndFormatTime(value, settings)
|
258
|
+
} else {
|
259
|
+
var prettyTime = _int2time(_time2int(value), settings.timeFormat);
|
260
|
+
}
|
261
|
+
|
262
|
+
_setTimeValue(self, prettyTime);
|
263
|
+
if (self.data('timepicker-list')) {
|
264
|
+
_setSelected(self, self.data('timepicker-list'));
|
265
|
+
}
|
266
|
+
|
267
|
+
return this;
|
268
|
+
},
|
269
|
+
|
270
|
+
remove: function()
|
271
|
+
{
|
272
|
+
var self = this;
|
273
|
+
|
274
|
+
// check if this element is a timepicker
|
275
|
+
if (!self.hasClass('ui-timepicker-input')) {
|
276
|
+
return;
|
277
|
+
}
|
278
|
+
|
279
|
+
var settings = self.data('timepicker-settings');
|
280
|
+
self.removeAttr('autocomplete', 'off');
|
281
|
+
self.removeClass('ui-timepicker-input');
|
282
|
+
self.removeData('timepicker-settings');
|
283
|
+
self.off('.timepicker');
|
284
|
+
|
285
|
+
// timepicker-list won't be present unless the user has interacted with this timepicker
|
286
|
+
if (self.data('timepicker-list')) {
|
287
|
+
self.data('timepicker-list').remove();
|
288
|
+
}
|
289
|
+
|
290
|
+
if (settings.useSelect) {
|
291
|
+
self.show();
|
292
|
+
}
|
293
|
+
|
294
|
+
self.removeData('timepicker-list');
|
295
|
+
|
296
|
+
return this;
|
297
|
+
}
|
298
|
+
};
|
299
|
+
|
300
|
+
// private methods
|
301
|
+
|
302
|
+
function _parseSettings(settings)
|
303
|
+
{
|
304
|
+
if (settings.minTime) {
|
305
|
+
settings.minTime = _time2int(settings.minTime);
|
306
|
+
}
|
307
|
+
|
308
|
+
if (settings.maxTime) {
|
309
|
+
settings.maxTime = _time2int(settings.maxTime);
|
310
|
+
}
|
311
|
+
|
312
|
+
if (settings.durationTime && typeof settings.durationTime !== 'function') {
|
313
|
+
settings.durationTime = _time2int(settings.durationTime);
|
314
|
+
}
|
315
|
+
|
316
|
+
if (settings.scrollDefault == 'now') {
|
317
|
+
settings.scrollDefault = _time2int(new Date());
|
318
|
+
} else if (settings.scrollDefault) {
|
319
|
+
settings.scrollDefault = _time2int(settings.scrollDefault);
|
320
|
+
} else if (settings.minTime) {
|
321
|
+
settings.scrollDefault = settings.minTime;
|
322
|
+
}
|
323
|
+
|
324
|
+
if (settings.scrollDefault) {
|
325
|
+
settings.scrollDefault = _roundTime(settings.scrollDefault, settings);
|
326
|
+
}
|
327
|
+
|
328
|
+
if (settings.timeFormat.match(/[gh]/)) {
|
329
|
+
settings._twelveHourTime = true;
|
330
|
+
}
|
331
|
+
|
332
|
+
if (settings.disableTimeRanges.length > 0) {
|
333
|
+
// convert string times to integers
|
334
|
+
for (var i in settings.disableTimeRanges) {
|
335
|
+
settings.disableTimeRanges[i] = [
|
336
|
+
_time2int(settings.disableTimeRanges[i][0]),
|
337
|
+
_time2int(settings.disableTimeRanges[i][1])
|
338
|
+
];
|
339
|
+
}
|
340
|
+
|
341
|
+
// sort by starting time
|
342
|
+
settings.disableTimeRanges = settings.disableTimeRanges.sort(function(a, b){
|
343
|
+
return a[0] - b[0];
|
344
|
+
});
|
345
|
+
|
346
|
+
// merge any overlapping ranges
|
347
|
+
for (var i = settings.disableTimeRanges.length-1; i > 0; i--) {
|
348
|
+
if (settings.disableTimeRanges[i][0] <= settings.disableTimeRanges[i-1][1]) {
|
349
|
+
settings.disableTimeRanges[i-1] = [
|
350
|
+
Math.min(settings.disableTimeRanges[i][0], settings.disableTimeRanges[i-1][0]),
|
351
|
+
Math.max(settings.disableTimeRanges[i][1], settings.disableTimeRanges[i-1][1])
|
352
|
+
];
|
353
|
+
settings.disableTimeRanges.splice(i, 1);
|
354
|
+
}
|
355
|
+
}
|
356
|
+
}
|
357
|
+
|
358
|
+
return settings;
|
359
|
+
}
|
360
|
+
|
361
|
+
function _render(self)
|
362
|
+
{
|
363
|
+
var settings = self.data('timepicker-settings');
|
364
|
+
var list = self.data('timepicker-list');
|
365
|
+
|
366
|
+
if (list && list.length) {
|
367
|
+
list.remove();
|
368
|
+
self.data('timepicker-list', false);
|
369
|
+
}
|
370
|
+
|
371
|
+
if (settings.useSelect) {
|
372
|
+
list = $('<select />', { 'class': 'ui-timepicker-select' });
|
373
|
+
var wrapped_list = list;
|
374
|
+
} else {
|
375
|
+
list = $('<ul />', { 'class': 'ui-timepicker-list' });
|
376
|
+
|
377
|
+
var wrapped_list = $('<div />', { 'class': 'ui-timepicker-wrapper', 'tabindex': -1 });
|
378
|
+
wrapped_list.css({'display':'none', 'position': 'absolute' }).append(list);
|
379
|
+
}
|
380
|
+
|
381
|
+
if (settings.noneOption) {
|
382
|
+
if (settings.noneOption === true) {
|
383
|
+
settings.noneOption = (settings.useSelect) ? 'Time...' : 'None';
|
384
|
+
}
|
385
|
+
|
386
|
+
if ($.isArray(settings.noneOption)) {
|
387
|
+
for (var i in settings.noneOption) {
|
388
|
+
if (parseInt(i, 10) === i){
|
389
|
+
var noneElement = _generateNoneElement(settings.noneOption[i], settings.useSelect);
|
390
|
+
list.append(noneElement);
|
391
|
+
}
|
392
|
+
}
|
393
|
+
} else {
|
394
|
+
var noneElement = _generateNoneElement(settings.noneOption, settings.useSelect);
|
395
|
+
list.append(noneElement);
|
396
|
+
}
|
397
|
+
}
|
398
|
+
|
399
|
+
if (settings.className) {
|
400
|
+
wrapped_list.addClass(settings.className);
|
401
|
+
}
|
402
|
+
|
403
|
+
if ((settings.minTime !== null || settings.durationTime !== null) && settings.showDuration) {
|
404
|
+
wrapped_list.addClass('ui-timepicker-with-duration');
|
405
|
+
wrapped_list.addClass('ui-timepicker-step-'+settings.step);
|
406
|
+
}
|
407
|
+
|
408
|
+
var durStart = settings.minTime;
|
409
|
+
if (typeof settings.durationTime === 'function') {
|
410
|
+
durStart = _time2int(settings.durationTime());
|
411
|
+
} else if (settings.durationTime !== null) {
|
412
|
+
durStart = settings.durationTime;
|
413
|
+
}
|
414
|
+
var start = (settings.minTime !== null) ? settings.minTime : 0;
|
415
|
+
var end = (settings.maxTime !== null) ? settings.maxTime : (start + _ONE_DAY - 1);
|
416
|
+
|
417
|
+
if (end <= start) {
|
418
|
+
// make sure the end time is greater than start time, otherwise there will be no list to show
|
419
|
+
end += _ONE_DAY;
|
420
|
+
}
|
421
|
+
|
422
|
+
if (end === _ONE_DAY-1 && settings.timeFormat.indexOf('H') !== -1) {
|
423
|
+
// show a 24:00 option when using military time
|
424
|
+
end = _ONE_DAY;
|
425
|
+
}
|
426
|
+
|
427
|
+
var dr = settings.disableTimeRanges;
|
428
|
+
var drCur = 0;
|
429
|
+
var drLen = dr.length;
|
430
|
+
|
431
|
+
for (var i=start; i <= end; i += settings.step*60) {
|
432
|
+
var timeInt = i;
|
433
|
+
var timeString = _int2time(timeInt, settings.timeFormat);
|
434
|
+
|
435
|
+
if (settings.useSelect) {
|
436
|
+
var row = $('<option />', { 'value': timeString });
|
437
|
+
row.text(timeString);
|
438
|
+
} else {
|
439
|
+
var row = $('<li />');
|
440
|
+
row.data('time', (timeInt <= 86400 ? timeInt : timeInt % 86400));
|
441
|
+
row.text(timeString);
|
442
|
+
}
|
443
|
+
|
444
|
+
if ((settings.minTime !== null || settings.durationTime !== null) && settings.showDuration) {
|
445
|
+
var durationString = _int2duration(i - durStart, settings.step);
|
446
|
+
if (settings.useSelect) {
|
447
|
+
row.text(row.text()+' ('+durationString+')');
|
448
|
+
} else {
|
449
|
+
var duration = $('<span />', { 'class': 'ui-timepicker-duration' });
|
450
|
+
duration.text(' ('+durationString+')');
|
451
|
+
row.append(duration);
|
452
|
+
}
|
453
|
+
}
|
454
|
+
|
455
|
+
if (drCur < drLen) {
|
456
|
+
if (timeInt >= dr[drCur][1]) {
|
457
|
+
drCur += 1;
|
458
|
+
}
|
459
|
+
|
460
|
+
if (dr[drCur] && timeInt >= dr[drCur][0] && timeInt < dr[drCur][1]) {
|
461
|
+
if (settings.useSelect) {
|
462
|
+
row.prop('disabled', true);
|
463
|
+
} else {
|
464
|
+
row.addClass('ui-timepicker-disabled');
|
465
|
+
}
|
466
|
+
}
|
467
|
+
}
|
468
|
+
|
469
|
+
list.append(row);
|
470
|
+
}
|
471
|
+
|
472
|
+
wrapped_list.data('timepicker-input', self);
|
473
|
+
self.data('timepicker-list', wrapped_list);
|
474
|
+
|
475
|
+
if (settings.useSelect) {
|
476
|
+
list.val(_roundAndFormatTime(self.val(), settings));
|
477
|
+
list.on('focus', function(){
|
478
|
+
$(this).data('timepicker-input').trigger('showTimepicker');
|
479
|
+
});
|
480
|
+
list.on('blur', function(){
|
481
|
+
$(this).data('timepicker-input').trigger('hideTimepicker');
|
482
|
+
});
|
483
|
+
list.on('change', function(){
|
484
|
+
_setTimeValue(self, $(this).val(), 'select');
|
485
|
+
});
|
486
|
+
|
487
|
+
self.hide().after(list);
|
488
|
+
} else {
|
489
|
+
var appendTo = settings.appendTo;
|
490
|
+
if (typeof appendTo === 'string') {
|
491
|
+
appendTo = $(appendTo);
|
492
|
+
} else if (typeof appendTo === 'function') {
|
493
|
+
appendTo = appendTo(self);
|
494
|
+
}
|
495
|
+
appendTo.append(wrapped_list);
|
496
|
+
_setSelected(self, list);
|
497
|
+
|
498
|
+
list.on('mousedown', 'li', function(e) {
|
499
|
+
|
500
|
+
// hack: temporarily disable the focus handler
|
501
|
+
// to deal with the fact that IE fires 'focus'
|
502
|
+
// events asynchronously
|
503
|
+
self.off('focus.timepicker');
|
504
|
+
self.on('focus.timepicker-ie-hack', function(){
|
505
|
+
self.off('focus.timepicker-ie-hack');
|
506
|
+
self.on('focus.timepicker', methods.show);
|
507
|
+
});
|
508
|
+
|
509
|
+
if (!_hideKeyboard(self)) {
|
510
|
+
self[0].focus();
|
511
|
+
}
|
512
|
+
|
513
|
+
// make sure only the clicked row is selected
|
514
|
+
list.find('li').removeClass('ui-timepicker-selected');
|
515
|
+
$(this).addClass('ui-timepicker-selected');
|
516
|
+
|
517
|
+
if (_selectValue(self)) {
|
518
|
+
self.trigger('hideTimepicker');
|
519
|
+
wrapped_list.hide();
|
520
|
+
}
|
521
|
+
});
|
522
|
+
}
|
523
|
+
}
|
524
|
+
|
525
|
+
function _generateNoneElement(optionValue, useSelect)
|
526
|
+
{
|
527
|
+
var label, className, value;
|
528
|
+
|
529
|
+
if (typeof optionValue == 'object') {
|
530
|
+
label = optionValue.label;
|
531
|
+
className = optionValue.className;
|
532
|
+
value = optionValue.value;
|
533
|
+
} else if (typeof optionValue == 'string') {
|
534
|
+
label = optionValue;
|
535
|
+
} else {
|
536
|
+
$.error('Invalid noneOption value');
|
537
|
+
}
|
538
|
+
|
539
|
+
if (useSelect) {
|
540
|
+
return $('<option />', {
|
541
|
+
'value': value,
|
542
|
+
'class': className,
|
543
|
+
'text': label
|
544
|
+
});
|
545
|
+
} else {
|
546
|
+
return $('<li />', {
|
547
|
+
'class': className,
|
548
|
+
'text': label
|
549
|
+
}).data('time', value);
|
550
|
+
}
|
551
|
+
}
|
552
|
+
|
553
|
+
function _roundTime(seconds, settings)
|
554
|
+
{
|
555
|
+
if (!$.isNumeric(seconds)) {
|
556
|
+
seconds = _time2int(seconds);
|
557
|
+
}
|
558
|
+
|
559
|
+
if (seconds === null) {
|
560
|
+
return null;
|
561
|
+
} else {
|
562
|
+
var offset = seconds % (settings.step*60); // step is in minutes
|
563
|
+
|
564
|
+
if (offset >= settings.step*30) {
|
565
|
+
// if offset is larger than a half step, round up
|
566
|
+
seconds += (settings.step*60) - offset;
|
567
|
+
} else {
|
568
|
+
// round down
|
569
|
+
seconds -= offset;
|
570
|
+
}
|
571
|
+
|
572
|
+
return seconds;
|
573
|
+
}
|
574
|
+
}
|
575
|
+
|
576
|
+
function _roundAndFormatTime(seconds, settings)
|
577
|
+
{
|
578
|
+
seconds = _roundTime(seconds, settings);
|
579
|
+
if (seconds !== null) {
|
580
|
+
return _int2time(seconds, settings.timeFormat);
|
581
|
+
}
|
582
|
+
}
|
583
|
+
|
584
|
+
function _generateBaseDate()
|
585
|
+
{
|
586
|
+
return new Date(1970, 1, 1, 0, 0, 0);
|
587
|
+
}
|
588
|
+
|
589
|
+
// event handler to decide whether to close timepicker
|
590
|
+
function _closeHandler(e)
|
591
|
+
{
|
592
|
+
var target = $(e.target);
|
593
|
+
var input = target.closest('.ui-timepicker-input');
|
594
|
+
if (input.length === 0 && target.closest('.ui-timepicker-wrapper').length === 0) {
|
595
|
+
methods.hide();
|
596
|
+
$(document).unbind('.ui-timepicker');
|
597
|
+
}
|
598
|
+
}
|
599
|
+
|
600
|
+
function _hideKeyboard(self)
|
601
|
+
{
|
602
|
+
var settings = self.data('timepicker-settings');
|
603
|
+
return ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && settings.disableTouchKeyboard);
|
604
|
+
}
|
605
|
+
|
606
|
+
function _findRow(self, list, value)
|
607
|
+
{
|
608
|
+
if (!value && value !== 0) {
|
609
|
+
return false;
|
610
|
+
}
|
611
|
+
|
612
|
+
var settings = self.data('timepicker-settings');
|
613
|
+
var out = false;
|
614
|
+
var halfStep = settings.step*30;
|
615
|
+
|
616
|
+
// loop through the menu items
|
617
|
+
list.find('li').each(function(i, obj) {
|
618
|
+
var jObj = $(obj);
|
619
|
+
if (typeof jObj.data('time') != 'number') {
|
620
|
+
return;
|
621
|
+
}
|
622
|
+
|
623
|
+
var offset = jObj.data('time') - value;
|
624
|
+
|
625
|
+
// check if the value is less than half a step from each row
|
626
|
+
if (Math.abs(offset) < halfStep || offset == halfStep) {
|
627
|
+
out = jObj;
|
628
|
+
return false;
|
629
|
+
}
|
630
|
+
});
|
631
|
+
|
632
|
+
return out;
|
633
|
+
}
|
634
|
+
|
635
|
+
function _setSelected(self, list)
|
636
|
+
{
|
637
|
+
list.find('li').removeClass('ui-timepicker-selected');
|
638
|
+
|
639
|
+
var timeValue = _time2int(_getTimeValue(self), self.data('timepicker-settings'));
|
640
|
+
if (timeValue === null) {
|
641
|
+
return;
|
642
|
+
}
|
643
|
+
|
644
|
+
var selected = _findRow(self, list, timeValue);
|
645
|
+
if (selected) {
|
646
|
+
|
647
|
+
var topDelta = selected.offset().top - list.offset().top;
|
648
|
+
|
649
|
+
if (topDelta + selected.outerHeight() > list.outerHeight() || topDelta < 0) {
|
650
|
+
list.scrollTop(list.scrollTop() + selected.position().top - selected.outerHeight());
|
651
|
+
}
|
652
|
+
|
653
|
+
selected.addClass('ui-timepicker-selected');
|
654
|
+
}
|
655
|
+
}
|
656
|
+
|
657
|
+
|
658
|
+
function _formatValue(e)
|
659
|
+
{
|
660
|
+
if (this.value === '') {
|
661
|
+
return;
|
662
|
+
}
|
663
|
+
|
664
|
+
var self = $(this);
|
665
|
+
var list = self.data('timepicker-list');
|
666
|
+
|
667
|
+
if (self.is(':focus') && (!e || e.type != 'change')) {
|
668
|
+
return;
|
669
|
+
}
|
670
|
+
|
671
|
+
var seconds = _time2int(this.value);
|
672
|
+
|
673
|
+
if (seconds === null) {
|
674
|
+
self.trigger('timeFormatError');
|
675
|
+
return;
|
676
|
+
}
|
677
|
+
|
678
|
+
var settings = self.data('timepicker-settings');
|
679
|
+
var rangeError = false;
|
680
|
+
// check that the time in within bounds
|
681
|
+
if (settings.minTime !== null && seconds < settings.minTime) {
|
682
|
+
rangeError = true;
|
683
|
+
} else if (settings.maxTime !== null && seconds > settings.maxTime) {
|
684
|
+
rangeError = true;
|
685
|
+
}
|
686
|
+
|
687
|
+
// check that time isn't within disabled time ranges
|
688
|
+
$.each(settings.disableTimeRanges, function(){
|
689
|
+
if (seconds >= this[0] && seconds < this[1]) {
|
690
|
+
rangeError = true;
|
691
|
+
return false;
|
692
|
+
}
|
693
|
+
});
|
694
|
+
|
695
|
+
if (settings.forceRoundTime) {
|
696
|
+
var offset = seconds % (settings.step*60); // step is in minutes
|
697
|
+
|
698
|
+
if (offset >= settings.step*30) {
|
699
|
+
// if offset is larger than a half step, round up
|
700
|
+
seconds += (settings.step*60) - offset;
|
701
|
+
} else {
|
702
|
+
// round down
|
703
|
+
seconds -= offset;
|
704
|
+
}
|
705
|
+
}
|
706
|
+
|
707
|
+
var prettyTime = _int2time(seconds, settings.timeFormat);
|
708
|
+
|
709
|
+
if (rangeError) {
|
710
|
+
if (_setTimeValue(self, prettyTime, 'error')) {
|
711
|
+
self.trigger('timeRangeError');
|
712
|
+
}
|
713
|
+
} else {
|
714
|
+
_setTimeValue(self, prettyTime);
|
715
|
+
}
|
716
|
+
}
|
717
|
+
|
718
|
+
function _getTimeValue(self)
|
719
|
+
{
|
720
|
+
if (self.is('input')) {
|
721
|
+
return self.val();
|
722
|
+
} else {
|
723
|
+
// use the element's data attributes to store values
|
724
|
+
return self.data('ui-timepicker-value');
|
725
|
+
}
|
726
|
+
}
|
727
|
+
|
728
|
+
function _setTimeValue(self, value, source)
|
729
|
+
{
|
730
|
+
if (self.is('input')) {
|
731
|
+
self.val(value);
|
732
|
+
|
733
|
+
var settings = self.data('timepicker-settings');
|
734
|
+
if (settings.useSelect) {
|
735
|
+
self.data('timepicker-list').val(_roundAndFormatTime(value, settings));
|
736
|
+
}
|
737
|
+
}
|
738
|
+
|
739
|
+
if (self.data('ui-timepicker-value') != value) {
|
740
|
+
self.data('ui-timepicker-value', value);
|
741
|
+
if (source == 'select') {
|
742
|
+
self.trigger('selectTime').trigger('changeTime').trigger('change');
|
743
|
+
} else if (source != 'error') {
|
744
|
+
self.trigger('changeTime');
|
745
|
+
}
|
746
|
+
|
747
|
+
return true;
|
748
|
+
} else {
|
749
|
+
self.trigger('selectTime');
|
750
|
+
return false;
|
751
|
+
}
|
752
|
+
}
|
753
|
+
|
754
|
+
/*
|
755
|
+
* Keyboard navigation via arrow keys
|
756
|
+
*/
|
757
|
+
function _keydownhandler(e)
|
758
|
+
{
|
759
|
+
var self = $(this);
|
760
|
+
var list = self.data('timepicker-list');
|
761
|
+
|
762
|
+
if (!list || !list.is(':visible')) {
|
763
|
+
if (e.keyCode == 40) {
|
764
|
+
// show the list!
|
765
|
+
methods.show.call(self.get(0));
|
766
|
+
list = self.data('timepicker-list');
|
767
|
+
if (!_hideKeyboard(self)) {
|
768
|
+
self.focus();
|
769
|
+
}
|
770
|
+
} else {
|
771
|
+
return true;
|
772
|
+
}
|
773
|
+
}
|
774
|
+
|
775
|
+
switch (e.keyCode) {
|
776
|
+
|
777
|
+
case 13: // return
|
778
|
+
if (_selectValue(self)) {
|
779
|
+
methods.hide.apply(this);
|
780
|
+
}
|
781
|
+
|
782
|
+
e.preventDefault();
|
783
|
+
return false;
|
784
|
+
|
785
|
+
case 38: // up
|
786
|
+
var selected = list.find('.ui-timepicker-selected');
|
787
|
+
|
788
|
+
if (!selected.length) {
|
789
|
+
list.find('li').each(function(i, obj) {
|
790
|
+
if ($(obj).position().top > 0) {
|
791
|
+
selected = $(obj);
|
792
|
+
return false;
|
793
|
+
}
|
794
|
+
});
|
795
|
+
selected.addClass('ui-timepicker-selected');
|
796
|
+
|
797
|
+
} else if (!selected.is(':first-child')) {
|
798
|
+
selected.removeClass('ui-timepicker-selected');
|
799
|
+
selected.prev().addClass('ui-timepicker-selected');
|
800
|
+
|
801
|
+
if (selected.prev().position().top < selected.outerHeight()) {
|
802
|
+
list.scrollTop(list.scrollTop() - selected.outerHeight());
|
803
|
+
}
|
804
|
+
}
|
805
|
+
|
806
|
+
return false;
|
807
|
+
|
808
|
+
case 40: // down
|
809
|
+
selected = list.find('.ui-timepicker-selected');
|
810
|
+
|
811
|
+
if (selected.length === 0) {
|
812
|
+
list.find('li').each(function(i, obj) {
|
813
|
+
if ($(obj).position().top > 0) {
|
814
|
+
selected = $(obj);
|
815
|
+
return false;
|
816
|
+
}
|
817
|
+
});
|
818
|
+
|
819
|
+
selected.addClass('ui-timepicker-selected');
|
820
|
+
} else if (!selected.is(':last-child')) {
|
821
|
+
selected.removeClass('ui-timepicker-selected');
|
822
|
+
selected.next().addClass('ui-timepicker-selected');
|
823
|
+
|
824
|
+
if (selected.next().position().top + 2*selected.outerHeight() > list.outerHeight()) {
|
825
|
+
list.scrollTop(list.scrollTop() + selected.outerHeight());
|
826
|
+
}
|
827
|
+
}
|
828
|
+
|
829
|
+
return false;
|
830
|
+
|
831
|
+
case 27: // escape
|
832
|
+
list.find('li').removeClass('ui-timepicker-selected');
|
833
|
+
methods.hide();
|
834
|
+
break;
|
835
|
+
|
836
|
+
case 9: //tab
|
837
|
+
methods.hide();
|
838
|
+
break;
|
839
|
+
|
840
|
+
default:
|
841
|
+
return true;
|
842
|
+
}
|
843
|
+
}
|
844
|
+
|
845
|
+
/*
|
846
|
+
* Time typeahead
|
847
|
+
*/
|
848
|
+
function _keyuphandler(e)
|
849
|
+
{
|
850
|
+
var self = $(this);
|
851
|
+
var list = self.data('timepicker-list');
|
852
|
+
|
853
|
+
if (!list || !list.is(':visible')) {
|
854
|
+
return true;
|
855
|
+
}
|
856
|
+
|
857
|
+
if (!self.data('timepicker-settings').typeaheadHighlight) {
|
858
|
+
list.find('li').removeClass('ui-timepicker-selected');
|
859
|
+
return true;
|
860
|
+
}
|
861
|
+
|
862
|
+
switch (e.keyCode) {
|
863
|
+
|
864
|
+
case 96: // numpad numerals
|
865
|
+
case 97:
|
866
|
+
case 98:
|
867
|
+
case 99:
|
868
|
+
case 100:
|
869
|
+
case 101:
|
870
|
+
case 102:
|
871
|
+
case 103:
|
872
|
+
case 104:
|
873
|
+
case 105:
|
874
|
+
case 48: // numerals
|
875
|
+
case 49:
|
876
|
+
case 50:
|
877
|
+
case 51:
|
878
|
+
case 52:
|
879
|
+
case 53:
|
880
|
+
case 54:
|
881
|
+
case 55:
|
882
|
+
case 56:
|
883
|
+
case 57:
|
884
|
+
case 65: // a
|
885
|
+
case 77: // m
|
886
|
+
case 80: // p
|
887
|
+
case 186: // colon
|
888
|
+
case 8: // backspace
|
889
|
+
case 46: // delete
|
890
|
+
_setSelected(self, list);
|
891
|
+
break;
|
892
|
+
|
893
|
+
default:
|
894
|
+
// list.find('li').removeClass('ui-timepicker-selected');
|
895
|
+
return;
|
896
|
+
}
|
897
|
+
}
|
898
|
+
|
899
|
+
function _selectValue(self)
|
900
|
+
{
|
901
|
+
var settings = self.data('timepicker-settings');
|
902
|
+
var list = self.data('timepicker-list');
|
903
|
+
var timeValue = null;
|
904
|
+
|
905
|
+
var cursor = list.find('.ui-timepicker-selected');
|
906
|
+
|
907
|
+
if (cursor.hasClass('ui-timepicker-disabled')) {
|
908
|
+
return false;
|
909
|
+
}
|
910
|
+
|
911
|
+
if (cursor.length) {
|
912
|
+
// selected value found
|
913
|
+
timeValue = cursor.data('time');
|
914
|
+
}
|
915
|
+
|
916
|
+
if (timeValue !== null) {
|
917
|
+
if (typeof timeValue == 'string') {
|
918
|
+
self.val(timeValue);
|
919
|
+
} else {
|
920
|
+
var timeString = _int2time(timeValue, settings.timeFormat);
|
921
|
+
_setTimeValue(self, timeString, 'select');
|
922
|
+
}
|
923
|
+
}
|
924
|
+
|
925
|
+
//self.trigger('change').trigger('selectTime');
|
926
|
+
return true;
|
927
|
+
}
|
928
|
+
|
929
|
+
function _int2duration(seconds, step)
|
930
|
+
{
|
931
|
+
seconds = Math.abs(seconds);
|
932
|
+
var minutes = Math.round(seconds/60),
|
933
|
+
duration = [],
|
934
|
+
hours, mins;
|
935
|
+
|
936
|
+
if (minutes < 60) {
|
937
|
+
// Only show (x mins) under 1 hour
|
938
|
+
duration = [minutes, _lang.mins];
|
939
|
+
} else {
|
940
|
+
hours = Math.floor(minutes/60);
|
941
|
+
mins = minutes%60;
|
942
|
+
|
943
|
+
// Show decimal notation (eg: 1.5 hrs) for 30 minute steps
|
944
|
+
if (step == 30 && mins == 30) {
|
945
|
+
hours += _lang.decimal + 5;
|
946
|
+
}
|
947
|
+
|
948
|
+
duration.push(hours);
|
949
|
+
duration.push(hours == 1 ? _lang.hr : _lang.hrs);
|
950
|
+
|
951
|
+
// Show remainder minutes notation (eg: 1 hr 15 mins) for non-30 minute steps
|
952
|
+
// and only if there are remainder minutes to show
|
953
|
+
if (step != 30 && mins) {
|
954
|
+
duration.push(mins);
|
955
|
+
duration.push(_lang.mins);
|
956
|
+
}
|
957
|
+
}
|
958
|
+
|
959
|
+
return duration.join(' ');
|
960
|
+
}
|
961
|
+
|
962
|
+
function _int2time(seconds, format)
|
963
|
+
{
|
964
|
+
if (seconds === null) {
|
965
|
+
return;
|
966
|
+
}
|
967
|
+
|
968
|
+
var time = new Date(_baseDate.valueOf() + (seconds*1000));
|
969
|
+
|
970
|
+
if (isNaN(time.getTime())) {
|
971
|
+
return;
|
972
|
+
}
|
973
|
+
|
974
|
+
var output = '';
|
975
|
+
var hour, code;
|
976
|
+
for (var i=0; i<format.length; i++) {
|
977
|
+
|
978
|
+
code = format.charAt(i);
|
979
|
+
switch (code) {
|
980
|
+
|
981
|
+
case 'a':
|
982
|
+
output += (time.getHours() > 11) ? _lang.pm : _lang.am;
|
983
|
+
break;
|
984
|
+
|
985
|
+
case 'A':
|
986
|
+
output += (time.getHours() > 11) ? _lang.PM : _lang.AM;
|
987
|
+
break;
|
988
|
+
|
989
|
+
case 'g':
|
990
|
+
hour = time.getHours() % 12;
|
991
|
+
output += (hour === 0) ? '12' : hour;
|
992
|
+
break;
|
993
|
+
|
994
|
+
case 'G':
|
995
|
+
output += time.getHours();
|
996
|
+
break;
|
997
|
+
|
998
|
+
case 'h':
|
999
|
+
hour = time.getHours() % 12;
|
1000
|
+
|
1001
|
+
if (hour !== 0 && hour < 10) {
|
1002
|
+
hour = '0'+hour;
|
1003
|
+
}
|
1004
|
+
|
1005
|
+
output += (hour === 0) ? '12' : hour;
|
1006
|
+
break;
|
1007
|
+
|
1008
|
+
case 'H':
|
1009
|
+
hour = time.getHours();
|
1010
|
+
if (seconds === _ONE_DAY) hour = 24;
|
1011
|
+
output += (hour > 9) ? hour : '0'+hour;
|
1012
|
+
break;
|
1013
|
+
|
1014
|
+
case 'i':
|
1015
|
+
var minutes = time.getMinutes();
|
1016
|
+
output += (minutes > 9) ? minutes : '0'+minutes;
|
1017
|
+
break;
|
1018
|
+
|
1019
|
+
case 's':
|
1020
|
+
seconds = time.getSeconds();
|
1021
|
+
output += (seconds > 9) ? seconds : '0'+seconds;
|
1022
|
+
break;
|
1023
|
+
|
1024
|
+
case '\\':
|
1025
|
+
// escape character; add the next character and skip ahead
|
1026
|
+
i++;
|
1027
|
+
output += format.charAt(i);
|
1028
|
+
break;
|
1029
|
+
|
1030
|
+
default:
|
1031
|
+
output += code;
|
1032
|
+
}
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
return output;
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
function _time2int(timeString, settings)
|
1039
|
+
{
|
1040
|
+
if (timeString === '') return null;
|
1041
|
+
if (!timeString || timeString+0 == timeString) return timeString;
|
1042
|
+
|
1043
|
+
if (typeof(timeString) == 'object') {
|
1044
|
+
return timeString.getHours()*3600 + timeString.getMinutes()*60 + timeString.getSeconds();
|
1045
|
+
}
|
1046
|
+
|
1047
|
+
timeString = timeString.toLowerCase();
|
1048
|
+
|
1049
|
+
var d = new Date(0);
|
1050
|
+
var time;
|
1051
|
+
|
1052
|
+
// try to parse time input
|
1053
|
+
time = timeString.match(/^([0-2]?[0-9])\W?([0-5][0-9])?\W?([0-5][0-9])?\s*([pa]?)m?$/);
|
1054
|
+
|
1055
|
+
if (!time) {
|
1056
|
+
return null;
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
var hour = parseInt(time[1]*1, 10);
|
1060
|
+
var ampm = time[4];
|
1061
|
+
var hours = hour;
|
1062
|
+
|
1063
|
+
if (ampm) {
|
1064
|
+
if (hour == 12) {
|
1065
|
+
hours = (time[4] == 'p') ? 12 : 0;
|
1066
|
+
} else {
|
1067
|
+
hours = (hour + (time[4] == 'p' ? 12 : 0));
|
1068
|
+
}
|
1069
|
+
}
|
1070
|
+
|
1071
|
+
var minutes = ( time[2]*1 || 0 );
|
1072
|
+
var seconds = ( time[3]*1 || 0 );
|
1073
|
+
var timeInt = hours*3600 + minutes*60 + seconds;
|
1074
|
+
|
1075
|
+
// if no am/pm provided, intelligently guess based on the scrollDefault
|
1076
|
+
if (!ampm && settings && settings._twelveHourTime && settings.scrollDefault) {
|
1077
|
+
var delta = timeInt - settings.scrollDefault;
|
1078
|
+
if (delta < 0 && delta >= _ONE_DAY / -2) {
|
1079
|
+
timeInt = (timeInt + (_ONE_DAY / 2)) % _ONE_DAY;
|
1080
|
+
}
|
1081
|
+
}
|
1082
|
+
|
1083
|
+
return timeInt
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
function _pad2(n) {
|
1087
|
+
return ("0" + n).slice(-2);
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
// Plugin entry
|
1091
|
+
$.fn.timepicker = function(method)
|
1092
|
+
{
|
1093
|
+
if (!this.length) return this;
|
1094
|
+
if (methods[method]) {
|
1095
|
+
// check if this element is a timepicker
|
1096
|
+
if (!this.hasClass('ui-timepicker-input')) {
|
1097
|
+
return this;
|
1098
|
+
}
|
1099
|
+
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
1100
|
+
}
|
1101
|
+
else if(typeof method === "object" || !method) { return methods.init.apply(this, arguments); }
|
1102
|
+
else { $.error("Method "+ method + " does not exist on jQuery.timepicker"); }
|
1103
|
+
};
|
1104
|
+
// Global defaults
|
1105
|
+
$.fn.timepicker.defaults = {
|
1106
|
+
className: null,
|
1107
|
+
minTime: null,
|
1108
|
+
maxTime: null,
|
1109
|
+
durationTime: null,
|
1110
|
+
step: 30,
|
1111
|
+
showDuration: false,
|
1112
|
+
showOnFocus: true,
|
1113
|
+
timeFormat: 'g:ia',
|
1114
|
+
scrollDefault: null,
|
1115
|
+
selectOnBlur: false,
|
1116
|
+
disableTouchKeyboard: false,
|
1117
|
+
forceRoundTime: false,
|
1118
|
+
appendTo: 'body',
|
1119
|
+
orientation: 'ltr',
|
1120
|
+
disableTimeRanges: [],
|
1121
|
+
closeOnWindowScroll: false,
|
1122
|
+
typeaheadHighlight: true,
|
1123
|
+
noneOption: false
|
1124
|
+
};
|
1125
|
+
}));
|