jquery-timeentry-rails 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +4 -0
- data/Rakefile +2 -0
- data/jquery-timeentry-rails.gemspec +19 -0
- data/lib/jquery-timeentry-rails.rb +10 -0
- data/lib/jquery-timeentry-rails/version.rb +7 -0
- data/vendor/assets/images/spinnerBlue.png +0 -0
- data/vendor/assets/images/spinnerBlueBig.png +0 -0
- data/vendor/assets/images/spinnerDefault.png +0 -0
- data/vendor/assets/images/spinnerDefaultBig.png +0 -0
- data/vendor/assets/images/spinnerGem.png +0 -0
- data/vendor/assets/images/spinnerGemBig.png +0 -0
- data/vendor/assets/images/spinnerGreen.png +0 -0
- data/vendor/assets/images/spinnerGreenBig.png +0 -0
- data/vendor/assets/images/spinnerOrange.png +0 -0
- data/vendor/assets/images/spinnerOrangeBig.png +0 -0
- data/vendor/assets/images/spinnerSquare.png +0 -0
- data/vendor/assets/images/spinnerSquareBig.png +0 -0
- data/vendor/assets/images/spinnerText.png +0 -0
- data/vendor/assets/images/spinnerTextBig.png +0 -0
- data/vendor/assets/images/spinnerUpDown.png +0 -0
- data/vendor/assets/images/spinnerUpDownBig.png +0 -0
- data/vendor/assets/javascripts/jquery.timeentry-ar.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-ca.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-cs.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-de.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-es.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-fa.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-fr.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-hu.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-is.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-it.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-ja.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-lt.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-lv.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-nl.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-pl.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-pt.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-ro.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-ru.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-sk.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-sv.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-tr.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-vi.js +10 -0
- data/vendor/assets/javascripts/jquery.timeentry-zh-CN.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry-zh-TW.js +9 -0
- data/vendor/assets/javascripts/jquery.timeentry.js.erb +931 -0
- data/vendor/assets/stylesheets/jquery.timeentry.css +5 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 267d86f1272e280a7dc37d0c643292dcac18d2e8
|
4
|
+
data.tar.gz: 22fcbc127fa33fbc342575df377e5386898e3edb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 28e605acb6dc8d46eb027604b87a48fd469932886520f6b7ab896b23ea59733fbd5105892eb7def2d8a754191b25976f53a9a13ad00b9fc77592ab7aab208967
|
7
|
+
data.tar.gz: eebb9acf574a4febcafd7d6092abd9f9bed91c54918788231e90766ac3b701a972ebb384ab3500c390bed7793c3f9d26f428f4204e336a3d0cb546b8a2144006
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/jquery-timeentry-rails/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Frédéric Rodrigo"]
|
6
|
+
gem.email = ["fred.rodrigo@gmail.com"]
|
7
|
+
gem.description = %q{A jQuery plugin that sets an input field up to pick a time value using a spinner.}
|
8
|
+
gem.summary = %q{A jQuery plugin that sets an input field up to pick a time value using a spinner.}
|
9
|
+
gem.homepage = "http://keith-wood.name/timeEntry.html"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "jquery-timeentry-rails"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Jquery::Timeentry::Rails::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'railties', '>= 3.1.0'
|
19
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Arabic initialize for the jQuery time entry extension
|
3
|
+
Written by Mohammad Baydoun (mab@modbay.me). */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['ar'] = {show24Hours: false, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['ص', 'م'],
|
7
|
+
spinnerTexts: ['الأن', 'الحقل السابق', 'الحقل التالي', 'زيادة', 'تنقيص']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['ar']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Catalan initialisation for the jQuery time entry extension
|
3
|
+
Written by Gabriel Guzman (gabriel@josoft.com.ar). */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['ca'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Ara', 'Camp anterior', 'Següent camp', 'Augmentar', 'Disminuir']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['ca']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Czech initialisation for the jQuery time entry extension
|
3
|
+
Written by Stanislav Kurinec (stenly.kurinec@gmail.com) */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['cs'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['Dop', 'Odp'],
|
7
|
+
spinnerTexts: ['Nyní', 'Předchozí pole', 'Následující pole', 'Zvýšit', 'Snížit']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['cs']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
German initialisation for the jQuery time entry extension
|
3
|
+
Written by Eyk Schulz (eyk.schulz@gmx.net) */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['de'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Jetzt', 'vorheriges Feld', 'nächstes Feld', 'hoch', 'runter']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['de']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Spanish initialisation for the jQuery time entry extension
|
3
|
+
Written by diegok (diego@freekeylabs.com). */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['es'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Ahora', 'Campo anterior', 'Siguiente campo', 'Aumentar', 'Disminuir']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['es']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Persian initialisation for the jQuery time entry extension
|
3
|
+
translation by benyblack */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['fa'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['ق.ظ', 'ب.ظ'],
|
7
|
+
spinnerTexts: ['اکنون', 'قبلی', 'بعدی', 'افزایش', 'کاهش']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['fa']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
French initialisation for the jQuery time entry extension
|
3
|
+
Written by Keith Wood (kbwood@iprimus.com.au) June 2007. */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['fr'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Maintenant', 'Précédent', 'Suivant', 'Augmenter', 'Diminuer']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['fr']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Hungarian initialisation for the jQuery time entry extension
|
3
|
+
Written by Karaszi Istvan (raszi@spam.raszi.hu) */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['hu'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['DE', 'DU'],
|
7
|
+
spinnerTexts: ['Most', 'Előző mező', 'Következő mező', 'Növel', 'Csökkent']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['hu']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Icelandic initialisation for the jQuery time entry extension
|
3
|
+
Written by Már Örlygsson (http://mar.anomy.net/) */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['is'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['fh', 'eh'],
|
7
|
+
spinnerTexts: ['Núna', 'Fyrra svæði', 'Næsta svæði', 'Hækka', 'Lækka']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['is']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Italian initialisation for the jQuery time entry extension
|
3
|
+
Written by Apaella (apaella@gmail.com) June 2007. */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['it'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Adesso', 'Precedente', 'Successivo', 'Aumenta', 'Diminuisci']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['it']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Japanese initialisation for the jQuery time entry extension
|
3
|
+
Written by Yuuki Takahashi (yuuki@fb69.jp) */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['ja'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['現在時刻', '前へ', '次へ', '増やす', '減らす']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['ja']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Lithuanian initialisation for the jQuery time entry extension
|
3
|
+
Written by Andrej Andrejev */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['lt'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Dabar', 'Ankstesnis laukas', 'Kitas laukas', 'Daugiau', 'Mažiau']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['lt']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Latvian (UTF-8) initialisation for the jQuery $.timeEntry extension.
|
3
|
+
Written by Rihards Prieditis (rprieditis@gmail.com). */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['lv'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Pašlaik', 'Iepriekšējais lauks', 'Nākamais lauks', 'Palielināt', 'Samazināt']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['lv']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Dutch initialisation written for the jQuery time entry extension.
|
3
|
+
Glenn plas (glenn.plas@telenet.be) March 2008. */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['nl'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Nu', 'Vorig veld', 'Volgend veld','Verhoog', 'Verlaag']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['nl']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Polish initialisation for the jQuery time entry extension.
|
3
|
+
Polish translation by Jacek Wysocki (jacek.wysocki@gmail.com). */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['pl'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Teraz', 'Poprzednie pole', 'Następne pole', 'Zwiększ wartość', 'Zmniejsz wartość']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['pl']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Portuguese initialisation for the jQuery time entry extension
|
3
|
+
Written by Dino Sane (dino@asttra.com.br). */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['pt'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Agora', 'Campo anterior', 'Campo Seguinte', 'Aumentar', 'Diminuir']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['pt']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Romanian initialisation for the jQuery time entry extension
|
3
|
+
Written by Edmond L. (ll_edmond@walla.com) */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['ro'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Acum', 'Campul Anterior', 'Campul Urmator', 'Mareste', 'Micsoreaza']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['ro']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Russian (UTF-8) initialisation for the jQuery $.timeEntry extension.
|
3
|
+
Written by Andrew Stromnov (stromnov@gmail.com). */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['ru'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Сейчас', 'Предыдущее поле', 'Следующее поле', 'Больше', 'Меньше']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['ru']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Slovak initialisation for the jQuery time entry extension
|
3
|
+
Written by Vojtech Rinik (vojto@hmm.sk) */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['sk'] = {show24Hours: false, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Teraz', 'Predchádzajúce pole', 'Nasledujúce pole', 'Zvýšiť', 'Znížiť']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['sk']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Swedish initialisation for the jQuery time entry extension.
|
3
|
+
Written by Anders Ekdahl ( anders@nomadiz.se). */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['sv'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Nu', 'Förra fältet', 'Nästa fält', 'öka', 'minska']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['sv']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Turkish initialisation for the jQuery time entry extension
|
3
|
+
Written by Vural Dinçer */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['tr'] = {show24Hours: true, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['şu an', 'önceki alan', 'sonraki alan', 'arttır', 'azalt']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['tr']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Vietnamese template for the jQuery time entry extension
|
3
|
+
Written by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['vi'] = {show24Hours: false, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['Hiện tại', 'Mục trước', 'Mục sau', 'Tăng', 'Giảm']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['vi']);
|
9
|
+
})(jQuery);
|
10
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Simplified Chinese initialisation for the jQuery time entry extension.
|
3
|
+
By Cloudream(cloudream@gmail.com) */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['zh-CN'] = {show24Hours: false, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['当前', '左移', '右移', '加一', '减一']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['zh-CN']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Traditional Chinese initialisation for the jQuery time entry extension.
|
3
|
+
By Taian Su(taiansu@gmail.com) */
|
4
|
+
(function($) {
|
5
|
+
$.timeEntry.regional['zh-TW'] = {show24Hours: false, separator: ':',
|
6
|
+
ampmPrefix: '', ampmNames: ['AM', 'PM'],
|
7
|
+
spinnerTexts: ['現在時刻', '上一個欄位', '下一個欄位', '增加', '减少']};
|
8
|
+
$.timeEntry.setDefaults($.timeEntry.regional['zh-TW']);
|
9
|
+
})(jQuery);
|
@@ -0,0 +1,931 @@
|
|
1
|
+
/* http://keith-wood.name/timeEntry.html
|
2
|
+
Time entry for jQuery v1.5.2.
|
3
|
+
Written by Keith Wood (kbwood{at}iinet.com.au) June 2007.
|
4
|
+
Available under the MIT (https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt) license.
|
5
|
+
Please attribute the author if you use it. */
|
6
|
+
|
7
|
+
/* Turn an input field into an entry point for a time value.
|
8
|
+
The time can be entered via directly typing the value,
|
9
|
+
via the arrow keys, or via spinner buttons.
|
10
|
+
It is configurable to show 12 or 24-hour time, to show or hide seconds,
|
11
|
+
to enforce a minimum and/or maximum time, to change the spinner image,
|
12
|
+
and to constrain the time to steps, e.g. only on the quarter hours.
|
13
|
+
Attach it with $('input selector').timeEntry(); for default settings,
|
14
|
+
or configure it with options like:
|
15
|
+
$('input selector').timeEntry(
|
16
|
+
{spinnerImage: 'spinnerSquare.png', spinnerSize: [20, 20, 0]}); */
|
17
|
+
|
18
|
+
(function($) { // Hide scope, no $ conflict
|
19
|
+
|
20
|
+
/* TimeEntry manager.
|
21
|
+
Use the singleton instance of this class, $.timeEntry, to interact with the time entry
|
22
|
+
functionality. Settings for (groups of) fields are maintained in an instance object,
|
23
|
+
allowing multiple different settings on the same page. */
|
24
|
+
function TimeEntry() {
|
25
|
+
this._disabledInputs = []; // List of time entry inputs that have been disabled
|
26
|
+
this.regional = []; // Available regional settings, indexed by language code
|
27
|
+
this.regional[''] = { // Default regional settings
|
28
|
+
show24Hours: false, // True to use 24 hour time, false for 12 hour (AM/PM)
|
29
|
+
separator: ':', // The separator between time fields
|
30
|
+
ampmPrefix: '', // The separator before the AM/PM text
|
31
|
+
ampmNames: ['AM', 'PM'], // Names of morning/evening markers
|
32
|
+
spinnerTexts: ['Now', 'Previous field', 'Next field', 'Increment', 'Decrement']
|
33
|
+
// The popup texts for the spinner image areas
|
34
|
+
};
|
35
|
+
this._defaults = {
|
36
|
+
appendText: '', // Display text following the input box, e.g. showing the format
|
37
|
+
showSeconds: false, // True to show seconds as well, false for hours/minutes only
|
38
|
+
timeSteps: [1, 1, 1], // Steps for each of hours/minutes/seconds when incrementing/decrementing
|
39
|
+
initialField: 0, // The field to highlight initially, 0 = hours, 1 = minutes, ...
|
40
|
+
noSeparatorEntry: false, // True to move to next sub-field after two digits entry
|
41
|
+
useMouseWheel: true, // True to use mouse wheel for increment/decrement if possible,
|
42
|
+
// false to never use it
|
43
|
+
defaultTime: null, // The time to use if none has been set, leave at null for now
|
44
|
+
minTime: null, // The earliest selectable time, or null for no limit
|
45
|
+
maxTime: null, // The latest selectable time, or null for no limit
|
46
|
+
spinnerImage: '<%= asset_path 'spinnerDefault.png' %>', // The URL of the images to use for the time spinner
|
47
|
+
// Seven images packed horizontally for normal, each button pressed, and disabled
|
48
|
+
spinnerSize: [20, 20, 8], // The width and height of the spinner image,
|
49
|
+
// and size of centre button for current time
|
50
|
+
spinnerBigImage: '', // The URL of the images to use for the expanded time spinner
|
51
|
+
// Seven images packed horizontally for normal, each button pressed, and disabled
|
52
|
+
spinnerBigSize: [40, 40, 16], // The width and height of the expanded spinner image,
|
53
|
+
// and size of centre button for current time
|
54
|
+
spinnerIncDecOnly: false, // True for increment/decrement buttons only, false for all
|
55
|
+
spinnerRepeat: [500, 250], // Initial and subsequent waits in milliseconds
|
56
|
+
// for repeats on the spinner buttons
|
57
|
+
beforeShow: null, // Function that takes an input field and
|
58
|
+
// returns a set of custom settings for the time entry
|
59
|
+
beforeSetTime: null // Function that runs before updating the time,
|
60
|
+
// takes the old and new times, and minimum and maximum times as parameters,
|
61
|
+
// and returns an adjusted time if necessary
|
62
|
+
};
|
63
|
+
$.extend(this._defaults, this.regional['']);
|
64
|
+
}
|
65
|
+
|
66
|
+
$.extend(TimeEntry.prototype, {
|
67
|
+
/* Class name added to elements to indicate already configured with time entry. */
|
68
|
+
markerClassName: 'hasTimeEntry',
|
69
|
+
/* Name of the data property for instance settings. */
|
70
|
+
propertyName: 'timeEntry',
|
71
|
+
|
72
|
+
/* Class name for the appended content. */
|
73
|
+
_appendClass: 'timeEntry_append',
|
74
|
+
/* Class name for the time entry control. */
|
75
|
+
_controlClass: 'timeEntry_control',
|
76
|
+
/* Class name for the expanded spinner. */
|
77
|
+
_expandClass: 'timeEntry_expand',
|
78
|
+
|
79
|
+
/* Override the default settings for all instances of the time entry.
|
80
|
+
@param options (object) the new settings to use as defaults (anonymous object)
|
81
|
+
@return (DateEntry) this object */
|
82
|
+
setDefaults: function(options) {
|
83
|
+
$.extend(this._defaults, options || {});
|
84
|
+
return this;
|
85
|
+
},
|
86
|
+
|
87
|
+
/* Attach the time entry handler to an input field.
|
88
|
+
@param target (element) the field to attach to
|
89
|
+
@param options (object) custom settings for this instance */
|
90
|
+
_attachPlugin: function(target, options) {
|
91
|
+
var input = $(target);
|
92
|
+
if (input.hasClass(this.markerClassName)) {
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
var inst = {options: $.extend({}, this._defaults, options), input: input, _field: 0,
|
96
|
+
_selectedHour: 0, _selectedMinute: 0, _selectedSecond: 0};
|
97
|
+
input.data(this.propertyName, inst).addClass(this.markerClassName).
|
98
|
+
bind('focus.' + this.propertyName, this._doFocus).
|
99
|
+
bind('blur.' + this.propertyName, this._doBlur).
|
100
|
+
bind('click.' + this.propertyName, this._doClick).
|
101
|
+
bind('keydown.' + this.propertyName, this._doKeyDown).
|
102
|
+
bind('keypress.' + this.propertyName, this._doKeyPress).
|
103
|
+
bind('paste.' + this.propertyName, function(event) { // Check pastes
|
104
|
+
setTimeout(function() { plugin._parseTime(inst); }, 1);
|
105
|
+
});
|
106
|
+
this._optionPlugin(target, options);
|
107
|
+
},
|
108
|
+
|
109
|
+
/* Retrieve or reconfigure the settings for a time entry control.
|
110
|
+
@param target (element) the control to affect
|
111
|
+
@param options (object) the new options for this instance or
|
112
|
+
(string) an individual property name
|
113
|
+
@param value (any) the individual property value (omit if options
|
114
|
+
is an object or to retrieve the value of a setting)
|
115
|
+
@return (any) if retrieving a value */
|
116
|
+
_optionPlugin: function(target, options, value) {
|
117
|
+
target = $(target);
|
118
|
+
var inst = target.data(this.propertyName);
|
119
|
+
if (!options || (typeof options == 'string' && value == null)) { // Get option
|
120
|
+
var name = options;
|
121
|
+
options = (inst || {}).options;
|
122
|
+
return (options && name ? options[name] : options);
|
123
|
+
}
|
124
|
+
|
125
|
+
if (!target.hasClass(this.markerClassName)) {
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
options = options || {};
|
129
|
+
if (typeof options == 'string') {
|
130
|
+
var name = options;
|
131
|
+
options = {};
|
132
|
+
options[name] = value;
|
133
|
+
}
|
134
|
+
var currentTime = this._extractTime(inst);
|
135
|
+
$.extend(inst.options, options);
|
136
|
+
inst._field = 0;
|
137
|
+
if (currentTime) {
|
138
|
+
this._setTime(inst, new Date(0, 0, 0, currentTime[0], currentTime[1], currentTime[2]));
|
139
|
+
}
|
140
|
+
// Remove stuff dependent on old settings
|
141
|
+
target.next('span.' + this._appendClass).remove();
|
142
|
+
target.parent().find('span.' + this._controlClass).remove();
|
143
|
+
if ($.fn.mousewheel) {
|
144
|
+
target.unmousewheel();
|
145
|
+
}
|
146
|
+
// And re-add if requested
|
147
|
+
var spinner = (!inst.options.spinnerImage ? null :
|
148
|
+
$('<span class="' + this._controlClass + '" style="display: inline-block; ' +
|
149
|
+
'background: url(\'' + inst.options.spinnerImage + '\') 0 0 no-repeat; width: ' +
|
150
|
+
inst.options.spinnerSize[0] + 'px; height: ' + inst.options.spinnerSize[1] + 'px;"></span>'));
|
151
|
+
target.after(inst.options.appendText ? '<span class="' + this._appendClass + '">' +
|
152
|
+
inst.options.appendText + '</span>' : '').after(spinner || '');
|
153
|
+
// Allow mouse wheel usage
|
154
|
+
if (inst.options.useMouseWheel && $.fn.mousewheel) {
|
155
|
+
target.mousewheel(this._doMouseWheel);
|
156
|
+
}
|
157
|
+
if (spinner) {
|
158
|
+
spinner.mousedown(this._handleSpinner).mouseup(this._endSpinner).
|
159
|
+
mouseover(this._expandSpinner).mouseout(this._endSpinner).
|
160
|
+
mousemove(this._describeSpinner);
|
161
|
+
}
|
162
|
+
},
|
163
|
+
|
164
|
+
/* Enable a time entry input and any associated spinner.
|
165
|
+
@param target (element) single input field */
|
166
|
+
_enablePlugin: function(target) {
|
167
|
+
this._enableDisable(target, false);
|
168
|
+
},
|
169
|
+
|
170
|
+
/* Disable a time entry input and any associated spinner.
|
171
|
+
@param target (element) single input field */
|
172
|
+
_disablePlugin: function(target) {
|
173
|
+
this._enableDisable(target, true);
|
174
|
+
},
|
175
|
+
|
176
|
+
/* Enable or disable a time entry input and any associated spinner.
|
177
|
+
@param target (element) single input field
|
178
|
+
@param disable (boolean) true to disable, false to enable */
|
179
|
+
_enableDisable: function(target, disable) {
|
180
|
+
var inst = $.data(target, this.propertyName);
|
181
|
+
if (!inst) {
|
182
|
+
return;
|
183
|
+
}
|
184
|
+
target.disabled = disable;
|
185
|
+
if (target.nextSibling && target.nextSibling.nodeName.toLowerCase() == 'span') {
|
186
|
+
plugin._changeSpinner(inst, target.nextSibling, (disable ? 5 : -1));
|
187
|
+
}
|
188
|
+
plugin._disabledInputs = $.map(plugin._disabledInputs,
|
189
|
+
function(value) { return (value == target ? null : value); }); // Delete entry
|
190
|
+
if (disable) {
|
191
|
+
plugin._disabledInputs.push(target);
|
192
|
+
}
|
193
|
+
},
|
194
|
+
|
195
|
+
/* Check whether an input field has been disabled.
|
196
|
+
@param target (element) input field to check
|
197
|
+
@return (boolean) true if this field has been disabled, false if it is enabled */
|
198
|
+
_isDisabledPlugin: function(target) {
|
199
|
+
return $.inArray(target, this._disabledInputs) > -1;
|
200
|
+
},
|
201
|
+
|
202
|
+
/* Remove the time entry functionality from an input.
|
203
|
+
@param target (element) the control to affect */
|
204
|
+
_destroyPlugin: function(target) {
|
205
|
+
target = $(target);
|
206
|
+
if (!target.hasClass(this.markerClassName)) {
|
207
|
+
return;
|
208
|
+
}
|
209
|
+
target.removeClass(this.markerClassName).removeData(this.propertyName).
|
210
|
+
unbind('.' + this.propertyName);
|
211
|
+
if ($.fn.mousewheel) {
|
212
|
+
target.unmousewheel();
|
213
|
+
}
|
214
|
+
this._disabledInputs = $.map(this._disabledInputs,
|
215
|
+
function(value) { return (value == target[0] ? null : value); }); // Delete entry
|
216
|
+
target.siblings('.' + this._appendClass + ',.' + this._controlClass).remove();
|
217
|
+
},
|
218
|
+
|
219
|
+
/* Initialise the current time for a time entry input field.
|
220
|
+
@param target (element) input field to update
|
221
|
+
@param time (Date) the new time (year/month/day ignored) or null for now */
|
222
|
+
_setTimePlugin: function(target, time) {
|
223
|
+
var inst = $.data(target, this.propertyName);
|
224
|
+
if (inst) {
|
225
|
+
if (time === null || time === '') {
|
226
|
+
inst.input.val('');
|
227
|
+
}
|
228
|
+
else {
|
229
|
+
this._setTime(inst, time ? (typeof time == 'object' ?
|
230
|
+
new Date(time.getTime()) : time) : null);
|
231
|
+
}
|
232
|
+
}
|
233
|
+
},
|
234
|
+
|
235
|
+
/* Retrieve the current time for a time entry input field.
|
236
|
+
@param target (element) input field to examine
|
237
|
+
@return (Date) current time (year/month/day zero) or null if none */
|
238
|
+
_getTimePlugin: function(target) {
|
239
|
+
var inst = $.data(target, this.propertyName);
|
240
|
+
var currentTime = (inst ? this._extractTime(inst) : null);
|
241
|
+
return (!currentTime ? null :
|
242
|
+
new Date(0, 0, 0, currentTime[0], currentTime[1], currentTime[2]));
|
243
|
+
},
|
244
|
+
|
245
|
+
/* Retrieve the millisecond offset for the current time.
|
246
|
+
@param target (element) input field to examine
|
247
|
+
@return (number) the time as milliseconds offset or zero if none */
|
248
|
+
_getOffsetPlugin: function(target) {
|
249
|
+
var inst = $.data(target, this.propertyName);
|
250
|
+
var currentTime = (inst ? this._extractTime(inst) : null);
|
251
|
+
return (!currentTime ? 0 :
|
252
|
+
(currentTime[0] * 3600 + currentTime[1] * 60 + currentTime[2]) * 1000);
|
253
|
+
},
|
254
|
+
|
255
|
+
/* Initialise time entry.
|
256
|
+
@param target (element) the input field or
|
257
|
+
(event) the focus event */
|
258
|
+
_doFocus: function(target) {
|
259
|
+
var input = (target.nodeName && target.nodeName.toLowerCase() == 'input' ? target : this);
|
260
|
+
if (plugin._lastInput == input || plugin._isDisabledPlugin(input)) {
|
261
|
+
plugin._focussed = false;
|
262
|
+
return;
|
263
|
+
}
|
264
|
+
var inst = $.data(input, plugin.propertyName);
|
265
|
+
plugin._focussed = true;
|
266
|
+
plugin._lastInput = input;
|
267
|
+
plugin._blurredInput = null;
|
268
|
+
$.extend(inst.options, ($.isFunction(inst.options.beforeShow) ?
|
269
|
+
inst.options.beforeShow.apply(input, [input]) : {}));
|
270
|
+
plugin._parseTime(inst);
|
271
|
+
setTimeout(function() { plugin._showField(inst); }, 10);
|
272
|
+
},
|
273
|
+
|
274
|
+
/* Note that the field has been exited.
|
275
|
+
@param event (event) the blur event */
|
276
|
+
_doBlur: function(event) {
|
277
|
+
plugin._blurredInput = plugin._lastInput;
|
278
|
+
plugin._lastInput = null;
|
279
|
+
},
|
280
|
+
|
281
|
+
/* Select appropriate field portion on click, if already in the field.
|
282
|
+
@param event (event) the click event */
|
283
|
+
_doClick: function(event) {
|
284
|
+
var input = event.target;
|
285
|
+
var inst = $.data(input, plugin.propertyName);
|
286
|
+
var prevField = inst._field;
|
287
|
+
if (!plugin._focussed) {
|
288
|
+
var fieldSize = inst.options.separator.length + 2;
|
289
|
+
inst._field = 0;
|
290
|
+
if (input.selectionStart != null) { // Use input select range
|
291
|
+
for (var field = 0; field <= Math.max(1, inst._secondField, inst._ampmField); field++) {
|
292
|
+
var end = (field != inst._ampmField ? (field * fieldSize) + 2 :
|
293
|
+
(inst._ampmField * fieldSize) + inst.options.ampmPrefix.length +
|
294
|
+
inst.options.ampmNames[0].length);
|
295
|
+
inst._field = field;
|
296
|
+
if (input.selectionStart < end) {
|
297
|
+
break;
|
298
|
+
}
|
299
|
+
}
|
300
|
+
}
|
301
|
+
else if (input.createTextRange) { // Check against bounding boxes
|
302
|
+
var src = $(event.srcElement);
|
303
|
+
var range = input.createTextRange();
|
304
|
+
var convert = function(value) {
|
305
|
+
return {thin: 2, medium: 4, thick: 6}[value] || value;
|
306
|
+
};
|
307
|
+
var offsetX = event.clientX + document.documentElement.scrollLeft -
|
308
|
+
(src.offset().left + parseInt(convert(src.css('border-left-width')), 10)) -
|
309
|
+
range.offsetLeft; // Position - left edge - alignment
|
310
|
+
for (var field = 0; field <= Math.max(1, inst._secondField, inst._ampmField); field++) {
|
311
|
+
var end = (field != inst._ampmField ? (field * fieldSize) + 2 :
|
312
|
+
(inst._ampmField * fieldSize) + inst.options.ampmPrefix.length +
|
313
|
+
inst.options.ampmNames[0].length);
|
314
|
+
range.collapse();
|
315
|
+
range.moveEnd('character', end);
|
316
|
+
inst._field = field;
|
317
|
+
if (offsetX < range.boundingWidth) { // And compare
|
318
|
+
break;
|
319
|
+
}
|
320
|
+
}
|
321
|
+
}
|
322
|
+
}
|
323
|
+
if (prevField != inst._field) {
|
324
|
+
inst._lastChr = '';
|
325
|
+
}
|
326
|
+
plugin._showField(inst);
|
327
|
+
plugin._focussed = false;
|
328
|
+
},
|
329
|
+
|
330
|
+
/* Handle keystrokes in the field.
|
331
|
+
@param event (event) the keydown event
|
332
|
+
@return (boolean) true to continue, false to stop processing */
|
333
|
+
_doKeyDown: function(event) {
|
334
|
+
if (event.keyCode >= 48) { // >= '0'
|
335
|
+
return true;
|
336
|
+
}
|
337
|
+
var inst = $.data(event.target, plugin.propertyName);
|
338
|
+
switch (event.keyCode) {
|
339
|
+
case 9: return (event.shiftKey ?
|
340
|
+
// Move to previous time field, or out if at the beginning
|
341
|
+
plugin._changeField(inst, -1, true) :
|
342
|
+
// Move to next time field, or out if at the end
|
343
|
+
plugin._changeField(inst, +1, true));
|
344
|
+
case 35: if (event.ctrlKey) { // Clear time on ctrl+end
|
345
|
+
plugin._setValue(inst, '');
|
346
|
+
}
|
347
|
+
else { // Last field on end
|
348
|
+
inst._field = Math.max(1, inst._secondField, inst._ampmField);
|
349
|
+
plugin._adjustField(inst, 0);
|
350
|
+
}
|
351
|
+
break;
|
352
|
+
case 36: if (event.ctrlKey) { // Current time on ctrl+home
|
353
|
+
plugin._setTime(inst);
|
354
|
+
}
|
355
|
+
else { // First field on home
|
356
|
+
inst._field = 0;
|
357
|
+
plugin._adjustField(inst, 0);
|
358
|
+
}
|
359
|
+
break;
|
360
|
+
case 37: plugin._changeField(inst, -1, false); break; // Previous field on left
|
361
|
+
case 38: plugin._adjustField(inst, +1); break; // Increment time field on up
|
362
|
+
case 39: plugin._changeField(inst, +1, false); break; // Next field on right
|
363
|
+
case 40: plugin._adjustField(inst, -1); break; // Decrement time field on down
|
364
|
+
case 46: plugin._setValue(inst, ''); break; // Clear time on delete
|
365
|
+
default: return true;
|
366
|
+
}
|
367
|
+
return false;
|
368
|
+
},
|
369
|
+
|
370
|
+
/* Disallow unwanted characters.
|
371
|
+
@param event (event) the keypress event
|
372
|
+
@return (boolean) true to continue, false to stop processing */
|
373
|
+
_doKeyPress: function(event) {
|
374
|
+
var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
|
375
|
+
if (chr < ' ') {
|
376
|
+
return true;
|
377
|
+
}
|
378
|
+
var inst = $.data(event.target, plugin.propertyName);
|
379
|
+
plugin._handleKeyPress(inst, chr);
|
380
|
+
return false;
|
381
|
+
},
|
382
|
+
|
383
|
+
/* Increment/decrement on mouse wheel activity.
|
384
|
+
@param event (event) the mouse wheel event
|
385
|
+
@param delta (number) the amount of change */
|
386
|
+
_doMouseWheel: function(event, delta) {
|
387
|
+
if (plugin._isDisabledPlugin(event.target)) {
|
388
|
+
return;
|
389
|
+
}
|
390
|
+
var inst = $.data(event.target, plugin.propertyName);
|
391
|
+
inst.input.focus();
|
392
|
+
if (!inst.input.val()) {
|
393
|
+
plugin._parseTime(inst);
|
394
|
+
}
|
395
|
+
plugin._adjustField(inst, delta);
|
396
|
+
event.preventDefault();
|
397
|
+
},
|
398
|
+
|
399
|
+
/* Expand the spinner, if possible, to make it easier to use.
|
400
|
+
@param event (event) the mouse over event */
|
401
|
+
_expandSpinner: function(event) {
|
402
|
+
var spinner = plugin._getSpinnerTarget(event);
|
403
|
+
var inst = $.data(plugin._getInput(spinner), plugin.propertyName);
|
404
|
+
if (plugin._isDisabledPlugin(inst.input[0])) {
|
405
|
+
return;
|
406
|
+
}
|
407
|
+
if (inst.options.spinnerBigImage) {
|
408
|
+
inst._expanded = true;
|
409
|
+
var offset = $(spinner).offset();
|
410
|
+
var relative = null;
|
411
|
+
$(spinner).parents().each(function() {
|
412
|
+
var parent = $(this);
|
413
|
+
if (parent.css('position') == 'relative' ||
|
414
|
+
parent.css('position') == 'absolute') {
|
415
|
+
relative = parent.offset();
|
416
|
+
}
|
417
|
+
return !relative;
|
418
|
+
});
|
419
|
+
$('<div class="' + plugin._expandClass + '" style="position: absolute; left: ' +
|
420
|
+
(offset.left - (inst.options.spinnerBigSize[0] - inst.options.spinnerSize[0]) / 2 -
|
421
|
+
(relative ? relative.left : 0)) + 'px; top: ' +
|
422
|
+
(offset.top - (inst.options.spinnerBigSize[1] - inst.options.spinnerSize[1]) / 2 -
|
423
|
+
(relative ? relative.top : 0)) + 'px; width: ' +
|
424
|
+
inst.options.spinnerBigSize[0] + 'px; height: ' +
|
425
|
+
inst.options.spinnerBigSize[1] + 'px; background: transparent url(' +
|
426
|
+
inst.options.spinnerBigImage + ') no-repeat 0px 0px; z-index: 10;"></div>').
|
427
|
+
mousedown(plugin._handleSpinner).mouseup(plugin._endSpinner).
|
428
|
+
mouseout(plugin._endExpand).mousemove(plugin._describeSpinner).
|
429
|
+
insertAfter(spinner);
|
430
|
+
}
|
431
|
+
},
|
432
|
+
|
433
|
+
/* Locate the actual input field from the spinner.
|
434
|
+
@param spinner (element) the current spinner
|
435
|
+
@return (element) the corresponding input */
|
436
|
+
_getInput: function(spinner) {
|
437
|
+
return $(spinner).siblings('.' + plugin.markerClassName)[0];
|
438
|
+
},
|
439
|
+
|
440
|
+
/* Change the title based on position within the spinner.
|
441
|
+
@param event (event) the mouse move event */
|
442
|
+
_describeSpinner: function(event) {
|
443
|
+
var spinner = plugin._getSpinnerTarget(event);
|
444
|
+
var inst = $.data(plugin._getInput(spinner), plugin.propertyName);
|
445
|
+
spinner.title = inst.options.spinnerTexts[plugin._getSpinnerRegion(inst, event)];
|
446
|
+
},
|
447
|
+
|
448
|
+
/* Handle a click on the spinner.
|
449
|
+
@param event (event) the mouse click event */
|
450
|
+
_handleSpinner: function(event) {
|
451
|
+
var spinner = plugin._getSpinnerTarget(event);
|
452
|
+
var input = plugin._getInput(spinner);
|
453
|
+
if (plugin._isDisabledPlugin(input)) {
|
454
|
+
return;
|
455
|
+
}
|
456
|
+
if (input == plugin._blurredInput) {
|
457
|
+
plugin._lastInput = input;
|
458
|
+
plugin._blurredInput = null;
|
459
|
+
}
|
460
|
+
var inst = $.data(input, plugin.propertyName);
|
461
|
+
plugin._doFocus(input);
|
462
|
+
var region = plugin._getSpinnerRegion(inst, event);
|
463
|
+
plugin._changeSpinner(inst, spinner, region);
|
464
|
+
plugin._actionSpinner(inst, region);
|
465
|
+
plugin._timer = null;
|
466
|
+
plugin._handlingSpinner = true;
|
467
|
+
if (region >= 3 && inst.options.spinnerRepeat[0]) { // Repeat increment/decrement
|
468
|
+
plugin._timer = setTimeout(
|
469
|
+
function() { plugin._repeatSpinner(inst, region); },
|
470
|
+
inst.options.spinnerRepeat[0]);
|
471
|
+
$(spinner).one('mouseout', plugin._releaseSpinner).
|
472
|
+
one('mouseup', plugin._releaseSpinner);
|
473
|
+
}
|
474
|
+
},
|
475
|
+
|
476
|
+
/* Action a click on the spinner.
|
477
|
+
@param inst (object) the instance settings
|
478
|
+
@param region (number) the spinner "button" */
|
479
|
+
_actionSpinner: function(inst, region) {
|
480
|
+
if (!inst.input.val()) {
|
481
|
+
plugin._parseTime(inst);
|
482
|
+
}
|
483
|
+
switch (region) {
|
484
|
+
case 0: this._setTime(inst); break;
|
485
|
+
case 1: this._changeField(inst, -1, false); break;
|
486
|
+
case 2: this._changeField(inst, +1, false); break;
|
487
|
+
case 3: this._adjustField(inst, +1); break;
|
488
|
+
case 4: this._adjustField(inst, -1); break;
|
489
|
+
}
|
490
|
+
},
|
491
|
+
|
492
|
+
/* Repeat a click on the spinner.
|
493
|
+
@param inst (object) the instance settings
|
494
|
+
@param region (number) the spinner "button" */
|
495
|
+
_repeatSpinner: function(inst, region) {
|
496
|
+
if (!plugin._timer) {
|
497
|
+
return;
|
498
|
+
}
|
499
|
+
plugin._lastInput = plugin._blurredInput;
|
500
|
+
this._actionSpinner(inst, region);
|
501
|
+
this._timer = setTimeout(
|
502
|
+
function() { plugin._repeatSpinner(inst, region); },
|
503
|
+
inst.options.spinnerRepeat[1]);
|
504
|
+
},
|
505
|
+
|
506
|
+
/* Stop a spinner repeat.
|
507
|
+
@param event (event) the mouse event */
|
508
|
+
_releaseSpinner: function(event) {
|
509
|
+
clearTimeout(plugin._timer);
|
510
|
+
plugin._timer = null;
|
511
|
+
},
|
512
|
+
|
513
|
+
/* Tidy up after an expanded spinner.
|
514
|
+
@param event (event) the mouse event */
|
515
|
+
_endExpand: function(event) {
|
516
|
+
plugin._timer = null;
|
517
|
+
var spinner = plugin._getSpinnerTarget(event);
|
518
|
+
var input = plugin._getInput(spinner);
|
519
|
+
var inst = $.data(input, plugin.propertyName);
|
520
|
+
$(spinner).remove();
|
521
|
+
inst._expanded = false;
|
522
|
+
},
|
523
|
+
|
524
|
+
/* Tidy up after a spinner click.
|
525
|
+
@param event (event) the mouse event */
|
526
|
+
_endSpinner: function(event) {
|
527
|
+
plugin._timer = null;
|
528
|
+
var spinner = plugin._getSpinnerTarget(event);
|
529
|
+
var input = plugin._getInput(spinner);
|
530
|
+
var inst = $.data(input, plugin.propertyName);
|
531
|
+
if (!plugin._isDisabledPlugin(input)) {
|
532
|
+
plugin._changeSpinner(inst, spinner, -1);
|
533
|
+
}
|
534
|
+
if (plugin._handlingSpinner) {
|
535
|
+
plugin._lastInput = plugin._blurredInput;
|
536
|
+
}
|
537
|
+
if (plugin._lastInput && plugin._handlingSpinner) {
|
538
|
+
plugin._showField(inst);
|
539
|
+
}
|
540
|
+
plugin._handlingSpinner = false;
|
541
|
+
},
|
542
|
+
|
543
|
+
/* Retrieve the spinner from the event.
|
544
|
+
@param event (event) the mouse click event
|
545
|
+
@return (element) the target field */
|
546
|
+
_getSpinnerTarget: function(event) {
|
547
|
+
return event.target || event.srcElement;
|
548
|
+
},
|
549
|
+
|
550
|
+
/* Determine which "button" within the spinner was clicked.
|
551
|
+
@param inst (object) the instance settings
|
552
|
+
@param event (event) the mouse event
|
553
|
+
@return (number) the spinner "button" number */
|
554
|
+
_getSpinnerRegion: function(inst, event) {
|
555
|
+
var spinner = this._getSpinnerTarget(event);
|
556
|
+
var pos = $(spinner).offset();
|
557
|
+
var scrolled = [document.documentElement.scrollLeft || document.body.scrollLeft,
|
558
|
+
document.documentElement.scrollTop || document.body.scrollTop];
|
559
|
+
var left = (inst.options.spinnerIncDecOnly ? 99 : event.clientX + scrolled[0] - pos.left);
|
560
|
+
var top = event.clientY + scrolled[1] - pos.top;
|
561
|
+
var spinnerSize = inst.options[inst._expanded ? 'spinnerBigSize' : 'spinnerSize'];
|
562
|
+
var right = (inst.options.spinnerIncDecOnly ? 99 : spinnerSize[0] - 1 - left);
|
563
|
+
var bottom = spinnerSize[1] - 1 - top;
|
564
|
+
if (spinnerSize[2] > 0 && Math.abs(left - right) <= spinnerSize[2] &&
|
565
|
+
Math.abs(top - bottom) <= spinnerSize[2]) {
|
566
|
+
return 0; // Centre button
|
567
|
+
}
|
568
|
+
var min = Math.min(left, top, right, bottom);
|
569
|
+
return (min == left ? 1 : (min == right ? 2 : (min == top ? 3 : 4))); // Nearest edge
|
570
|
+
},
|
571
|
+
|
572
|
+
/* Change the spinner image depending on button clicked.
|
573
|
+
@param inst (object) the instance settings
|
574
|
+
@param spinner (element) the spinner control
|
575
|
+
@param region (number) the spinner "button" */
|
576
|
+
_changeSpinner: function(inst, spinner, region) {
|
577
|
+
$(spinner).css('background-position', '-' + ((region + 1) *
|
578
|
+
inst.options[inst._expanded ? 'spinnerBigSize' : 'spinnerSize'][0]) + 'px 0px');
|
579
|
+
},
|
580
|
+
|
581
|
+
/* Extract the time value from the input field, or default to now.
|
582
|
+
@param inst (object) the instance settings */
|
583
|
+
_parseTime: function(inst) {
|
584
|
+
var currentTime = this._extractTime(inst);
|
585
|
+
if (currentTime) {
|
586
|
+
inst._selectedHour = currentTime[0];
|
587
|
+
inst._selectedMinute = currentTime[1];
|
588
|
+
inst._selectedSecond = currentTime[2];
|
589
|
+
}
|
590
|
+
else {
|
591
|
+
var now = this._constrainTime(inst);
|
592
|
+
inst._selectedHour = now[0];
|
593
|
+
inst._selectedMinute = now[1];
|
594
|
+
inst._selectedSecond = (inst.options.showSeconds ? now[2] : 0);
|
595
|
+
}
|
596
|
+
inst._secondField = (inst.options.showSeconds ? 2 : -1);
|
597
|
+
inst._ampmField = (inst.options.show24Hours ? -1 : (inst.options.showSeconds ? 3 : 2));
|
598
|
+
inst._lastChr = '';
|
599
|
+
inst._field = Math.max(0, Math.min(
|
600
|
+
Math.max(1, inst._secondField, inst._ampmField), inst.options.initialField));
|
601
|
+
if (inst.input.val() != '') {
|
602
|
+
this._showTime(inst);
|
603
|
+
}
|
604
|
+
},
|
605
|
+
|
606
|
+
/* Extract the time value from a string as an array of values, or default to null.
|
607
|
+
@param inst (object) the instance settings
|
608
|
+
@param value (string) the time value to parse
|
609
|
+
@return (number[3]) the time components (hours, minutes, seconds)
|
610
|
+
or null if no value */
|
611
|
+
_extractTime: function(inst, value) {
|
612
|
+
value = value || inst.input.val();
|
613
|
+
var currentTime = value.split(inst.options.separator);
|
614
|
+
if (inst.options.separator == '' && value != '') {
|
615
|
+
currentTime[0] = value.substring(0, 2);
|
616
|
+
currentTime[1] = value.substring(2, 4);
|
617
|
+
currentTime[2] = value.substring(4, 6);
|
618
|
+
}
|
619
|
+
if (currentTime.length >= 2) {
|
620
|
+
var isAM = !inst.options.show24Hours && (value.indexOf(inst.options.ampmNames[0]) > -1);
|
621
|
+
var isPM = !inst.options.show24Hours && (value.indexOf(inst.options.ampmNames[1]) > -1);
|
622
|
+
var hour = parseInt(currentTime[0], 10);
|
623
|
+
hour = (isNaN(hour) ? 0 : hour);
|
624
|
+
hour = ((isAM || isPM) && hour == 12 ? 0 : hour) + (isPM ? 12 : 0);
|
625
|
+
var minute = parseInt(currentTime[1], 10);
|
626
|
+
minute = (isNaN(minute) ? 0 : minute);
|
627
|
+
var second = (currentTime.length >= 3 ?
|
628
|
+
parseInt(currentTime[2], 10) : 0);
|
629
|
+
second = (isNaN(second) || !inst.options.showSeconds ? 0 : second);
|
630
|
+
return this._constrainTime(inst, [hour, minute, second]);
|
631
|
+
}
|
632
|
+
return null;
|
633
|
+
},
|
634
|
+
|
635
|
+
/* Constrain the given/current time to the time steps.
|
636
|
+
@param inst (object) the instance settings
|
637
|
+
@param fields (number[3]) the current time components (hours, minutes, seconds)
|
638
|
+
@return (number[3]) the constrained time components (hours, minutes, seconds) */
|
639
|
+
_constrainTime: function(inst, fields) {
|
640
|
+
var specified = (fields != null);
|
641
|
+
if (!specified) {
|
642
|
+
var now = this._determineTime(inst.options.defaultTime, inst) || new Date();
|
643
|
+
fields = [now.getHours(), now.getMinutes(), now.getSeconds()];
|
644
|
+
}
|
645
|
+
var reset = false;
|
646
|
+
for (var i = 0; i < inst.options.timeSteps.length; i++) {
|
647
|
+
if (reset) {
|
648
|
+
fields[i] = 0;
|
649
|
+
}
|
650
|
+
else if (inst.options.timeSteps[i] > 1) {
|
651
|
+
fields[i] = Math.round(fields[i] / inst.options.timeSteps[i]) *
|
652
|
+
inst.options.timeSteps[i];
|
653
|
+
reset = true;
|
654
|
+
}
|
655
|
+
}
|
656
|
+
return fields;
|
657
|
+
},
|
658
|
+
|
659
|
+
/* Set the selected time into the input field.
|
660
|
+
@param inst (object) the instance settings */
|
661
|
+
_showTime: function(inst) {
|
662
|
+
var currentTime = (this._formatNumber(inst.options.show24Hours ? inst._selectedHour :
|
663
|
+
((inst._selectedHour + 11) % 12) + 1) + inst.options.separator +
|
664
|
+
this._formatNumber(inst._selectedMinute) +
|
665
|
+
(inst.options.showSeconds ? inst.options.separator +
|
666
|
+
this._formatNumber(inst._selectedSecond) : '') +
|
667
|
+
(inst.options.show24Hours ? '' : inst.options.ampmPrefix +
|
668
|
+
inst.options.ampmNames[(inst._selectedHour < 12 ? 0 : 1)]));
|
669
|
+
this._setValue(inst, currentTime);
|
670
|
+
this._showField(inst);
|
671
|
+
},
|
672
|
+
|
673
|
+
/* Highlight the current time field.
|
674
|
+
@param inst (object) the instance settings */
|
675
|
+
_showField: function(inst) {
|
676
|
+
var input = inst.input[0];
|
677
|
+
if (inst.input.is(':hidden') || plugin._lastInput != input) {
|
678
|
+
return;
|
679
|
+
}
|
680
|
+
var fieldSize = inst.options.separator.length + 2;
|
681
|
+
var start = (inst._field != inst._ampmField ? (inst._field * fieldSize) :
|
682
|
+
(inst._ampmField * fieldSize) - inst.options.separator.length +
|
683
|
+
inst.options.ampmPrefix.length);
|
684
|
+
var end = start + (inst._field != inst._ampmField ? 2 : inst.options.ampmNames[0].length);
|
685
|
+
if (input.setSelectionRange) { // Mozilla
|
686
|
+
input.setSelectionRange(start, end);
|
687
|
+
}
|
688
|
+
else if (input.createTextRange) { // IE
|
689
|
+
var range = input.createTextRange();
|
690
|
+
range.moveStart('character', start);
|
691
|
+
range.moveEnd('character', end - inst.input.val().length);
|
692
|
+
range.select();
|
693
|
+
}
|
694
|
+
if (!input.disabled) {
|
695
|
+
input.focus();
|
696
|
+
}
|
697
|
+
},
|
698
|
+
|
699
|
+
/* Ensure displayed single number has a leading zero.
|
700
|
+
@param value (number) current value
|
701
|
+
@return (string) number with at least two digits */
|
702
|
+
_formatNumber: function(value) {
|
703
|
+
return (value < 10 ? '0' : '') + value;
|
704
|
+
},
|
705
|
+
|
706
|
+
/* Update the input field and notify listeners.
|
707
|
+
@param inst (object) the instance settings
|
708
|
+
@param value (string) the new value */
|
709
|
+
_setValue: function(inst, value) {
|
710
|
+
if (value != inst.input.val()) {
|
711
|
+
inst.input.val(value).trigger('change');
|
712
|
+
}
|
713
|
+
},
|
714
|
+
|
715
|
+
/* Move to previous/next field, or out of field altogether if appropriate.
|
716
|
+
@param inst (object) the instance settings
|
717
|
+
@param offset (number) the direction of change (-1, +1)
|
718
|
+
@param moveOut (boolean) true if can move out of the field
|
719
|
+
@return (boolean) true if exitting the field, false if not */
|
720
|
+
_changeField: function(inst, offset, moveOut) {
|
721
|
+
var atFirstLast = (inst.input.val() == '' || inst._field ==
|
722
|
+
(offset == -1 ? 0 : Math.max(1, inst._secondField, inst._ampmField)));
|
723
|
+
if (!atFirstLast) {
|
724
|
+
inst._field += offset;
|
725
|
+
}
|
726
|
+
this._showField(inst);
|
727
|
+
inst._lastChr = '';
|
728
|
+
return (atFirstLast && moveOut);
|
729
|
+
},
|
730
|
+
|
731
|
+
/* Update the current field in the direction indicated.
|
732
|
+
@param inst (object) the instance settings
|
733
|
+
@param offset (number) the amount to change by */
|
734
|
+
_adjustField: function(inst, offset) {
|
735
|
+
if (inst.input.val() == '') {
|
736
|
+
offset = 0;
|
737
|
+
}
|
738
|
+
this._setTime(inst, new Date(0, 0, 0,
|
739
|
+
inst._selectedHour + (inst._field == 0 ? offset * inst.options.timeSteps[0] : 0) +
|
740
|
+
(inst._field == inst._ampmField ? offset * 12 : 0),
|
741
|
+
inst._selectedMinute + (inst._field == 1 ? offset * inst.options.timeSteps[1] : 0),
|
742
|
+
inst._selectedSecond +
|
743
|
+
(inst._field == inst._secondField ? offset * inst.options.timeSteps[2] : 0)));
|
744
|
+
},
|
745
|
+
|
746
|
+
/* Check against minimum/maximum and display time.
|
747
|
+
@param inst (object) the instance settings
|
748
|
+
@param time (Date) an actual time or
|
749
|
+
(number) offset in seconds from now or
|
750
|
+
(string) units and periods of offsets from now */
|
751
|
+
_setTime: function(inst, time) {
|
752
|
+
time = this._determineTime(time, inst);
|
753
|
+
var fields = this._constrainTime(inst, time ?
|
754
|
+
[time.getHours(), time.getMinutes(), time.getSeconds()] : null);
|
755
|
+
time = new Date(0, 0, 0, fields[0], fields[1], fields[2]);
|
756
|
+
// Normalise to base date
|
757
|
+
var time = this._normaliseTime(time);
|
758
|
+
var minTime = this._normaliseTime(this._determineTime(inst.options.minTime, inst));
|
759
|
+
var maxTime = this._normaliseTime(this._determineTime(inst.options.maxTime, inst));
|
760
|
+
// Ensure it is within the bounds set
|
761
|
+
if (minTime && maxTime && minTime > maxTime) {
|
762
|
+
if (time < minTime && time > maxTime) {
|
763
|
+
time = (Math.abs(time - minTime) < Math.abs(time - maxTime) ? minTime : maxTime);
|
764
|
+
}
|
765
|
+
}
|
766
|
+
else {
|
767
|
+
time = (minTime && time < minTime ? minTime :
|
768
|
+
(maxTime && time > maxTime ? maxTime : time));
|
769
|
+
}
|
770
|
+
// Perform further restrictions if required
|
771
|
+
if ($.isFunction(inst.options.beforeSetTime)) {
|
772
|
+
time = inst.options.beforeSetTime.apply(inst.input[0],
|
773
|
+
[this._getTimePlugin(inst.input[0]), time, minTime, maxTime]);
|
774
|
+
}
|
775
|
+
inst._selectedHour = time.getHours();
|
776
|
+
inst._selectedMinute = time.getMinutes();
|
777
|
+
inst._selectedSecond = time.getSeconds();
|
778
|
+
this._showTime(inst);
|
779
|
+
},
|
780
|
+
|
781
|
+
/* A time may be specified as an exact value or a relative one.
|
782
|
+
@param setting (Date) an actual time or
|
783
|
+
(number) offset in seconds from now or
|
784
|
+
(string) units and periods of offsets from now
|
785
|
+
@param inst (object) the instance settings
|
786
|
+
@return (Date) the calculated time */
|
787
|
+
_determineTime: function(setting, inst) {
|
788
|
+
var offsetNumeric = function(offset) { // E.g. +300, -2
|
789
|
+
var time = new Date();
|
790
|
+
time.setTime(time.getTime() + offset * 1000);
|
791
|
+
return time;
|
792
|
+
};
|
793
|
+
var offsetString = function(offset) { // E.g. '+2m', '-4h', '+3h +30m' or '12:34:56PM'
|
794
|
+
var fields = plugin._extractTime(inst, offset); // Actual time?
|
795
|
+
var time = new Date();
|
796
|
+
var hour = (fields ? fields[0] : time.getHours());
|
797
|
+
var minute = (fields ? fields[1] : time.getMinutes());
|
798
|
+
var second = (fields ? fields[2] : time.getSeconds());
|
799
|
+
if (!fields) {
|
800
|
+
var pattern = /([+-]?[0-9]+)\s*(s|S|m|M|h|H)?/g;
|
801
|
+
var matches = pattern.exec(offset);
|
802
|
+
while (matches) {
|
803
|
+
switch (matches[2] || 's') {
|
804
|
+
case 's' : case 'S' :
|
805
|
+
second += parseInt(matches[1], 10); break;
|
806
|
+
case 'm' : case 'M' :
|
807
|
+
minute += parseInt(matches[1], 10); break;
|
808
|
+
case 'h' : case 'H' :
|
809
|
+
hour += parseInt(matches[1], 10); break;
|
810
|
+
}
|
811
|
+
matches = pattern.exec(offset);
|
812
|
+
}
|
813
|
+
}
|
814
|
+
time = new Date(0, 0, 10, hour, minute, second, 0);
|
815
|
+
if (/^!/.test(offset)) { // No wrapping
|
816
|
+
if (time.getDate() > 10) {
|
817
|
+
time = new Date(0, 0, 10, 23, 59, 59);
|
818
|
+
}
|
819
|
+
else if (time.getDate() < 10) {
|
820
|
+
time = new Date(0, 0, 10, 0, 0, 0);
|
821
|
+
}
|
822
|
+
}
|
823
|
+
return time;
|
824
|
+
};
|
825
|
+
return (setting ? (typeof setting == 'string' ? offsetString(setting) :
|
826
|
+
(typeof setting == 'number' ? offsetNumeric(setting) : setting)) : null);
|
827
|
+
},
|
828
|
+
|
829
|
+
/* Normalise time object to a common date.
|
830
|
+
@param time (Date) the original time
|
831
|
+
@return (Date) the normalised time */
|
832
|
+
_normaliseTime: function(time) {
|
833
|
+
if (!time) {
|
834
|
+
return null;
|
835
|
+
}
|
836
|
+
time.setFullYear(1900);
|
837
|
+
time.setMonth(0);
|
838
|
+
time.setDate(0);
|
839
|
+
return time;
|
840
|
+
},
|
841
|
+
|
842
|
+
/* Update time based on keystroke entered.
|
843
|
+
@param inst (object) the instance settings
|
844
|
+
@param chr (ch) the new character */
|
845
|
+
_handleKeyPress: function(inst, chr) {
|
846
|
+
if (chr == inst.options.separator) {
|
847
|
+
this._changeField(inst, +1, false);
|
848
|
+
}
|
849
|
+
else if (chr >= '0' && chr <= '9') { // Allow direct entry of time
|
850
|
+
var key = parseInt(chr, 10);
|
851
|
+
var value = parseInt(inst._lastChr + chr, 10);
|
852
|
+
var hour = (inst._field != 0 ? inst._selectedHour :
|
853
|
+
(inst.options.show24Hours ? (value < 24 ? value : key) :
|
854
|
+
(value >= 1 && value <= 12 ? value :
|
855
|
+
(key > 0 ? key : inst._selectedHour)) % 12 +
|
856
|
+
(inst._selectedHour >= 12 ? 12 : 0)));
|
857
|
+
var minute = (inst._field != 1 ? inst._selectedMinute :
|
858
|
+
(value < 60 ? value : key));
|
859
|
+
var second = (inst._field != inst._secondField ? inst._selectedSecond :
|
860
|
+
(value < 60 ? value : key));
|
861
|
+
var fields = this._constrainTime(inst, [hour, minute, second]);
|
862
|
+
this._setTime(inst, new Date(0, 0, 0, fields[0], fields[1], fields[2]));
|
863
|
+
if (inst.options.noSeparatorEntry && inst._lastChr) {
|
864
|
+
this._changeField(inst, +1, false);
|
865
|
+
}
|
866
|
+
else {
|
867
|
+
inst._lastChr = chr;
|
868
|
+
}
|
869
|
+
}
|
870
|
+
else if (!inst.options.show24Hours) { // Set am/pm based on first char of names
|
871
|
+
chr = chr.toLowerCase();
|
872
|
+
if ((chr == inst.options.ampmNames[0].substring(0, 1).toLowerCase() &&
|
873
|
+
inst._selectedHour >= 12) ||
|
874
|
+
(chr == inst.options.ampmNames[1].substring(0, 1).toLowerCase() &&
|
875
|
+
inst._selectedHour < 12)) {
|
876
|
+
var saveField = inst._field;
|
877
|
+
inst._field = inst._ampmField;
|
878
|
+
this._adjustField(inst, +1);
|
879
|
+
inst._field = saveField;
|
880
|
+
this._showField(inst);
|
881
|
+
}
|
882
|
+
}
|
883
|
+
}
|
884
|
+
});
|
885
|
+
|
886
|
+
// The list of commands that return values and don't permit chaining
|
887
|
+
var getters = ['getOffset', 'getTime', 'isDisabled'];
|
888
|
+
|
889
|
+
/* Determine whether a command is a getter and doesn't permit chaining.
|
890
|
+
@param command (string, optional) the command to run
|
891
|
+
@param otherArgs ([], optional) any other arguments for the command
|
892
|
+
@return true if the command is a getter, false if not */
|
893
|
+
function isNotChained(command, otherArgs) {
|
894
|
+
if (command == 'option' && (otherArgs.length == 0 ||
|
895
|
+
(otherArgs.length == 1 && typeof otherArgs[0] == 'string'))) {
|
896
|
+
return true;
|
897
|
+
}
|
898
|
+
return $.inArray(command, getters) > -1;
|
899
|
+
}
|
900
|
+
|
901
|
+
/* Attach the time entry functionality to a jQuery selection.
|
902
|
+
@param options (object) the new settings to use for these instances (optional) or
|
903
|
+
(string) the command to run (optional)
|
904
|
+
@return (jQuery) for chaining further calls or
|
905
|
+
(any) getter value */
|
906
|
+
$.fn.timeEntry = function(options) {
|
907
|
+
var otherArgs = Array.prototype.slice.call(arguments, 1);
|
908
|
+
if (isNotChained(options, otherArgs)) {
|
909
|
+
return plugin['_' + options + 'Plugin'].
|
910
|
+
apply(plugin, [this[0]].concat(otherArgs));
|
911
|
+
}
|
912
|
+
return this.each(function() {
|
913
|
+
if (typeof options == 'string') {
|
914
|
+
if (!plugin['_' + options + 'Plugin']) {
|
915
|
+
throw 'Unknown command: ' + options;
|
916
|
+
}
|
917
|
+
plugin['_' + options + 'Plugin'].
|
918
|
+
apply(plugin, [this].concat(otherArgs));
|
919
|
+
}
|
920
|
+
else {
|
921
|
+
// Check for settings on the control itself
|
922
|
+
var inlineSettings = ($.fn.metadata ? $(this).metadata() : {});
|
923
|
+
plugin._attachPlugin(this, $.extend({}, inlineSettings, options || {}));
|
924
|
+
}
|
925
|
+
});
|
926
|
+
};
|
927
|
+
|
928
|
+
/* Initialise the time entry functionality. */
|
929
|
+
var plugin = $.timeEntry = new TimeEntry(); // Singleton instance
|
930
|
+
|
931
|
+
})(jQuery);
|