pikaday-gem 1.0.0.2 → 1.1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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