jquery-tools 0.0.2

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.
Files changed (30) hide show
  1. data/.gitignore +1 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +31 -0
  6. data/Rakefile +2 -0
  7. data/jquery-tools.gemspec +17 -0
  8. data/lib/jquery-tools.rb +8 -0
  9. data/lib/jquery-tools/version.rb +5 -0
  10. data/vendor/assets/images/next.gif +0 -0
  11. data/vendor/assets/images/prev.gif +0 -0
  12. data/vendor/assets/javascripts/dateinput/dateinput.js +783 -0
  13. data/vendor/assets/javascripts/overlay/overlay.apple.js +155 -0
  14. data/vendor/assets/javascripts/overlay/overlay.js +293 -0
  15. data/vendor/assets/javascripts/rangeinput/rangeinput.js +471 -0
  16. data/vendor/assets/javascripts/scrollable/scrollable.autoscroll.js +96 -0
  17. data/vendor/assets/javascripts/scrollable/scrollable.js +368 -0
  18. data/vendor/assets/javascripts/scrollable/scrollable.navigator.js +134 -0
  19. data/vendor/assets/javascripts/tabs/tabs.js +319 -0
  20. data/vendor/assets/javascripts/tabs/tabs.slideshow.js +191 -0
  21. data/vendor/assets/javascripts/toolbox/toolbox.expose.js +224 -0
  22. data/vendor/assets/javascripts/toolbox/toolbox.flashembed.js +301 -0
  23. data/vendor/assets/javascripts/toolbox/toolbox.history.js +108 -0
  24. data/vendor/assets/javascripts/toolbox/toolbox.mousewheel.js +65 -0
  25. data/vendor/assets/javascripts/tooltip/tooltip.dynamic.js +154 -0
  26. data/vendor/assets/javascripts/tooltip/tooltip.js +358 -0
  27. data/vendor/assets/javascripts/tooltip/tooltip.slide.js +78 -0
  28. data/vendor/assets/javascripts/validator/validator.js +598 -0
  29. data/vendor/assets/stylesheets/jquery-tools/dateinput.css +139 -0
  30. metadata +74 -0
@@ -0,0 +1 @@
1
+ *.gem
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create 1.9.3@jquery-tools
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jquery-tools.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Lar Van Der Jagt
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # Jquery::Tools
2
+
3
+ Wrapper for the jQuery tools library found at: [jquery-tools](http://flowplayer.org/tools/index.html)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'jquery-tools'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install jquery-tools
18
+
19
+ ## Usage
20
+
21
+ Include individual components via Sprockets:
22
+
23
+ #= require jquery-tools/dateinput/dateinput
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/jquery-tools/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Lar Van Der Jagt"]
6
+ gem.email = ["lar@hashrocket.com"]
7
+ gem.description = %q{Ruby gem to wrap the jquery-tools library}
8
+ gem.summary = %q{http://flowplayer.org/tools/index.html}
9
+ gem.homepage = ""
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "jquery-tools"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Jquery::Tools::VERSION
17
+ end
@@ -0,0 +1,8 @@
1
+ require "jquery-tools/version"
2
+
3
+ module Jquery
4
+ module Tools
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Jquery
2
+ module Tools
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,783 @@
1
+ /**
2
+ * @license
3
+ * jQuery Tools @VERSION Dateinput - <input type="date" /> for humans
4
+ *
5
+ * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
6
+ *
7
+ * http://flowplayer.org/tools/form/dateinput/
8
+ *
9
+ * Since: Mar 2010
10
+ * Date: @DATE
11
+ */
12
+ (function($, undefined) {
13
+
14
+ /* TODO:
15
+ preserve today highlighted
16
+ */
17
+
18
+ $.tools = $.tools || {version: '@VERSION'};
19
+
20
+ var instances = [],
21
+ tool,
22
+
23
+ // h=72, j=74, k=75, l=76, down=40, left=37, up=38, right=39
24
+ KEYS = [75, 76, 38, 39, 74, 72, 40, 37],
25
+ LABELS = {};
26
+
27
+ tool = $.tools.dateinput = {
28
+
29
+ conf: {
30
+ format: 'mm/dd/yy',
31
+ selectors: false,
32
+ yearRange: [-5, 5],
33
+ lang: 'en',
34
+ offset: [0, 0],
35
+ speed: 0,
36
+ firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
37
+ min: undefined,
38
+ max: undefined,
39
+ trigger: 0,
40
+ toggle: 0,
41
+ editable: 0,
42
+
43
+ css: {
44
+
45
+ prefix: 'cal',
46
+ input: 'date',
47
+
48
+ // ids
49
+ root: 0,
50
+ head: 0,
51
+ title: 0,
52
+ prev: 0,
53
+ next: 0,
54
+ month: 0,
55
+ year: 0,
56
+ days: 0,
57
+
58
+ body: 0,
59
+ weeks: 0,
60
+ today: 0,
61
+ current: 0,
62
+
63
+ // classnames
64
+ week: 0,
65
+ off: 0,
66
+ sunday: 0,
67
+ focus: 0,
68
+ disabled: 0,
69
+ trigger: 0
70
+ }
71
+ },
72
+
73
+ localize: function(language, labels) {
74
+ $.each(labels, function(key, val) {
75
+ labels[key] = val.split(",");
76
+ });
77
+ LABELS[language] = labels;
78
+ }
79
+
80
+ };
81
+
82
+ tool.localize("en", {
83
+ months: 'January,February,March,April,May,June,July,August,September,October,November,December',
84
+ shortMonths: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec',
85
+ days: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday',
86
+ shortDays: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'
87
+ });
88
+
89
+
90
+ //{{{ private functions
91
+
92
+
93
+ // @return amount of days in certain month
94
+ function dayAm(year, month) {
95
+ return new Date(year, month + 1, 0).getDate();
96
+ }
97
+
98
+ function zeropad(val, len) {
99
+ val = '' + val;
100
+ len = len || 2;
101
+ while (val.length < len) { val = "0" + val; }
102
+ return val;
103
+ }
104
+
105
+ // thanks: http://stevenlevithan.com/assets/misc/date.format.js
106
+ var Re = /d{1,4}|m{1,4}|yy(?:yy)?|"[^"]*"|'[^']*'/g, tmpTag = $("<a/>");
107
+
108
+ function format(date, fmt, lang) {
109
+
110
+ var d = date.getDate(),
111
+ D = date.getDay(),
112
+ m = date.getMonth(),
113
+ y = date.getFullYear(),
114
+
115
+ flags = {
116
+ d: d,
117
+ dd: zeropad(d),
118
+ ddd: LABELS[lang].shortDays[D],
119
+ dddd: LABELS[lang].days[D],
120
+ m: m + 1,
121
+ mm: zeropad(m + 1),
122
+ mmm: LABELS[lang].shortMonths[m],
123
+ mmmm: LABELS[lang].months[m],
124
+ yy: String(y).slice(2),
125
+ yyyy: y
126
+ };
127
+
128
+ var ret = fmt.replace(Re, function ($0) {
129
+ return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
130
+ });
131
+
132
+ // a small trick to handle special characters
133
+ return tmpTag.html(ret).html();
134
+
135
+ }
136
+
137
+ function integer(val) {
138
+ return parseInt(val, 10);
139
+ }
140
+
141
+ function isSameDay(d1, d2) {
142
+ return d1.getFullYear() === d2.getFullYear() &&
143
+ d1.getMonth() == d2.getMonth() &&
144
+ d1.getDate() == d2.getDate();
145
+ }
146
+
147
+ function parseDate(val) {
148
+
149
+ if (val === undefined) { return; }
150
+ if (val.constructor == Date) { return val; }
151
+
152
+ if (typeof val == 'string') {
153
+
154
+ // rfc3339?
155
+ var els = val.split("-");
156
+ if (els.length == 3) {
157
+ return new Date(integer(els[0]), integer(els[1]) -1, integer(els[2]));
158
+ }
159
+
160
+ // invalid offset
161
+ if ( !(/^-?\d+$/).test(val) ) { return; }
162
+
163
+ // convert to integer
164
+ val = integer(val);
165
+ }
166
+
167
+ var date = new Date;
168
+ date.setDate(date.getDate() + val);
169
+ return date;
170
+ }
171
+
172
+ //}}}
173
+
174
+
175
+ function Dateinput(input, conf) {
176
+
177
+ // variables
178
+ var self = this,
179
+ now = new Date,
180
+ yearNow = now.getFullYear(),
181
+ css = conf.css,
182
+ labels = LABELS[conf.lang],
183
+ root = $("#" + css.root),
184
+ title = root.find("#" + css.title),
185
+ trigger,
186
+ pm, nm,
187
+ currYear, currMonth, currDay,
188
+ value = input.attr("data-value") || conf.value || input.val(),
189
+ min = input.attr("min") || conf.min,
190
+ max = input.attr("max") || conf.max,
191
+ opened,
192
+ original;
193
+
194
+ // zero min is not undefined
195
+ if (min === 0) { min = "0"; }
196
+
197
+ // use sane values for value, min & max
198
+ value = parseDate(value) || now;
199
+
200
+ min = parseDate(min || new Date(yearNow + conf.yearRange[0], 1, 1));
201
+ max = parseDate(max || new Date( yearNow + conf.yearRange[1]+ 1, 1, -1));
202
+
203
+
204
+ // check that language exists
205
+ if (!labels) { throw "Dateinput: invalid language: " + conf.lang; }
206
+
207
+ // Replace built-in date input: NOTE: input.attr("type", "text") throws exception by the browser
208
+ if (input.attr("type") == 'date') {
209
+ var original = input.clone(),
210
+ def = original.wrap("<div/>").parent().html(),
211
+ clone = $(def.replace(/type/i, "type=text data-orig-type"));
212
+
213
+ if (conf.value) clone.val(conf.value); // jquery 1.6.2 val(undefined) will clear val()
214
+
215
+ input.replaceWith(clone);
216
+ input = clone;
217
+ }
218
+
219
+ input.addClass(css.input);
220
+
221
+ var fire = input.add(self);
222
+
223
+ // construct layout
224
+ if (!root.length) {
225
+
226
+ // root
227
+ root = $('<div><div><a/><div/><a/></div><div><div/><div/></div></div>')
228
+ .hide().css({position: 'absolute'}).attr("id", css.root);
229
+
230
+ // elements
231
+ root.children()
232
+ .eq(0).attr("id", css.head).end()
233
+ .eq(1).attr("id", css.body).children()
234
+ .eq(0).attr("id", css.days).end()
235
+ .eq(1).attr("id", css.weeks).end().end().end()
236
+ .find("a").eq(0).attr("id", css.prev).end().eq(1).attr("id", css.next);
237
+
238
+ // title
239
+ title = root.find("#" + css.head).find("div").attr("id", css.title);
240
+
241
+ // year & month selectors
242
+ if (conf.selectors) {
243
+ var monthSelector = $("<select/>").attr("id", css.month),
244
+ yearSelector = $("<select/>").attr("id", css.year);
245
+ title.html(monthSelector.add(yearSelector));
246
+ }
247
+
248
+ // day titles
249
+ var days = root.find("#" + css.days);
250
+
251
+ // days of the week
252
+ for (var d = 0; d < 7; d++) {
253
+ days.append($("<span/>").text(labels.shortDays[(d + conf.firstDay) % 7]));
254
+ }
255
+
256
+ $("body").append(root);
257
+ }
258
+
259
+
260
+ // trigger icon
261
+ if (conf.trigger) {
262
+ trigger = $("<a/>").attr("href", "#").addClass(css.trigger).click(function(e) {
263
+ conf.toggle ? self.toggle() : self.show();
264
+ return e.preventDefault();
265
+ }).insertAfter(input);
266
+ }
267
+
268
+
269
+ // layout elements
270
+ var weeks = root.find("#" + css.weeks);
271
+ yearSelector = root.find("#" + css.year);
272
+ monthSelector = root.find("#" + css.month);
273
+
274
+
275
+ //{{{ pick
276
+
277
+ function select(date, conf, e) {
278
+
279
+ // current value
280
+ value = date;
281
+ currYear = date.getFullYear();
282
+ currMonth = date.getMonth();
283
+ currDay = date.getDate();
284
+
285
+
286
+ // beforChange
287
+ e = e || $.Event("api");
288
+ e.type = "beforeChange";
289
+
290
+ fire.trigger(e, [date]);
291
+ if (e.isDefaultPrevented()) { return; }
292
+
293
+ // formatting
294
+ input.val(format(date, conf.format, conf.lang));
295
+
296
+ // change
297
+ e.type = "change";
298
+ fire.trigger(e);
299
+
300
+ // store value into input
301
+ input.data("date", date);
302
+
303
+ self.hide(e);
304
+ }
305
+ //}}}
306
+
307
+
308
+ //{{{ onShow
309
+
310
+ function onShow(ev) {
311
+
312
+ ev.type = "onShow";
313
+ fire.trigger(ev);
314
+
315
+ $(document).bind("keydown.d", function(e) {
316
+
317
+ if (e.ctrlKey) { return true; }
318
+ var key = e.keyCode;
319
+
320
+ // backspace clears the value
321
+ if (key == 8) {
322
+ input.val("");
323
+ return self.hide(e);
324
+ }
325
+
326
+ // esc or tab key
327
+ if (key == 27 || key == 9) { return self.hide(e); }
328
+
329
+ if ($(KEYS).index(key) >= 0) {
330
+
331
+ if (!opened) {
332
+ self.show(e);
333
+ return e.preventDefault();
334
+ }
335
+
336
+ var days = $("#" + css.weeks + " a"),
337
+ el = $("." + css.focus),
338
+ index = days.index(el);
339
+
340
+ el.removeClass(css.focus);
341
+
342
+ if (key == 74 || key == 40) { index += 7; }
343
+ else if (key == 75 || key == 38) { index -= 7; }
344
+ else if (key == 76 || key == 39) { index += 1; }
345
+ else if (key == 72 || key == 37) { index -= 1; }
346
+
347
+
348
+ if (index > 41) {
349
+ self.addMonth();
350
+ el = $("#" + css.weeks + " a:eq(" + (index-42) + ")");
351
+ } else if (index < 0) {
352
+ self.addMonth(-1);
353
+ el = $("#" + css.weeks + " a:eq(" + (index+42) + ")");
354
+ } else {
355
+ el = days.eq(index);
356
+ }
357
+
358
+ el.addClass(css.focus);
359
+ return e.preventDefault();
360
+
361
+ }
362
+
363
+ // pageUp / pageDown
364
+ if (key == 34) { return self.addMonth(); }
365
+ if (key == 33) { return self.addMonth(-1); }
366
+
367
+ // home
368
+ if (key == 36) { return self.today(); }
369
+
370
+ // enter
371
+ if (key == 13) {
372
+ if (!$(e.target).is("select")) {
373
+ $("." + css.focus).click();
374
+ }
375
+ }
376
+
377
+ return $([16, 17, 18, 9]).index(key) >= 0;
378
+ });
379
+
380
+
381
+ // click outside dateinput
382
+ $(document).bind("click.d", function(e) {
383
+ var el = e.target;
384
+
385
+ if (!$(el).parents("#" + css.root).length && el != input[0] && (!trigger || el != trigger[0])) {
386
+ self.hide(e);
387
+ }
388
+
389
+ });
390
+ }
391
+ //}}}
392
+
393
+
394
+ $.extend(self, {
395
+
396
+
397
+ /**
398
+ * @public
399
+ * Show the calendar
400
+ */
401
+ show: function(e) {
402
+
403
+ if (input.attr("readonly") || input.attr("disabled") || opened) { return; }
404
+
405
+ // onBeforeShow
406
+ e = e || $.Event();
407
+ e.type = "onBeforeShow";
408
+ fire.trigger(e);
409
+ if (e.isDefaultPrevented()) { return; }
410
+
411
+ $.each(instances, function() {
412
+ this.hide();
413
+ });
414
+
415
+ opened = true;
416
+
417
+ // month selector
418
+ monthSelector.unbind("change").change(function() {
419
+ self.setValue(yearSelector.val(), $(this).val());
420
+ });
421
+
422
+ // year selector
423
+ yearSelector.unbind("change").change(function() {
424
+ self.setValue($(this).val(), monthSelector.val());
425
+ });
426
+
427
+ // prev / next month
428
+ pm = root.find("#" + css.prev).unbind("click").click(function(e) {
429
+ if (!pm.hasClass(css.disabled)) {
430
+ self.addMonth(-1);
431
+ }
432
+ return false;
433
+ });
434
+
435
+ nm = root.find("#" + css.next).unbind("click").click(function(e) {
436
+ if (!nm.hasClass(css.disabled)) {
437
+ self.addMonth();
438
+ }
439
+ return false;
440
+ });
441
+
442
+ // set date
443
+ self.setValue(value);
444
+
445
+ // show calendar
446
+ var pos = input.offset();
447
+
448
+ // iPad position fix
449
+ if (/iPad/i.test(navigator.userAgent)) {
450
+ pos.top -= $(window).scrollTop();
451
+ }
452
+
453
+ root.css({
454
+ top: pos.top + input.outerHeight({margins: true}) + conf.offset[0],
455
+ left: pos.left + conf.offset[1]
456
+ });
457
+
458
+ if (conf.speed) {
459
+ root.show(conf.speed, function() {
460
+ onShow(e);
461
+ });
462
+ } else {
463
+ root.show();
464
+ onShow(e);
465
+ }
466
+
467
+ return self;
468
+ },
469
+
470
+ /**
471
+ * @public
472
+ *
473
+ * Set the value of the dateinput
474
+ */
475
+ setValue: function(year, month, day) {
476
+
477
+ var date = integer(month) >= -1 ? new Date(integer(year), integer(month), integer(day == undefined || isNaN(day) ? 1 : day)) :
478
+ year || value;
479
+
480
+ if (date < min) { date = min; }
481
+ else if (date > max) { date = max; }
482
+
483
+ // date given as ISO string
484
+ if (typeof year == 'string') { date = parseDate(year); }
485
+
486
+ year = date.getFullYear();
487
+ month = date.getMonth();
488
+ day = date.getDate();
489
+
490
+
491
+ // roll year & month
492
+ if (month == -1) {
493
+ month = 11;
494
+ year--;
495
+ } else if (month == 12) {
496
+ month = 0;
497
+ year++;
498
+ }
499
+
500
+ if (!opened) {
501
+ select(date, conf);
502
+ return self;
503
+ }
504
+
505
+ currMonth = month;
506
+ currYear = year;
507
+ currDay = day;
508
+
509
+ // variables
510
+ var tmp = new Date(year, month, 1 - conf.firstDay), begin = tmp.getDay(),
511
+ days = dayAm(year, month),
512
+ prevDays = dayAm(year, month - 1),
513
+ week;
514
+
515
+ // selectors
516
+ if (conf.selectors) {
517
+
518
+ // month selector
519
+ monthSelector.empty();
520
+ $.each(labels.months, function(i, m) {
521
+ if (min < new Date(year, i + 1, 1) && max > new Date(year, i, 0)) {
522
+ monthSelector.append($("<option/>").html(m).attr("value", i));
523
+ }
524
+ });
525
+
526
+ // year selector
527
+ yearSelector.empty();
528
+ var yearNow = now.getFullYear();
529
+
530
+ for (var i = yearNow + conf.yearRange[0]; i < yearNow + conf.yearRange[1]; i++) {
531
+ if (min < new Date(i + 1, 0, 1) && max > new Date(i, 0, 0)) {
532
+ yearSelector.append($("<option/>").text(i));
533
+ }
534
+ }
535
+
536
+ monthSelector.val(month);
537
+ yearSelector.val(year);
538
+
539
+ // title
540
+ } else {
541
+ title.html(labels.months[month] + " " + year);
542
+ }
543
+
544
+ // populate weeks
545
+ weeks.empty();
546
+ pm.add(nm).removeClass(css.disabled);
547
+
548
+ // !begin === "sunday"
549
+ for (var j = !begin ? -7 : 0, a, num; j < (!begin ? 35 : 42); j++) {
550
+
551
+ a = $("<a/>");
552
+
553
+ if (j % 7 === 0) {
554
+ week = $("<div/>").addClass(css.week);
555
+ weeks.append(week);
556
+ }
557
+
558
+ if (j < begin) {
559
+ a.addClass(css.off);
560
+ num = prevDays - begin + j + 1;
561
+ date = new Date(year, month-1, num);
562
+
563
+ } else if (j >= begin + days) {
564
+ a.addClass(css.off);
565
+ num = j - days - begin + 1;
566
+ date = new Date(year, month+1, num);
567
+
568
+ } else {
569
+ num = j - begin + 1;
570
+ date = new Date(year, month, num);
571
+
572
+ // current date
573
+ if (isSameDay(value, date)) {
574
+ a.attr("id", css.current).addClass(css.focus);
575
+
576
+ // today
577
+ } else if (isSameDay(now, date)) {
578
+ a.attr("id", css.today);
579
+ }
580
+ }
581
+
582
+ // disabled
583
+ if (min && date < min) {
584
+ a.add(pm).addClass(css.disabled);
585
+ }
586
+
587
+ if (max && date > max) {
588
+ a.add(nm).addClass(css.disabled);
589
+ }
590
+
591
+ a.attr("href", "#" + num).text(num).data("date", date);
592
+
593
+ week.append(a);
594
+ }
595
+
596
+ // date picking
597
+ weeks.find("a").click(function(e) {
598
+ var el = $(this);
599
+ if (!el.hasClass(css.disabled)) {
600
+ $("#" + css.current).removeAttr("id");
601
+ el.attr("id", css.current);
602
+ select(el.data("date"), conf, e);
603
+ }
604
+ return false;
605
+ });
606
+
607
+ // sunday
608
+ if (css.sunday) {
609
+ weeks.find(css.week).each(function() {
610
+ var beg = conf.firstDay ? 7 - conf.firstDay : 0;
611
+ $(this).children().slice(beg, beg + 1).addClass(css.sunday);
612
+ });
613
+ }
614
+
615
+ return self;
616
+ },
617
+ //}}}
618
+
619
+ setMin: function(val, fit) {
620
+ min = parseDate(val);
621
+ if (fit && value < min) { self.setValue(min); }
622
+ return self;
623
+ },
624
+
625
+ setMax: function(val, fit) {
626
+ max = parseDate(val);
627
+ if (fit && value > max) { self.setValue(max); }
628
+ return self;
629
+ },
630
+
631
+ today: function() {
632
+ return self.setValue(now);
633
+ },
634
+
635
+ addDay: function(amount) {
636
+ return this.setValue(currYear, currMonth, currDay + (amount || 1));
637
+ },
638
+
639
+ addMonth: function(amount) {
640
+ var targetMonth = currMonth + (amount || 1),
641
+ daysInTargetMonth = dayAm(currYear, targetMonth),
642
+ targetDay = currDay <= daysInTargetMonth ? currDay : daysInTargetMonth;
643
+
644
+ return this.setValue(currYear, targetMonth, targetDay);
645
+ },
646
+
647
+ addYear: function(amount) {
648
+ return this.setValue(currYear + (amount || 1), currMonth, currDay);
649
+ },
650
+
651
+ destroy: function() {
652
+ input.add(document).unbind("click.d").unbind("keydown.d");
653
+ root.add(trigger).remove();
654
+ input.removeData("dateinput").removeClass(css.input);
655
+ if (original) { input.replaceWith(original); }
656
+ },
657
+
658
+ hide: function(e) {
659
+
660
+ if (opened) {
661
+
662
+ // onHide
663
+ e = $.Event();
664
+ e.type = "onHide";
665
+ fire.trigger(e);
666
+
667
+ $(document).unbind("click.d").unbind("keydown.d");
668
+
669
+ // cancelled ?
670
+ if (e.isDefaultPrevented()) { return; }
671
+
672
+ // do the hide
673
+ root.hide();
674
+ opened = false;
675
+ }
676
+
677
+ return self;
678
+ },
679
+
680
+ toggle: function(){
681
+ return self.isOpen() ? self.hide() : self.show();
682
+ },
683
+
684
+ getConf: function() {
685
+ return conf;
686
+ },
687
+
688
+ getInput: function() {
689
+ return input;
690
+ },
691
+
692
+ getCalendar: function() {
693
+ return root;
694
+ },
695
+
696
+ getValue: function(dateFormat) {
697
+ return dateFormat ? format(value, dateFormat, conf.lang) : value;
698
+ },
699
+
700
+ isOpen: function() {
701
+ return opened;
702
+ }
703
+
704
+ });
705
+
706
+ // callbacks
707
+ $.each(['onBeforeShow','onShow','change','onHide'], function(i, name) {
708
+
709
+ // configuration
710
+ if ($.isFunction(conf[name])) {
711
+ $(self).bind(name, conf[name]);
712
+ }
713
+
714
+ // API methods
715
+ self[name] = function(fn) {
716
+ if (fn) { $(self).bind(name, fn); }
717
+ return self;
718
+ };
719
+ });
720
+
721
+ if (!conf.editable) {
722
+
723
+ // show dateinput & assign keyboard shortcuts
724
+ input.bind("focus.d click.d", self.show).keydown(function(e) {
725
+
726
+ var key = e.keyCode;
727
+
728
+ // open dateinput with navigation keyw
729
+ if (!opened && $(KEYS).index(key) >= 0) {
730
+ self.show(e);
731
+ return e.preventDefault();
732
+ }
733
+
734
+ // allow tab
735
+ return e.shiftKey || e.ctrlKey || e.altKey || key == 9 ? true : e.preventDefault();
736
+
737
+ });
738
+ }
739
+
740
+ // initial value
741
+ if (parseDate(input.val())) {
742
+ select(value, conf);
743
+ }
744
+
745
+ }
746
+
747
+ $.expr[':'].date = function(el) {
748
+ var type = el.getAttribute("type");
749
+ return type && type == 'date' || !!$(el).data("dateinput");
750
+ };
751
+
752
+
753
+ $.fn.dateinput = function(conf) {
754
+
755
+ // already instantiated
756
+ if (this.data("dateinput")) { return this; }
757
+
758
+ // configuration
759
+ conf = $.extend(true, {}, tool.conf, conf);
760
+
761
+ // CSS prefix
762
+ $.each(conf.css, function(key, val) {
763
+ if (!val && key != 'prefix') {
764
+ conf.css[key] = (conf.css.prefix || '') + (val || key);
765
+ }
766
+ });
767
+
768
+ var els;
769
+
770
+ this.each(function() {
771
+ var el = new Dateinput($(this), conf);
772
+ instances.push(el);
773
+ var input = el.getInput().data("dateinput", el);
774
+ els = els ? els.add(input) : input;
775
+ });
776
+
777
+ return els ? els : this;
778
+ };
779
+
780
+
781
+ }) (jQuery);
782
+
783
+