pikaday-gem 1.0.0.2 → 1.1.0.0

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.
data/README.md CHANGED
@@ -47,8 +47,10 @@ If you would like to update this gem you should take the following steps:
47
47
  Then the maintainer of the gem will need to do the following steps:
48
48
 
49
49
  1. Update the version [lib/pikaday-gem/version.rb](lib/pikaday-gem/version.rb)
50
- 1. Run ``gem build pikaday-gem.gemspec`` to package the gem
51
- 1. Once satisfied, push the gem up to RubyGems.org with ``gem push pikaday-gem-<VERSION>.gem``
50
+ 1. `rake build`
51
+ 1. `git add .`
52
+ 1. `git commit -am "version changes"`
52
53
  1. Update [the changelog](CHANGELOG.md)
54
+ 1. `rake release`
53
55
 
54
56
  [pikaday]: https://github.com/dbushell/Pikaday
@@ -1,3 +1,3 @@
1
1
  module PikadayGem
2
- VERSION = "1.0.0.2"
2
+ VERSION = "1.1.0.0"
3
3
  end
@@ -0,0 +1,838 @@
1
+ /*!
2
+ * Pikaday
3
+ *
4
+ * Copyright © 2013 David Bushell | BSD & MIT license | https://github.com/dbushell/Pikaday
5
+ */
6
+
7
+ (function (root, define, factory)
8
+ {
9
+ 'use strict';
10
+
11
+ if (typeof define === 'function' && define.amd) {
12
+ // AMD. Register as an anonymous module.
13
+ define(function (req)
14
+ {
15
+ // Load moment.js as an optional dependency
16
+ var id = 'moment';
17
+ var moment = req.defined && req.defined(id) ? req(id) : undefined;
18
+ return factory(moment || root.moment);
19
+ });
20
+ } else {
21
+ // Browser global
22
+ root.Pikaday = factory(root.moment);
23
+ }
24
+ }(window, window.define, function (moment)
25
+ {
26
+ 'use strict';
27
+
28
+ /**
29
+ * feature detection and helper functions
30
+ */
31
+ var hasMoment = typeof moment === 'function',
32
+
33
+ hasEventListeners = !!window.addEventListener,
34
+
35
+ document = window.document,
36
+
37
+ sto = window.setTimeout,
38
+
39
+ addEvent = function(el, e, callback, capture)
40
+ {
41
+ if (hasEventListeners) {
42
+ el.addEventListener(e, callback, !!capture);
43
+ } else {
44
+ el.attachEvent('on' + e, callback);
45
+ }
46
+ },
47
+
48
+ removeEvent = function(el, e, callback, capture)
49
+ {
50
+ if (hasEventListeners) {
51
+ el.removeEventListener(e, callback, !!capture);
52
+ } else {
53
+ el.detachEvent('on' + e, callback);
54
+ }
55
+ },
56
+
57
+ fireEvent = function(el, eventName, data)
58
+ {
59
+ var ev;
60
+
61
+ if (document.createEvent) {
62
+ ev = document.createEvent('HTMLEvents');
63
+ ev.initEvent(eventName, true, false);
64
+ ev = extend(ev, data);
65
+ el.dispatchEvent(ev);
66
+ } else if (document.createEventObject) {
67
+ ev = document.createEventObject();
68
+ ev = extend(ev, data);
69
+ el.fireEvent('on' + eventName, ev);
70
+ }
71
+ },
72
+
73
+ trim = function(str)
74
+ {
75
+ return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g,'');
76
+ },
77
+
78
+ hasClass = function(el, cn)
79
+ {
80
+ return (' ' + el.className + ' ').indexOf(' ' + cn + ' ') !== -1;
81
+ },
82
+
83
+ addClass = function(el, cn)
84
+ {
85
+ if (!hasClass(el, cn)) {
86
+ el.className = (el.className === '') ? cn : el.className + ' ' + cn;
87
+ }
88
+ },
89
+
90
+ removeClass = function(el, cn)
91
+ {
92
+ el.className = trim((' ' + el.className + ' ').replace(' ' + cn + ' ', ' '));
93
+ },
94
+
95
+ isArray = function(obj)
96
+ {
97
+ return (/Array/).test(Object.prototype.toString.call(obj));
98
+ },
99
+
100
+ isDate = function(obj)
101
+ {
102
+ return (/Date/).test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
103
+ },
104
+
105
+ isLeapYear = function(year)
106
+ {
107
+ // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
108
+ return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
109
+ },
110
+
111
+ getDaysInMonth = function(year, month)
112
+ {
113
+ return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
114
+ },
115
+
116
+ setToStartOfDay = function(date)
117
+ {
118
+ if (isDate(date)) date.setHours(0,0,0,0);
119
+ },
120
+
121
+ compareDates = function(a,b)
122
+ {
123
+ // weak date comparison (use setToStartOfDay(date) to ensure correct result)
124
+ return a.getTime() === b.getTime();
125
+ },
126
+
127
+ extend = function(to, from, overwrite)
128
+ {
129
+ var prop, hasProp;
130
+ for (prop in from) {
131
+ hasProp = to[prop] !== undefined;
132
+ if (hasProp && typeof from[prop] === 'object' && from[prop].nodeName === undefined) {
133
+ if (isDate(from[prop])) {
134
+ if (overwrite) {
135
+ to[prop] = new Date(from[prop].getTime());
136
+ }
137
+ }
138
+ else if (isArray(from[prop])) {
139
+ if (overwrite) {
140
+ to[prop] = from[prop].slice(0);
141
+ }
142
+ } else {
143
+ to[prop] = extend({}, from[prop], overwrite);
144
+ }
145
+ } else if (overwrite || !hasProp) {
146
+ to[prop] = from[prop];
147
+ }
148
+ }
149
+ return to;
150
+ },
151
+
152
+
153
+ /**
154
+ * defaults and localisation
155
+ */
156
+ defaults = {
157
+
158
+ // bind the picker to a form field
159
+ field: null,
160
+
161
+ // automatically show/hide the picker on `field` focus (default `true` if `field` is set)
162
+ bound: undefined,
163
+
164
+ // the default output format for `.toString()` and `field` value
165
+ format: 'YYYY-MM-DD',
166
+
167
+ // the initial date to view when first opened
168
+ defaultDate: null,
169
+
170
+ // make the `defaultDate` the initial selected value
171
+ setDefaultDate: false,
172
+
173
+ // first day of week (0: Sunday, 1: Monday etc)
174
+ firstDay: 0,
175
+
176
+ // the minimum/earliest date that can be selected
177
+ minDate: null,
178
+ // the maximum/latest date that can be selected
179
+ maxDate: null,
180
+
181
+ // number of years either side, or array of upper/lower range
182
+ yearRange: 10,
183
+
184
+ // used internally (don't config outside)
185
+ minYear: 0,
186
+ maxYear: 9999,
187
+ minMonth: undefined,
188
+ maxMonth: undefined,
189
+
190
+ isRTL: false,
191
+
192
+ // how many months are visible (not implemented yet)
193
+ numberOfMonths: 1,
194
+
195
+ // internationalization
196
+ i18n: {
197
+ previousMonth : 'Previous Month',
198
+ nextMonth : 'Next Month',
199
+ months : ['January','February','March','April','May','June','July','August','September','October','November','December'],
200
+ weekdays : ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
201
+ weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
202
+ },
203
+
204
+ // callback function
205
+ onSelect: null,
206
+ onOpen: null,
207
+ onClose: null,
208
+ onDraw: null
209
+ },
210
+
211
+
212
+ /**
213
+ * templating functions to abstract HTML rendering
214
+ */
215
+ renderDayName = function(opts, day, abbr)
216
+ {
217
+ day += opts.firstDay;
218
+ while (day >= 7) {
219
+ day -= 7;
220
+ }
221
+ return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day];
222
+ },
223
+
224
+ renderDay = function(i, isSelected, isToday, isDisabled, isEmpty)
225
+ {
226
+ if (isEmpty) {
227
+ return '<td class="is-empty"></td>';
228
+ }
229
+ var arr = [];
230
+ if (isDisabled) {
231
+ arr.push('is-disabled');
232
+ }
233
+ if (isToday) {
234
+ arr.push('is-today');
235
+ }
236
+ if (isSelected) {
237
+ arr.push('is-selected');
238
+ }
239
+ return '<td data-day="' + i + '" class="' + arr.join(' ') + '"><button class="pika-button" type="button">' + i + '</button>' + '</td>';
240
+ },
241
+
242
+ renderRow = function(days, isRTL)
243
+ {
244
+ return '<tr>' + (isRTL ? days.reverse() : days).join('') + '</tr>';
245
+ },
246
+
247
+ renderBody = function(rows)
248
+ {
249
+ return '<tbody>' + rows.join('') + '</tbody>';
250
+ },
251
+
252
+ renderHead = function(opts)
253
+ {
254
+ var i, arr = [];
255
+ for (i = 0; i < 7; i++) {
256
+ arr.push('<th scope="col"><abbr title="' + renderDayName(opts, i) + '">' + renderDayName(opts, i, true) + '</abbr></th>');
257
+ }
258
+ return '<thead>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</thead>';
259
+ },
260
+
261
+ renderTitle = function(instance)
262
+ {
263
+ var i, j, arr,
264
+ opts = instance._o,
265
+ month = instance._m,
266
+ year = instance._y,
267
+ isMinYear = year === opts.minYear,
268
+ isMaxYear = year === opts.maxYear,
269
+ html = '<div class="pika-title">',
270
+ prev = true,
271
+ next = true;
272
+
273
+ for (arr = [], i = 0; i < 12; i++) {
274
+ arr.push('<option value="' + i + '"' +
275
+ (i === month ? ' selected': '') +
276
+ ((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth) ? 'disabled' : '') + '>' +
277
+ opts.i18n.months[i] + '</option>');
278
+ }
279
+ html += '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month">' + arr.join('') + '</select></div>';
280
+
281
+ if (isArray(opts.yearRange)) {
282
+ i = opts.yearRange[0];
283
+ j = opts.yearRange[1] + 1;
284
+ } else {
285
+ i = year - opts.yearRange;
286
+ j = 1 + year + opts.yearRange;
287
+ }
288
+
289
+ for (arr = []; i < j && i <= opts.maxYear; i++) {
290
+ if (i >= opts.minYear) {
291
+ arr.push('<option value="' + i + '"' + (i === year ? ' selected': '') + '>' + (i) + '</option>');
292
+ }
293
+ }
294
+ html += '<div class="pika-label">' + year + '<select class="pika-select pika-select-year">' + arr.join('') + '</select></div>';
295
+
296
+ if (isMinYear && (month === 0 || opts.minMonth >= month)) {
297
+ prev = false;
298
+ }
299
+
300
+ if (isMaxYear && (month === 11 || opts.maxMonth <= month)) {
301
+ next = false;
302
+ }
303
+
304
+ html += '<button class="pika-prev' + (prev ? '' : ' is-disabled') + '" type="button">' + opts.i18n.previousMonth + '</button>';
305
+ html += '<button class="pika-next' + (next ? '' : ' is-disabled') + '" type="button">' + opts.i18n.nextMonth + '</button>';
306
+
307
+ return html += '</div>';
308
+ },
309
+
310
+ renderTable = function(opts, data)
311
+ {
312
+ return '<table cellpadding="0" cellspacing="0" class="pika-table">' + renderHead(opts) + renderBody(data) + '</table>';
313
+ },
314
+
315
+
316
+ /**
317
+ * Pikaday constructor
318
+ */
319
+ Pikaday = function(options)
320
+ {
321
+ var self = this,
322
+ opts = self.config(options);
323
+
324
+ self._onMouseDown = function(e)
325
+ {
326
+ if (!self._v) {
327
+ return;
328
+ }
329
+ e = e || window.event;
330
+ var target = e.target || e.srcElement;
331
+ if (!target) {
332
+ return;
333
+ }
334
+
335
+ if (!hasClass(target, 'is-disabled')) {
336
+ if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')) {
337
+ self.setDate(new Date(self._y, self._m, parseInt(target.innerHTML, 10)));
338
+ if (opts.bound) {
339
+ sto(function() {
340
+ self.hide();
341
+ }, 100);
342
+ }
343
+ return;
344
+ }
345
+ else if (hasClass(target, 'pika-prev')) {
346
+ self.prevMonth();
347
+ }
348
+ else if (hasClass(target, 'pika-next')) {
349
+ self.nextMonth();
350
+ }
351
+ }
352
+ if (!hasClass(target, 'pika-select')) {
353
+ if (e.preventDefault) {
354
+ e.preventDefault();
355
+ } else {
356
+ e.returnValue = false;
357
+ return false;
358
+ }
359
+ } else {
360
+ self._c = true;
361
+ }
362
+ };
363
+
364
+ self._onChange = function(e)
365
+ {
366
+ e = e || window.event;
367
+ var target = e.target || e.srcElement;
368
+ if (!target) {
369
+ return;
370
+ }
371
+ if (hasClass(target, 'pika-select-month')) {
372
+ self.gotoMonth(target.value);
373
+ }
374
+ else if (hasClass(target, 'pika-select-year')) {
375
+ self.gotoYear(target.value);
376
+ }
377
+ };
378
+
379
+ self._onInputChange = function(e)
380
+ {
381
+ var date;
382
+
383
+ if (e.firedBy === self) {
384
+ return;
385
+ }
386
+ if (hasMoment) {
387
+ date = moment(opts.field.value, opts.format);
388
+ date = (date && date.isValid()) ? date.toDate() : null;
389
+ }
390
+ else {
391
+ date = new Date(Date.parse(opts.field.value));
392
+ }
393
+ self.setDate(isDate(date) ? date : null);
394
+ if (!self._v) {
395
+ self.show();
396
+ }
397
+ };
398
+
399
+ self._onInputFocus = function()
400
+ {
401
+ self.show();
402
+ };
403
+
404
+ self._onInputClick = function()
405
+ {
406
+ self.show();
407
+ };
408
+
409
+ self._onInputBlur = function()
410
+ {
411
+ if (!self._c) {
412
+ self._b = sto(function() {
413
+ self.hide();
414
+ }, 50);
415
+ }
416
+ self._c = false;
417
+ };
418
+
419
+ self._onClick = function(e)
420
+ {
421
+ e = e || window.event;
422
+ var target = e.target || e.srcElement,
423
+ pEl = target;
424
+ if (!target) {
425
+ return;
426
+ }
427
+ if (!hasEventListeners && hasClass(target, 'pika-select')) {
428
+ if (!target.onchange) {
429
+ target.setAttribute('onchange', 'return;');
430
+ addEvent(target, 'change', self._onChange);
431
+ }
432
+ }
433
+ do {
434
+ if (hasClass(pEl, 'pika-single')) {
435
+ return;
436
+ }
437
+ }
438
+ while ((pEl = pEl.parentNode));
439
+ if (self._v && target !== opts.field) {
440
+ self.hide();
441
+ }
442
+ };
443
+
444
+ self.el = document.createElement('div');
445
+ self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : '');
446
+
447
+ addEvent(self.el, 'mousedown', self._onMouseDown, true);
448
+ addEvent(self.el, 'change', self._onChange);
449
+
450
+ if (opts.field) {
451
+ if (opts.bound) {
452
+ document.body.appendChild(self.el);
453
+ } else {
454
+ opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling);
455
+ }
456
+ addEvent(opts.field, 'change', self._onInputChange);
457
+
458
+ if (!opts.defaultDate) {
459
+ if (hasMoment && opts.field.value) {
460
+ opts.defaultDate = moment(opts.field.value, opts.format).toDate();
461
+ } else {
462
+ opts.defaultDate = new Date(Date.parse(opts.field.value));
463
+ }
464
+ opts.setDefaultDate = true;
465
+ }
466
+ }
467
+
468
+ var defDate = opts.defaultDate;
469
+
470
+ if (isDate(defDate)) {
471
+ if (opts.setDefaultDate) {
472
+ self.setDate(defDate, true);
473
+ } else {
474
+ self.gotoDate(defDate);
475
+ }
476
+ } else {
477
+ self.gotoDate(new Date());
478
+ }
479
+
480
+ if (opts.bound) {
481
+ this.hide();
482
+ self.el.className += ' is-bound';
483
+ addEvent(opts.field, 'click', self._onInputClick);
484
+ addEvent(opts.field, 'focus', self._onInputFocus);
485
+ addEvent(opts.field, 'blur', self._onInputBlur);
486
+ } else {
487
+ this.show();
488
+ }
489
+
490
+ };
491
+
492
+
493
+ /**
494
+ * public Pikaday API
495
+ */
496
+ Pikaday.prototype = {
497
+
498
+
499
+ /**
500
+ * configure functionality
501
+ */
502
+ config: function(options)
503
+ {
504
+ if (!this._o) {
505
+ this._o = extend({}, defaults, true);
506
+ }
507
+
508
+ var opts = extend(this._o, options, true);
509
+
510
+ opts.isRTL = !!opts.isRTL;
511
+
512
+ opts.field = (opts.field && opts.field.nodeName) ? opts.field : null;
513
+
514
+ opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field);
515
+
516
+ var nom = parseInt(opts.numberOfMonths, 10) || 1;
517
+ opts.numberOfMonths = nom > 4 ? 4 : nom;
518
+
519
+ if (!isDate(opts.minDate)) {
520
+ opts.minDate = false;
521
+ }
522
+ if (!isDate(opts.maxDate)) {
523
+ opts.maxDate = false;
524
+ }
525
+ if ((opts.minDate && opts.maxDate) && opts.maxDate < opts.minDate) {
526
+ opts.maxDate = opts.minDate = false;
527
+ }
528
+ if (opts.minDate) {
529
+ setToStartOfDay(opts.minDate);
530
+ opts.minYear = opts.minDate.getFullYear();
531
+ opts.minMonth = opts.minDate.getMonth();
532
+ }
533
+ if (opts.maxDate) {
534
+ setToStartOfDay(opts.maxDate);
535
+ opts.maxYear = opts.maxDate.getFullYear();
536
+ opts.maxMonth = opts.maxDate.getMonth();
537
+ }
538
+
539
+ if (isArray(opts.yearRange)) {
540
+ var fallback = new Date().getFullYear() - 10;
541
+ opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback;
542
+ opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback;
543
+ } else {
544
+ opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange;
545
+ if (opts.yearRange > 100) {
546
+ opts.yearRange = 100;
547
+ }
548
+ }
549
+
550
+ return opts;
551
+ },
552
+
553
+ /**
554
+ * return a formatted string of the current selection (using Moment.js if available)
555
+ */
556
+ toString: function(format)
557
+ {
558
+ return !isDate(this._d) ? '' : hasMoment ? moment(this._d).format(format || this._o.format) : this._d.toDateString();
559
+ },
560
+
561
+ /**
562
+ * return a Moment.js object of the current selection (if available)
563
+ */
564
+ getMoment: function()
565
+ {
566
+ return hasMoment ? moment(this._d) : null;
567
+ },
568
+
569
+ /**
570
+ * set the current selection from a Moment.js object (if available)
571
+ */
572
+ setMoment: function(date)
573
+ {
574
+ if (hasMoment && moment.isMoment(date)) {
575
+ this.setDate(date.toDate());
576
+ }
577
+ },
578
+
579
+ /**
580
+ * return a Date object of the current selection
581
+ */
582
+ getDate: function()
583
+ {
584
+ return isDate(this._d) ? new Date(this._d.getTime()) : null;
585
+ },
586
+
587
+ /**
588
+ * set the current selection
589
+ */
590
+ setDate: function(date, preventOnSelect)
591
+ {
592
+ if (!date) {
593
+ this._d = null;
594
+ return this.draw();
595
+ }
596
+ if (typeof date === 'string') {
597
+ date = new Date(Date.parse(date));
598
+ }
599
+ if (!isDate(date)) {
600
+ return;
601
+ }
602
+
603
+ var min = this._o.minDate,
604
+ max = this._o.maxDate;
605
+
606
+ if (isDate(min) && date < min) {
607
+ date = min;
608
+ } else if (isDate(max) && date > max) {
609
+ date = max;
610
+ }
611
+
612
+ this._d = new Date(date.getTime());
613
+ setToStartOfDay(this._d);
614
+ this.gotoDate(this._d);
615
+
616
+ if (this._o.field) {
617
+ this._o.field.value = this.toString();
618
+ fireEvent(this._o.field, 'change', { firedBy: this });
619
+ }
620
+ if (!preventOnSelect && typeof this._o.onSelect === 'function') {
621
+ this._o.onSelect.call(this, this.getDate());
622
+ }
623
+ },
624
+
625
+ /**
626
+ * change view to a specific date
627
+ */
628
+ gotoDate: function(date)
629
+ {
630
+ if (!isDate(date)) {
631
+ return;
632
+ }
633
+ this._y = date.getFullYear();
634
+ this._m = date.getMonth();
635
+ this.draw();
636
+ },
637
+
638
+ gotoToday: function()
639
+ {
640
+ this.gotoDate(new Date());
641
+ },
642
+
643
+ /**
644
+ * change view to a specific month (zero-index, e.g. 0: January)
645
+ */
646
+ gotoMonth: function(month)
647
+ {
648
+ if (!isNaN( (month = parseInt(month, 10)) )) {
649
+ this._m = month < 0 ? 0 : month > 11 ? 11 : month;
650
+ this.draw();
651
+ }
652
+ },
653
+
654
+ nextMonth: function()
655
+ {
656
+ if (++this._m > 11) {
657
+ this._m = 0;
658
+ this._y++;
659
+ }
660
+ this.draw();
661
+ },
662
+
663
+ prevMonth: function()
664
+ {
665
+ if (--this._m < 0) {
666
+ this._m = 11;
667
+ this._y--;
668
+ }
669
+ this.draw();
670
+ },
671
+
672
+ /**
673
+ * change view to a specific full year (e.g. "2012")
674
+ */
675
+ gotoYear: function(year)
676
+ {
677
+ if (!isNaN(year)) {
678
+ this._y = parseInt(year, 10);
679
+ this.draw();
680
+ }
681
+ },
682
+
683
+ /**
684
+ * refresh the HTML
685
+ */
686
+ draw: function(force)
687
+ {
688
+ if (!this._v && !force) {
689
+ return;
690
+ }
691
+ var opts = this._o,
692
+ minYear = opts.minYear,
693
+ maxYear = opts.maxYear,
694
+ minMonth = opts.minMonth,
695
+ maxMonth = opts.maxMonth;
696
+
697
+ if (this._y <= minYear) {
698
+ this._y = minYear;
699
+ if (!isNaN(minMonth) && this._m < minMonth) {
700
+ this._m = minMonth;
701
+ }
702
+ }
703
+ if (this._y >= maxYear) {
704
+ this._y = maxYear;
705
+ if (!isNaN(maxMonth) && this._m > maxMonth) {
706
+ this._m = maxMonth;
707
+ }
708
+ }
709
+
710
+ this.el.innerHTML = renderTitle(this) + this.render(this._y, this._m);
711
+
712
+ if (opts.bound) {
713
+ var pEl = opts.field,
714
+ left = pEl.offsetLeft,
715
+ top = pEl.offsetTop + pEl.offsetHeight;
716
+ while((pEl = pEl.offsetParent)) {
717
+ left += pEl.offsetLeft;
718
+ top += pEl.offsetTop;
719
+ }
720
+ this.el.style.cssText = 'position:absolute;left:' + left + 'px;top:' + top + 'px;';
721
+ sto(function() {
722
+ opts.field.focus();
723
+ }, 1);
724
+ }
725
+
726
+ if (typeof this._o.onDraw === 'function') {
727
+ var self = this;
728
+ sto(function() {
729
+ self._o.onDraw.call(self);
730
+ }, 0);
731
+ }
732
+ },
733
+
734
+ /**
735
+ * render HTML for a particular month
736
+ */
737
+ render: function(year, month)
738
+ {
739
+ var opts = this._o,
740
+ now = new Date(),
741
+ days = getDaysInMonth(year, month),
742
+ before = new Date(year, month, 1).getDay(),
743
+ data = [],
744
+ row = [];
745
+ setToStartOfDay(now);
746
+ if (opts.firstDay > 0) {
747
+ before -= opts.firstDay;
748
+ if (before < 0) {
749
+ before += 7;
750
+ }
751
+ }
752
+ var cells = days + before,
753
+ after = cells;
754
+ while(after > 7) {
755
+ after -= 7;
756
+ }
757
+ cells += 7 - after;
758
+ for (var i = 0, r = 0; i < cells; i++)
759
+ {
760
+ var day = new Date(year, month, 1 + (i - before)),
761
+ isDisabled = (opts.minDate && day < opts.minDate) || (opts.maxDate && day > opts.maxDate),
762
+ isSelected = isDate(this._d) ? compareDates(day, this._d) : false,
763
+ isToday = compareDates(day, now),
764
+ isEmpty = i < before || i >= (days + before);
765
+
766
+ row.push(renderDay(1 + (i - before), isSelected, isToday, isDisabled, isEmpty));
767
+
768
+ if (++r === 7) {
769
+ data.push(renderRow(row, opts.isRTL));
770
+ row = [];
771
+ r = 0;
772
+ }
773
+ }
774
+ return renderTable(opts, data);
775
+ },
776
+
777
+ isVisible: function()
778
+ {
779
+ return this._v;
780
+ },
781
+
782
+ show: function()
783
+ {
784
+ if (!this._v) {
785
+ if (this._o.bound) {
786
+ addEvent(document, 'click', this._onClick);
787
+ }
788
+ removeClass(this.el, 'is-hidden');
789
+ this._v = true;
790
+ this.draw();
791
+ if (typeof this._o.onOpen === 'function') {
792
+ this._o.onOpen.call(this);
793
+ }
794
+ }
795
+ },
796
+
797
+ hide: function()
798
+ {
799
+ var v = this._v;
800
+ if (v !== false) {
801
+ if (this._o.bound) {
802
+ removeEvent(document, 'click', this._onClick);
803
+ }
804
+ this.el.style.cssText = '';
805
+ addClass(this.el, 'is-hidden');
806
+ this._v = false;
807
+ if (v !== undefined && typeof this._o.onClose === 'function') {
808
+ this._o.onClose.call(this);
809
+ }
810
+ }
811
+ },
812
+
813
+ /**
814
+ * GAME OVER
815
+ */
816
+ destroy: function()
817
+ {
818
+ this.hide();
819
+ removeEvent(this.el, 'mousedown', this._onMouseDown, true);
820
+ removeEvent(this.el, 'change', this._onChange);
821
+ if (this._o.field) {
822
+ removeEvent(this._o.field, 'change', this._onInputChange);
823
+ if (this._o.bound) {
824
+ removeEvent(this._o.field, 'click', this._onInputClick);
825
+ removeEvent(this._o.field, 'focus', this._onInputFocus);
826
+ removeEvent(this._o.field, 'blur', this._onInputBlur);
827
+ }
828
+ }
829
+ if (this.el.parentNode) {
830
+ this.el.parentNode.removeChild(this.el);
831
+ }
832
+ }
833
+
834
+ };
835
+
836
+ return Pikaday;
837
+
838
+ }));
@@ -1,19 +1,39 @@
1
1
  /*!
2
2
  * Pikaday
3
- * Copyright © 2012 David Bushell | BSD & MIT license | http://dbushell.com/
3
+ *
4
+ * Copyright © 2013 David Bushell | BSD & MIT license | https://github.com/dbushell/Pikaday
4
5
  */
5
6
 
6
- (function(window, document, undefined)
7
+ (function (root, define, factory)
8
+ {
9
+ 'use strict';
10
+
11
+ if (typeof define === 'function' && define.amd) {
12
+ // AMD. Register as an anonymous module.
13
+ define(function (req)
14
+ {
15
+ // Load moment.js as an optional dependency
16
+ var id = 'moment';
17
+ var moment = req.defined && req.defined(id) ? req(id) : undefined;
18
+ return factory(moment || root.moment);
19
+ });
20
+ } else {
21
+ // Browser global
22
+ root.Pikaday = factory(root.moment);
23
+ }
24
+ }(window, window.define, function (moment)
7
25
  {
8
26
  'use strict';
9
27
 
10
28
  /**
11
29
  * feature detection and helper functions
12
30
  */
13
- var hasMoment = typeof window.moment === 'function',
31
+ var hasMoment = typeof moment === 'function',
14
32
 
15
33
  hasEventListeners = !!window.addEventListener,
16
34
 
35
+ document = window.document,
36
+
17
37
  sto = window.setTimeout,
18
38
 
19
39
  addEvent = function(el, e, callback, capture)
@@ -174,12 +194,11 @@
174
194
 
175
195
  // internationalization
176
196
  i18n: {
177
- previousMonth : 'Previous Month',
178
- nextMonth : 'Next Month',
179
- months : ['January','February','March','April','May','June','July','August','September','October','November','December'],
180
- //monthsShort : ['Jan_Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
181
- weekdays : ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
182
- weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
197
+ previousMonth : 'Previous Month',
198
+ nextMonth : 'Next Month',
199
+ months : ['January','February','March','April','May','June','July','August','September','October','November','December'],
200
+ weekdays : ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
201
+ weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
183
202
  },
184
203
 
185
204
  // callback function
@@ -291,13 +310,13 @@
291
310
  renderTable = function(opts, data)
292
311
  {
293
312
  return '<table cellpadding="0" cellspacing="0" class="pika-table">' + renderHead(opts) + renderBody(data) + '</table>';
294
- };
313
+ },
295
314
 
296
315
 
297
316
  /**
298
317
  * Pikaday constructor
299
318
  */
300
- window.Pikaday = function(options)
319
+ Pikaday = function(options)
301
320
  {
302
321
  var self = this,
303
322
  opts = self.config(options);
@@ -334,7 +353,8 @@
334
353
  if (e.preventDefault) {
335
354
  e.preventDefault();
336
355
  } else {
337
- return e.returnValue = false;
356
+ e.returnValue = false;
357
+ return false;
338
358
  }
339
359
  } else {
340
360
  self._c = true;
@@ -364,8 +384,8 @@
364
384
  return;
365
385
  }
366
386
  if (hasMoment) {
367
- date = window.moment(opts.field.value, opts.format);
368
- date = date ? date.toDate() : null;
387
+ date = moment(opts.field.value, opts.format);
388
+ date = (date && date.isValid()) ? date.toDate() : null;
369
389
  }
370
390
  else {
371
391
  date = new Date(Date.parse(opts.field.value));
@@ -376,17 +396,17 @@
376
396
  }
377
397
  };
378
398
 
379
- self._onInputFocus = function(e)
399
+ self._onInputFocus = function()
380
400
  {
381
401
  self.show();
382
402
  };
383
403
 
384
- self._onInputClick = function(e)
404
+ self._onInputClick = function()
385
405
  {
386
406
  self.show();
387
407
  };
388
408
 
389
- self._onInputBlur = function(e)
409
+ self._onInputBlur = function()
390
410
  {
391
411
  if (!self._c) {
392
412
  self._b = sto(function() {
@@ -437,7 +457,7 @@
437
457
 
438
458
  if (!opts.defaultDate) {
439
459
  if (hasMoment && opts.field.value) {
440
- opts.defaultDate = window.moment(opts.field.value, opts.format).toDate();
460
+ opts.defaultDate = moment(opts.field.value, opts.format).toDate();
441
461
  } else {
442
462
  opts.defaultDate = new Date(Date.parse(opts.field.value));
443
463
  }
@@ -473,7 +493,7 @@
473
493
  /**
474
494
  * public Pikaday API
475
495
  */
476
- window.Pikaday.prototype = {
496
+ Pikaday.prototype = {
477
497
 
478
498
 
479
499
  /**
@@ -535,7 +555,7 @@
535
555
  */
536
556
  toString: function(format)
537
557
  {
538
- return !isDate(this._d) ? '' : hasMoment ? window.moment(this._d).format(format || this._o.format) : this._d.toDateString();
558
+ return !isDate(this._d) ? '' : hasMoment ? moment(this._d).format(format || this._o.format) : this._d.toDateString();
539
559
  },
540
560
 
541
561
  /**
@@ -543,7 +563,7 @@
543
563
  */
544
564
  getMoment: function()
545
565
  {
546
- return hasMoment ? window.moment(this._d) : null;
566
+ return hasMoment ? moment(this._d) : null;
547
567
  },
548
568
 
549
569
  /**
@@ -551,7 +571,7 @@
551
571
  */
552
572
  setMoment: function(date)
553
573
  {
554
- if (hasMoment && window.moment.isMoment(date)) {
574
+ if (hasMoment && moment.isMoment(date)) {
555
575
  this.setDate(date.toDate());
556
576
  }
557
577
  },
@@ -595,7 +615,7 @@
595
615
 
596
616
  if (this._o.field) {
597
617
  this._o.field.value = this.toString();
598
- fireEvent(this._o.field, "change", { firedBy: this });
618
+ fireEvent(this._o.field, 'change', { firedBy: this });
599
619
  }
600
620
  if (!preventOnSelect && typeof this._o.onSelect === 'function') {
601
621
  this._o.onSelect.call(this, this.getDate());
@@ -813,4 +833,6 @@
813
833
 
814
834
  };
815
835
 
816
- })(window, window.document);
836
+ return Pikaday;
837
+
838
+ }));
@@ -0,0 +1,171 @@
1
+ @charset "UTF-8";
2
+
3
+ /*!
4
+ * Pikaday
5
+ * Copyright © 2012 David Bushell | BSD & MIT license | http://dbushell.com/
6
+ */
7
+
8
+ .pika-single {
9
+ z-index: 9999;
10
+ display: block;
11
+ position: relative;
12
+ width: 240px;
13
+ padding: 8px;
14
+ color: #333;
15
+ background: #fff;
16
+ border: 1px solid #ccc;
17
+ border-bottom-color: #bbb;
18
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
19
+ }
20
+
21
+ .pika-single.is-hidden {
22
+ display: none;
23
+ }
24
+
25
+ .pika-single.is-bound {
26
+ position: absolute;
27
+ box-shadow: 0 5px 15px -5px rgba(0,0,0,.5);
28
+ }
29
+
30
+ .pika-title {
31
+ position: relative;
32
+ text-align: center;
33
+ }
34
+
35
+ .pika-label {
36
+ display: inline-block;
37
+ *display: inline;
38
+ position: relative;
39
+ z-index: 9999;
40
+ overflow: hidden;
41
+ margin: 0;
42
+ padding: 5px 3px;
43
+ font-size: 14px;
44
+ line-height: 20px;
45
+ font-weight: bold;
46
+ background-color: #fff;
47
+ }
48
+ .pika-title select {
49
+ cursor: pointer;
50
+ position: absolute;
51
+ z-index: 9998;
52
+ margin: 0;
53
+ left: 0;
54
+ top: 5px;
55
+ filter: alpha(opacity=0);
56
+ opacity: 0;
57
+ }
58
+
59
+ .pika-prev,
60
+ .pika-next {
61
+ display: block;
62
+ cursor: pointer;
63
+ position: relative;
64
+ outline: none;
65
+ border: 0;
66
+ padding: 0;
67
+ width: 20px;
68
+ height: 30px;
69
+ background-color: transparent;
70
+ background-position: center center;
71
+ background-repeat: no-repeat;
72
+ background-size: 75% 75%;
73
+ white-space: nowrap;
74
+ text-indent: 100%;
75
+ overflow: hidden;
76
+ opacity: .5;
77
+ *position: absolute;
78
+ *top: 0;
79
+ }
80
+
81
+ .pika-prev:hover,
82
+ .pika-next:hover {
83
+ opacity: 1;
84
+ }
85
+
86
+ .pika-prev,
87
+ .is-rtl .pika-next {
88
+ float: left;
89
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==');
90
+ *left: 0;
91
+ }
92
+
93
+ .pika-next,
94
+ .is-rtl .pika-prev {
95
+ float: right;
96
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=');
97
+ *right: 0;
98
+ }
99
+
100
+ .pika-prev.is-disabled,
101
+ .pika-next.is-disabled {
102
+ cursor: default;
103
+ opacity: .2;
104
+ }
105
+
106
+ .pika-select {
107
+ display: inline-block;
108
+ *display: inline;
109
+ }
110
+
111
+ .pika-table {
112
+ width: 100%;
113
+ border-collapse: collapse;
114
+ border-spacing: 0;
115
+ border: 0;
116
+ }
117
+
118
+ .pika-table th,
119
+ .pika-table td {
120
+ width: 14.285714285714286%;
121
+ }
122
+
123
+ .pika-table th {
124
+ color: #999;
125
+ font-size: 12px;
126
+ line-height: 25px;
127
+ font-weight: bold;
128
+ text-align: center;
129
+ }
130
+
131
+ .pika-button {
132
+ cursor: pointer;
133
+ display: block;
134
+ outline: none;
135
+ border: 0;
136
+ margin: 0;
137
+ width: 100%;
138
+ padding: 5px;
139
+ color: #666;
140
+ font-size: 12px;
141
+ line-height: 15px;
142
+ text-align: right;
143
+ background: #f5f5f5;
144
+ }
145
+
146
+ .is-today .pika-button {
147
+ color: #33aaff;
148
+ font-weight: bold;
149
+ }
150
+
151
+ .is-selected .pika-button {
152
+ color: #fff;
153
+ font-weight: bold;
154
+ background: #33aaff;
155
+ box-shadow: inset 0 1px 3px #178fe5;
156
+ border-radius: 3px;
157
+ }
158
+
159
+ .is-disabled .pika-button {
160
+ pointer-events: none;
161
+ cursor: default;
162
+ color: #999;
163
+ opacity: .3;
164
+ }
165
+
166
+ .pika-button:hover {
167
+ color: #fff !important;
168
+ background: #ff8000 !important;
169
+ box-shadow: none !important;
170
+ border-radius: 3px !important;
171
+ }
@@ -52,6 +52,7 @@
52
52
  margin: 0;
53
53
  left: 0;
54
54
  top: 5px;
55
+ filter: alpha(opacity=0);
55
56
  opacity: 0;
56
57
  }
57
58
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pikaday-gem
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.2
4
+ version: 1.1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-03-20 00:00:00.000000000 Z
14
+ date: 2013-03-29 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: railties
@@ -56,8 +56,10 @@ files:
56
56
  - lib/pikaday-gem/version.rb
57
57
  - lib/pikaday-gem.rb
58
58
  - vendor/assets/javascripts/1.0.0/pikaday.js
59
+ - vendor/assets/javascripts/1.1.0/pikaday.js
59
60
  - vendor/assets/javascripts/pikaday.js
60
61
  - vendor/assets/stylesheets/1.0.0/pikaday.css
62
+ - vendor/assets/stylesheets/1.1.0/pikaday.css
61
63
  - vendor/assets/stylesheets/pikaday.css
62
64
  - MIT-LICENSE
63
65
  - Rakefile
@@ -76,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
78
  version: '0'
77
79
  segments:
78
80
  - 0
79
- hash: -2116128138076977319
81
+ hash: -1622310218773215052
80
82
  required_rubygems_version: !ruby/object:Gem::Requirement
81
83
  none: false
82
84
  requirements:
@@ -85,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
87
  version: '0'
86
88
  segments:
87
89
  - 0
88
- hash: -2116128138076977319
90
+ hash: -1622310218773215052
89
91
  requirements: []
90
92
  rubyforge_project:
91
93
  rubygems_version: 1.8.24