pikaday-gem 1.2.0 → 1.4.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.
@@ -20,7 +20,7 @@
20
20
  {
21
21
  // Load moment.js as an optional dependency
22
22
  var id = 'moment';
23
- moment = req.defined && req.defined(id) ? req(id) : undefined;
23
+ try { moment = req(id); } catch (e) {}
24
24
  return factory(moment);
25
25
  });
26
26
  } else {
@@ -107,6 +107,12 @@
107
107
  return (/Date/).test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
108
108
  },
109
109
 
110
+ isWeekend = function(date)
111
+ {
112
+ var day = date.getDay();
113
+ return day === 0 || day === 6;
114
+ },
115
+
110
116
  isLeapYear = function(year)
111
117
  {
112
118
  // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
@@ -134,7 +140,7 @@
134
140
  var prop, hasProp;
135
141
  for (prop in from) {
136
142
  hasProp = to[prop] !== undefined;
137
- if (hasProp && typeof from[prop] === 'object' && from[prop].nodeName === undefined) {
143
+ if (hasProp && typeof from[prop] === 'object' && from[prop] !== null && from[prop].nodeName === undefined) {
138
144
  if (isDate(from[prop])) {
139
145
  if (overwrite) {
140
146
  to[prop] = new Date(from[prop].getTime());
@@ -154,6 +160,17 @@
154
160
  return to;
155
161
  },
156
162
 
163
+ adjustCalendar = function(calendar) {
164
+ if (calendar.month < 0) {
165
+ calendar.year -= Math.ceil(Math.abs(calendar.month)/12);
166
+ calendar.month += 12;
167
+ }
168
+ if (calendar.month > 11) {
169
+ calendar.year += Math.floor(Math.abs(calendar.month)/12);
170
+ calendar.month -= 12;
171
+ }
172
+ return calendar;
173
+ },
157
174
 
158
175
  /**
159
176
  * defaults and localisation
@@ -170,6 +187,9 @@
170
187
  // ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position)
171
188
  position: 'bottom left',
172
189
 
190
+ // automatically fit in the viewport even if it means repositioning from the position option
191
+ reposition: true,
192
+
173
193
  // the default output format for `.toString()` and `field` value
174
194
  format: 'YYYY-MM-DD',
175
195
 
@@ -190,12 +210,18 @@
190
210
  // number of years either side, or array of upper/lower range
191
211
  yearRange: 10,
192
212
 
213
+ // show week numbers at head of row
214
+ showWeekNumber: false,
215
+
193
216
  // used internally (don't config outside)
194
217
  minYear: 0,
195
218
  maxYear: 9999,
196
219
  minMonth: undefined,
197
220
  maxMonth: undefined,
198
221
 
222
+ startRange: null,
223
+ endRange: null,
224
+
199
225
  isRTL: false,
200
226
 
201
227
  // Additional text to append to the year in the calendar title
@@ -204,9 +230,16 @@
204
230
  // Render the month after year in the calendar title
205
231
  showMonthAfterYear: false,
206
232
 
207
- // how many months are visible (not implemented yet)
233
+ // how many months are visible
208
234
  numberOfMonths: 1,
209
235
 
236
+ // when numberOfMonths is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`)
237
+ // only used for the first display or when a selected date is not visible
238
+ mainCalendar: 'left',
239
+
240
+ // Specify a DOM element to render the calendar in
241
+ container: undefined,
242
+
210
243
  // internationalization
211
244
  i18n: {
212
245
  previousMonth : 'Previous Month',
@@ -216,6 +249,9 @@
216
249
  weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
217
250
  },
218
251
 
252
+ // Theme Classname
253
+ theme: null,
254
+
219
255
  // callback function
220
256
  onSelect: null,
221
257
  onOpen: null,
@@ -236,22 +272,43 @@
236
272
  return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day];
237
273
  },
238
274
 
239
- renderDay = function(i, isSelected, isToday, isDisabled, isEmpty)
275
+ renderDay = function(opts)
240
276
  {
241
- if (isEmpty) {
277
+ if (opts.isEmpty) {
242
278
  return '<td class="is-empty"></td>';
243
279
  }
244
280
  var arr = [];
245
- if (isDisabled) {
281
+ if (opts.isDisabled) {
246
282
  arr.push('is-disabled');
247
283
  }
248
- if (isToday) {
284
+ if (opts.isToday) {
249
285
  arr.push('is-today');
250
286
  }
251
- if (isSelected) {
287
+ if (opts.isSelected) {
252
288
  arr.push('is-selected');
253
289
  }
254
- return '<td data-day="' + i + '" class="' + arr.join(' ') + '"><button class="pika-button" type="button">' + i + '</button>' + '</td>';
290
+ if (opts.isInRange) {
291
+ arr.push('is-inrange');
292
+ }
293
+ if (opts.isStartRange) {
294
+ arr.push('is-startrange');
295
+ }
296
+ if (opts.isEndRange) {
297
+ arr.push('is-endrange');
298
+ }
299
+ return '<td data-day="' + opts.day + '" class="' + arr.join(' ') + '">' +
300
+ '<button class="pika-button pika-day" type="button" ' +
301
+ 'data-pika-year="' + opts.year + '" data-pika-month="' + opts.month + '" data-pika-day="' + opts.day + '">' +
302
+ opts.day +
303
+ '</button>' +
304
+ '</td>';
305
+ },
306
+
307
+ renderWeek = function (d, m, y) {
308
+ // Lifted from http://javascript.about.com/library/blweekyear.htm, lightly modified.
309
+ var onejan = new Date(y, 0, 1),
310
+ weekNum = Math.ceil((((new Date(y, m, d) - onejan) / 86400000) + onejan.getDay()+1)/7);
311
+ return '<td class="pika-week">' + weekNum + '</td>';
255
312
  },
256
313
 
257
314
  renderRow = function(days, isRTL)
@@ -267,18 +324,19 @@
267
324
  renderHead = function(opts)
268
325
  {
269
326
  var i, arr = [];
327
+ if (opts.showWeekNumber) {
328
+ arr.push('<th></th>');
329
+ }
270
330
  for (i = 0; i < 7; i++) {
271
331
  arr.push('<th scope="col"><abbr title="' + renderDayName(opts, i) + '">' + renderDayName(opts, i, true) + '</abbr></th>');
272
332
  }
273
333
  return '<thead>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</thead>';
274
334
  },
275
335
 
276
- renderTitle = function(instance)
336
+ renderTitle = function(instance, c, year, month, refYear)
277
337
  {
278
338
  var i, j, arr,
279
339
  opts = instance._o,
280
- month = instance._m,
281
- year = instance._y,
282
340
  isMinYear = year === opts.minYear,
283
341
  isMaxYear = year === opts.maxYear,
284
342
  html = '<div class="pika-title">',
@@ -288,12 +346,12 @@
288
346
  next = true;
289
347
 
290
348
  for (arr = [], i = 0; i < 12; i++) {
291
- arr.push('<option value="' + i + '"' +
349
+ arr.push('<option value="' + (year === refYear ? i - c : 12 + i - c) + '"' +
292
350
  (i === month ? ' selected': '') +
293
351
  ((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth) ? 'disabled' : '') + '>' +
294
352
  opts.i18n.months[i] + '</option>');
295
353
  }
296
- monthHtml = '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month">' + arr.join('') + '</select></div>';
354
+ monthHtml = '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month" tabindex="-1">' + arr.join('') + '</select></div>';
297
355
 
298
356
  if (isArray(opts.yearRange)) {
299
357
  i = opts.yearRange[0];
@@ -308,7 +366,7 @@
308
366
  arr.push('<option value="' + i + '"' + (i === year ? ' selected': '') + '>' + (i) + '</option>');
309
367
  }
310
368
  }
311
- yearHtml = '<div class="pika-label">' + year + opts.yearSuffix + '<select class="pika-select pika-select-year">' + arr.join('') + '</select></div>';
369
+ yearHtml = '<div class="pika-label">' + year + opts.yearSuffix + '<select class="pika-select pika-select-year" tabindex="-1">' + arr.join('') + '</select></div>';
312
370
 
313
371
  if (opts.showMonthAfterYear) {
314
372
  html += yearHtml + monthHtml;
@@ -324,8 +382,12 @@
324
382
  next = false;
325
383
  }
326
384
 
327
- html += '<button class="pika-prev' + (prev ? '' : ' is-disabled') + '" type="button">' + opts.i18n.previousMonth + '</button>';
328
- html += '<button class="pika-next' + (next ? '' : ' is-disabled') + '" type="button">' + opts.i18n.nextMonth + '</button>';
385
+ if (c === 0) {
386
+ html += '<button class="pika-prev' + (prev ? '' : ' is-disabled') + '" type="button">' + opts.i18n.previousMonth + '</button>';
387
+ }
388
+ if (c === (instance._o.numberOfMonths - 1) ) {
389
+ html += '<button class="pika-next' + (next ? '' : ' is-disabled') + '" type="button">' + opts.i18n.nextMonth + '</button>';
390
+ }
329
391
 
330
392
  return html += '</div>';
331
393
  },
@@ -357,13 +419,15 @@
357
419
 
358
420
  if (!hasClass(target, 'is-disabled')) {
359
421
  if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')) {
360
- self.setDate(new Date(self._y, self._m, parseInt(target.innerHTML, 10)));
422
+ self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day')));
361
423
  if (opts.bound) {
362
424
  sto(function() {
363
425
  self.hide();
426
+ if (opts.field) {
427
+ opts.field.blur();
428
+ }
364
429
  }, 100);
365
430
  }
366
- return;
367
431
  }
368
432
  else if (hasClass(target, 'pika-prev')) {
369
433
  self.prevMonth();
@@ -373,6 +437,7 @@
373
437
  }
374
438
  }
375
439
  if (!hasClass(target, 'pika-select')) {
440
+ // if this is touch event prevent mouse events emulation
376
441
  if (e.preventDefault) {
377
442
  e.preventDefault();
378
443
  } else {
@@ -413,7 +478,9 @@
413
478
  else {
414
479
  date = new Date(Date.parse(opts.field.value));
415
480
  }
416
- self.setDate(isDate(date) ? date : null);
481
+ if (isDate(date)) {
482
+ self.setDate(date);
483
+ }
417
484
  if (!self._v) {
418
485
  self.show();
419
486
  }
@@ -431,6 +498,15 @@
431
498
 
432
499
  self._onInputBlur = function()
433
500
  {
501
+ // IE allows pika div to gain focus; catch blur the input field
502
+ var pEl = document.activeElement;
503
+ do {
504
+ if (hasClass(pEl, 'pika-single')) {
505
+ return;
506
+ }
507
+ }
508
+ while ((pEl = pEl.parentNode));
509
+
434
510
  if (!self._c) {
435
511
  self._b = sto(function() {
436
512
  self.hide();
@@ -454,24 +530,27 @@
454
530
  }
455
531
  }
456
532
  do {
457
- if (hasClass(pEl, 'pika-single')) {
533
+ if (hasClass(pEl, 'pika-single') || pEl === opts.trigger) {
458
534
  return;
459
535
  }
460
536
  }
461
537
  while ((pEl = pEl.parentNode));
462
- if (self._v && target !== opts.trigger) {
538
+ if (self._v && target !== opts.trigger && pEl !== opts.trigger) {
463
539
  self.hide();
464
540
  }
465
541
  };
466
542
 
467
543
  self.el = document.createElement('div');
468
- self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : '');
544
+ self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : '') + (opts.theme ? ' ' + opts.theme : '');
469
545
 
470
546
  addEvent(self.el, 'mousedown', self._onMouseDown, true);
547
+ addEvent(self.el, 'touchend', self._onMouseDown, true);
471
548
  addEvent(self.el, 'change', self._onChange);
472
549
 
473
550
  if (opts.field) {
474
- if (opts.bound) {
551
+ if (opts.container) {
552
+ opts.container.appendChild(self.el);
553
+ } else if (opts.bound) {
475
554
  document.body.appendChild(self.el);
476
555
  } else {
477
556
  opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling);
@@ -509,7 +588,6 @@
509
588
  } else {
510
589
  this.show();
511
590
  }
512
-
513
591
  };
514
592
 
515
593
 
@@ -534,10 +612,16 @@
534
612
 
535
613
  opts.field = (opts.field && opts.field.nodeName) ? opts.field : null;
536
614
 
615
+ opts.theme = (typeof opts.theme) === 'string' && opts.theme ? opts.theme : null;
616
+
537
617
  opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field);
538
618
 
539
619
  opts.trigger = (opts.trigger && opts.trigger.nodeName) ? opts.trigger : opts.field;
540
620
 
621
+ opts.disableWeekends = !!opts.disableWeekends;
622
+
623
+ opts.disableDayFn = (typeof opts.disableDayFn) === 'function' ? opts.disableDayFn : null;
624
+
541
625
  var nom = parseInt(opts.numberOfMonths, 10) || 1;
542
626
  opts.numberOfMonths = nom > 4 ? 4 : nom;
543
627
 
@@ -551,14 +635,10 @@
551
635
  opts.maxDate = opts.minDate = false;
552
636
  }
553
637
  if (opts.minDate) {
554
- setToStartOfDay(opts.minDate);
555
- opts.minYear = opts.minDate.getFullYear();
556
- opts.minMonth = opts.minDate.getMonth();
638
+ this.setMinDate(opts.minDate);
557
639
  }
558
640
  if (opts.maxDate) {
559
- setToStartOfDay(opts.maxDate);
560
- opts.maxYear = opts.maxDate.getFullYear();
561
- opts.maxMonth = opts.maxDate.getMonth();
641
+ this.setMaxDate(opts.maxDate);
562
642
  }
563
643
 
564
644
  if (isArray(opts.yearRange)) {
@@ -616,6 +696,12 @@
616
696
  {
617
697
  if (!date) {
618
698
  this._d = null;
699
+
700
+ if (this._o.field) {
701
+ this._o.field.value = '';
702
+ fireEvent(this._o.field, 'change', { firedBy: this });
703
+ }
704
+
619
705
  return this.draw();
620
706
  }
621
707
  if (typeof date === 'string') {
@@ -652,11 +738,43 @@
652
738
  */
653
739
  gotoDate: function(date)
654
740
  {
741
+ var newCalendar = true;
742
+
655
743
  if (!isDate(date)) {
656
744
  return;
657
745
  }
658
- this._y = date.getFullYear();
659
- this._m = date.getMonth();
746
+
747
+ if (this.calendars) {
748
+ var firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1),
749
+ lastVisibleDate = new Date(this.calendars[this.calendars.length-1].year, this.calendars[this.calendars.length-1].month, 1),
750
+ visibleDate = date.getTime();
751
+ // get the end of the month
752
+ lastVisibleDate.setMonth(lastVisibleDate.getMonth()+1);
753
+ lastVisibleDate.setDate(lastVisibleDate.getDate()-1);
754
+ newCalendar = (visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate);
755
+ }
756
+
757
+ if (newCalendar) {
758
+ this.calendars = [{
759
+ month: date.getMonth(),
760
+ year: date.getFullYear()
761
+ }];
762
+ if (this._o.mainCalendar === 'right') {
763
+ this.calendars[0].month += 1 - this._o.numberOfMonths;
764
+ }
765
+ }
766
+
767
+ this.adjustCalendars();
768
+ },
769
+
770
+ adjustCalendars: function() {
771
+ this.calendars[0] = adjustCalendar(this.calendars[0]);
772
+ for (var c = 1; c < this._o.numberOfMonths; c++) {
773
+ this.calendars[c] = adjustCalendar({
774
+ month: this.calendars[0].month + c,
775
+ year: this.calendars[0].year
776
+ });
777
+ }
660
778
  this.draw();
661
779
  },
662
780
 
@@ -670,28 +788,22 @@
670
788
  */
671
789
  gotoMonth: function(month)
672
790
  {
673
- if (!isNaN( (month = parseInt(month, 10)) )) {
674
- this._m = month < 0 ? 0 : month > 11 ? 11 : month;
675
- this.draw();
791
+ if (!isNaN(month)) {
792
+ this.calendars[0].month = parseInt(month, 10);
793
+ this.adjustCalendars();
676
794
  }
677
795
  },
678
796
 
679
797
  nextMonth: function()
680
798
  {
681
- if (++this._m > 11) {
682
- this._m = 0;
683
- this._y++;
684
- }
685
- this.draw();
799
+ this.calendars[0].month++;
800
+ this.adjustCalendars();
686
801
  },
687
802
 
688
803
  prevMonth: function()
689
804
  {
690
- if (--this._m < 0) {
691
- this._m = 11;
692
- this._y--;
693
- }
694
- this.draw();
805
+ this.calendars[0].month--;
806
+ this.adjustCalendars();
695
807
  },
696
808
 
697
809
  /**
@@ -700,8 +812,8 @@
700
812
  gotoYear: function(year)
701
813
  {
702
814
  if (!isNaN(year)) {
703
- this._y = parseInt(year, 10);
704
- this.draw();
815
+ this.calendars[0].year = parseInt(year, 10);
816
+ this.adjustCalendars();
705
817
  }
706
818
  },
707
819
 
@@ -710,7 +822,11 @@
710
822
  */
711
823
  setMinDate: function(value)
712
824
  {
825
+ setToStartOfDay(value);
713
826
  this._o.minDate = value;
827
+ this._o.minYear = value.getFullYear();
828
+ this._o.minMonth = value.getMonth();
829
+ this.draw();
714
830
  },
715
831
 
716
832
  /**
@@ -718,7 +834,21 @@
718
834
  */
719
835
  setMaxDate: function(value)
720
836
  {
837
+ setToStartOfDay(value);
721
838
  this._o.maxDate = value;
839
+ this._o.maxYear = value.getFullYear();
840
+ this._o.maxMonth = value.getMonth();
841
+ this.draw();
842
+ },
843
+
844
+ setStartRange: function(value)
845
+ {
846
+ this._o.startRange = value;
847
+ },
848
+
849
+ setEndRange: function(value)
850
+ {
851
+ this._o.endRange = value;
722
852
  },
723
853
 
724
854
  /**
@@ -733,7 +863,8 @@
733
863
  minYear = opts.minYear,
734
864
  maxYear = opts.maxYear,
735
865
  minMonth = opts.minMonth,
736
- maxMonth = opts.maxMonth;
866
+ maxMonth = opts.maxMonth,
867
+ html = '';
737
868
 
738
869
  if (this._y <= minYear) {
739
870
  this._y = minYear;
@@ -748,10 +879,13 @@
748
879
  }
749
880
  }
750
881
 
751
- this.el.innerHTML = renderTitle(this) + this.render(this._y, this._m);
882
+ for (var c = 0; c < opts.numberOfMonths; c++) {
883
+ html += '<div class="pika-lendar">' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year) + this.render(this.calendars[c].year, this.calendars[c].month) + '</div>';
884
+ }
885
+
886
+ this.el.innerHTML = html;
752
887
 
753
888
  if (opts.bound) {
754
- this.adjustPosition();
755
889
  if(opts.field.type !== 'hidden') {
756
890
  sto(function() {
757
891
  opts.trigger.focus();
@@ -769,12 +903,19 @@
769
903
 
770
904
  adjustPosition: function()
771
905
  {
772
- var field = this._o.trigger, pEl = field,
773
- width = this.el.offsetWidth, height = this.el.offsetHeight,
774
- viewportWidth = window.innerWidth || document.documentElement.clientWidth,
775
- viewportHeight = window.innerHeight || document.documentElement.clientHeight,
776
- scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop,
777
- left, top, clientRect;
906
+ var field, pEl, width, height, viewportWidth, viewportHeight, scrollTop, left, top, clientRect;
907
+
908
+ if (this._o.container) return;
909
+
910
+ this.el.style.position = 'absolute';
911
+
912
+ field = this._o.trigger;
913
+ pEl = field;
914
+ width = this.el.offsetWidth;
915
+ height = this.el.offsetHeight;
916
+ viewportWidth = window.innerWidth || document.documentElement.clientWidth;
917
+ viewportHeight = window.innerHeight || document.documentElement.clientHeight;
918
+ scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
778
919
 
779
920
  if (typeof field.getBoundingClientRect === 'function') {
780
921
  clientRect = field.getBoundingClientRect();
@@ -790,7 +931,7 @@
790
931
  }
791
932
 
792
933
  // default position is bottom & left
793
- if (left + width > viewportWidth ||
934
+ if ((this._o.reposition && left + width > viewportWidth) ||
794
935
  (
795
936
  this._o.position.indexOf('right') > -1 &&
796
937
  left - width + field.offsetWidth > 0
@@ -798,7 +939,7 @@
798
939
  ) {
799
940
  left = left - width + field.offsetWidth;
800
941
  }
801
- if (top + height > viewportHeight + scrollTop ||
942
+ if ((this._o.reposition && top + height > viewportHeight + scrollTop) ||
802
943
  (
803
944
  this._o.position.indexOf('top') > -1 &&
804
945
  top - height - field.offsetHeight > 0
@@ -806,11 +947,9 @@
806
947
  ) {
807
948
  top = top - height - field.offsetHeight;
808
949
  }
809
- this.el.style.cssText = [
810
- 'position: absolute',
811
- 'left: ' + left + 'px',
812
- 'top: ' + top + 'px'
813
- ].join(';');
950
+
951
+ this.el.style.left = left + 'px';
952
+ this.el.style.top = top + 'px';
814
953
  },
815
954
 
816
955
  /**
@@ -840,14 +979,35 @@
840
979
  for (var i = 0, r = 0; i < cells; i++)
841
980
  {
842
981
  var day = new Date(year, month, 1 + (i - before)),
843
- isDisabled = (opts.minDate && day < opts.minDate) || (opts.maxDate && day > opts.maxDate),
844
982
  isSelected = isDate(this._d) ? compareDates(day, this._d) : false,
845
983
  isToday = compareDates(day, now),
846
- isEmpty = i < before || i >= (days + before);
847
-
848
- row.push(renderDay(1 + (i - before), isSelected, isToday, isDisabled, isEmpty));
984
+ isEmpty = i < before || i >= (days + before),
985
+ isStartRange = opts.startRange && compareDates(opts.startRange, day),
986
+ isEndRange = opts.endRange && compareDates(opts.endRange, day),
987
+ isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange,
988
+ isDisabled = (opts.minDate && day < opts.minDate) ||
989
+ (opts.maxDate && day > opts.maxDate) ||
990
+ (opts.disableWeekends && isWeekend(day)) ||
991
+ (opts.disableDayFn && opts.disableDayFn(day)),
992
+ dayConfig = {
993
+ day: 1 + (i - before),
994
+ month: month,
995
+ year: year,
996
+ isSelected: isSelected,
997
+ isToday: isToday,
998
+ isDisabled: isDisabled,
999
+ isEmpty: isEmpty,
1000
+ isStartRange: isStartRange,
1001
+ isEndRange: isEndRange,
1002
+ isInRange: isInRange
1003
+ };
1004
+
1005
+ row.push(renderDay(dayConfig));
849
1006
 
850
1007
  if (++r === 7) {
1008
+ if (opts.showWeekNumber) {
1009
+ row.unshift(renderWeek(i - before, month, year));
1010
+ }
851
1011
  data.push(renderRow(row, opts.isRTL));
852
1012
  row = [];
853
1013
  r = 0;
@@ -864,12 +1024,13 @@
864
1024
  show: function()
865
1025
  {
866
1026
  if (!this._v) {
867
- if (this._o.bound) {
868
- addEvent(document, 'click', this._onClick);
869
- }
870
1027
  removeClass(this.el, 'is-hidden');
871
1028
  this._v = true;
872
1029
  this.draw();
1030
+ if (this._o.bound) {
1031
+ addEvent(document, 'click', this._onClick);
1032
+ this.adjustPosition();
1033
+ }
873
1034
  if (typeof this._o.onOpen === 'function') {
874
1035
  this._o.onOpen.call(this);
875
1036
  }
@@ -883,7 +1044,9 @@
883
1044
  if (this._o.bound) {
884
1045
  removeEvent(document, 'click', this._onClick);
885
1046
  }
886
- this.el.style.cssText = '';
1047
+ this.el.style.position = 'static'; // reset
1048
+ this.el.style.left = 'auto';
1049
+ this.el.style.top = 'auto';
887
1050
  addClass(this.el, 'is-hidden');
888
1051
  this._v = false;
889
1052
  if (v !== undefined && typeof this._o.onClose === 'function') {
@@ -899,6 +1062,7 @@
899
1062
  {
900
1063
  this.hide();
901
1064
  removeEvent(this.el, 'mousedown', this._onMouseDown, true);
1065
+ removeEvent(this.el, 'touchend', this._onMouseDown, true);
902
1066
  removeEvent(this.el, 'change', this._onChange);
903
1067
  if (this._o.field) {
904
1068
  removeEvent(this._o.field, 'change', this._onInputChange);
@@ -917,4 +1081,4 @@
917
1081
 
918
1082
  return Pikaday;
919
1083
 
920
- }));
1084
+ }));