xdan-datetimepicker-rails 2.5.1 → 2.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9a867af683c2455dd3321dfe62d7a6a1945d95d2
4
- data.tar.gz: a5da4cc1f13a6f9bddde28c2ad58eeb2b7191eac
3
+ metadata.gz: 6fa5d88e0e9e77c4a0da6c672756ab6e4372e4f1
4
+ data.tar.gz: 0068a2fcf276d60b31152e9c478dd95a45a72f3e
5
5
  SHA512:
6
- metadata.gz: 7abb6184db982b2360f7c36d808c616072472667a67a684fef22cb518c06d4ff2e6863a968f70dd2241fe9369d7706d2f2ae3f4f934dcd27eba257b967b59aa4
7
- data.tar.gz: ac6c99c6c5ed6722f1d381f1305915aeba076af451d0a51b9eac938bb4c533d0dc249ad4847fccd12ced4987b4a3722a13b03304eef3860a53b385d835d56898
6
+ metadata.gz: fa3b8d7a3e8b2ffca649611eec0718affe8b0c9c578c45c1d0a1f33d246388bf7a53e11a6c2b22a029daca022457bae7f461c024671765af5540aad85171beb8
7
+ data.tar.gz: 8e6104a5de360b644ef8995b2acd59a0319a6f0b9dc5177be5ee343b9a4f06621bb99ad83395c9cbe396538b99848f7675e7e039a2867ad6b6c4013fa9cb2b5b
@@ -575,7 +575,7 @@ var DateFormatter;
575
575
  }
576
576
  };
577
577
  })();/**
578
- * @preserve jQuery DateTimePicker plugin v2.4.9
578
+ * @preserve jQuery DateTimePicker plugin v2.5.1
579
579
  * @homepage http://xdsoft.net/jqplugins/datetimepicker/
580
580
  * @author Chupurnov Valeriy (<chupurnov@gmail.com>)
581
581
  */
@@ -1091,6 +1091,15 @@ var DateFormatter;
1091
1091
  "Dumengia", "Glindesdi", "Mardi", "Mesemna", "Gievgia", "Venderdi", "Sonda"
1092
1092
  ]
1093
1093
  },
1094
+ ka: { // Georgian
1095
+ months: [
1096
+ 'იანვარი', 'თებერვალი', 'მარტი', 'აპრილი', 'მაისი', 'ივნისი', 'ივლისი', 'აგვისტო', 'სექტემბერი', 'ოქტომბერი', 'ნოემბერი', 'დეკემბერი'
1097
+ ],
1098
+ dayOfWeekShort: [
1099
+ "კვ", "ორშ", "სამშ", "ოთხ", "ხუთ", "პარ", "შაბ"
1100
+ ],
1101
+ dayOfWeek: ["კვირა", "ორშაბათი", "სამშაბათი", "ოთხშაბათი", "ხუთშაბათი", "პარასკევი", "შაბათი"]
1102
+ },
1094
1103
  },
1095
1104
  value: '',
1096
1105
  rtl: false,
@@ -1180,31 +1189,31 @@ var DateFormatter;
1180
1189
  beforeShowDay: null,
1181
1190
 
1182
1191
  enterLikeTab: true,
1183
- showApplyButton: false
1192
+ showApplyButton: false
1184
1193
  };
1185
1194
 
1186
1195
  var dateHelper = null,
1187
1196
  globalLocaleDefault = 'en',
1188
1197
  globalLocale = 'en';
1189
-
1198
+
1190
1199
  var dateFormatterOptionsDefault = {
1191
1200
  meridiem: ['AM', 'PM']
1192
1201
  };
1193
-
1202
+
1194
1203
  var initDateFormatter = function(){
1195
1204
  var locale = default_options.i18n[globalLocale],
1196
1205
  opts = {
1197
1206
  days: locale.dayOfWeek,
1198
1207
  daysShort: locale.dayOfWeekShort,
1199
1208
  months: locale.months,
1200
- monthsShort: $.map(locale.months, function(n){ return n.substring(0, 3) }),
1209
+ monthsShort: $.map(locale.months, function(n){ return n.substring(0, 3) }),
1201
1210
  };
1202
-
1211
+
1203
1212
  dateHelper = new DateFormatter({
1204
1213
  dateSettings: $.extend({}, dateFormatterOptionsDefault, opts)
1205
1214
  });
1206
1215
  };
1207
-
1216
+
1208
1217
  // for locale settings
1209
1218
  $.datetimepicker = {
1210
1219
  setLocale: function(locale){
@@ -1215,6 +1224,9 @@ var DateFormatter;
1215
1224
  initDateFormatter();
1216
1225
  }
1217
1226
  },
1227
+ setDateFormatter: function(dateFormatter) {
1228
+ dateHelper = dateFormatter;
1229
+ },
1218
1230
  RFC_2822: 'D, d M Y H:i:s O',
1219
1231
  ATOM: 'Y-m-d\TH:i:sP',
1220
1232
  ISO_8601: 'Y-m-d\TH:i:sO',
@@ -1225,7 +1237,7 @@ var DateFormatter;
1225
1237
  RSS: 'D, d M Y H:i:s O',
1226
1238
  W3C: 'Y-m-d\TH:i:sP'
1227
1239
  };
1228
-
1240
+
1229
1241
  // first init date formatter
1230
1242
  initDateFormatter();
1231
1243
 
@@ -1276,7 +1288,6 @@ var DateFormatter;
1276
1288
  }
1277
1289
  return out;
1278
1290
  },
1279
- move = 0,
1280
1291
  timebox,
1281
1292
  parentHeight,
1282
1293
  height,
@@ -1346,7 +1357,7 @@ var DateFormatter;
1346
1357
  calcOffset(event);
1347
1358
  }
1348
1359
  })
1349
- .on('touchend touchcancel', function (event) {
1360
+ .on('touchend touchcancel', function () {
1350
1361
  touchStart = false;
1351
1362
  startTopScroll = 0;
1352
1363
  });
@@ -1408,7 +1419,7 @@ var DateFormatter;
1408
1419
  }
1409
1420
  });
1410
1421
 
1411
- timeboxparent.on('touchend touchcancel', function (event) {
1422
+ timeboxparent.on('touchend touchcancel', function () {
1412
1423
  start = false;
1413
1424
  startTop = 0;
1414
1425
  });
@@ -1419,7 +1430,7 @@ var DateFormatter;
1419
1430
 
1420
1431
  $.fn.datetimepicker = function (opt, opt2) {
1421
1432
  var result = this,
1422
- KEY0 = 48,
1433
+ KEY0 = 48,
1423
1434
  KEY9 = 57,
1424
1435
  _KEY0 = 96,
1425
1436
  _KEY9 = 105,
@@ -1448,7 +1459,7 @@ var DateFormatter;
1448
1459
 
1449
1460
  lazyInit = function (input) {
1450
1461
  input
1451
- .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function initOnActionCallback(event) {
1462
+ .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function initOnActionCallback() {
1452
1463
  if (input.is(':disabled') || input.data('xdsoft_datetimepicker')) {
1453
1464
  return;
1454
1465
  }
@@ -1477,20 +1488,20 @@ var DateFormatter;
1477
1488
  timepicker = $('<div class="xdsoft_timepicker active"><button type="button" class="xdsoft_prev"></button><div class="xdsoft_time_box"></div><button type="button" class="xdsoft_next"></button></div>'),
1478
1489
  timeboxparent = timepicker.find('.xdsoft_time_box').eq(0),
1479
1490
  timebox = $('<div class="xdsoft_time_variant"></div>'),
1480
- applyButton = $('<button type="button" class="xdsoft_save_selected blue-gradient-button">Save Selected</button>'),
1491
+ applyButton = $('<button type="button" class="xdsoft_save_selected blue-gradient-button">Save Selected</button>'),
1481
1492
 
1482
1493
  monthselect = $('<div class="xdsoft_select xdsoft_monthselect"><div></div></div>'),
1483
1494
  yearselect = $('<div class="xdsoft_select xdsoft_yearselect"><div></div></div>'),
1484
1495
  triggerAfterOpen = false,
1485
1496
  XDSoft_datetime,
1486
-
1497
+
1487
1498
  xchangeTimer,
1488
1499
  timerclick,
1489
1500
  current_time_index,
1490
1501
  setPos,
1491
1502
  timer = 0,
1492
- timer1 = 0,
1493
- _xdsoft_datetime;
1503
+ _xdsoft_datetime,
1504
+ forEachAncestorOf;
1494
1505
 
1495
1506
  if (options.id) {
1496
1507
  datetimepicker.attr('id', options.id);
@@ -1553,7 +1564,7 @@ var DateFormatter;
1553
1564
  event.stopPropagation();
1554
1565
  event.preventDefault();
1555
1566
  })
1556
- .on('touchstart mousedown.xdsoft', '.xdsoft_option', function (event) {
1567
+ .on('touchstart mousedown.xdsoft', '.xdsoft_option', function () {
1557
1568
  if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) {
1558
1569
  _xdsoft_datetime.currentTime = _xdsoft_datetime.now();
1559
1570
  }
@@ -1576,52 +1587,12 @@ var DateFormatter;
1576
1587
  });
1577
1588
 
1578
1589
  datetimepicker.getValue = function () {
1579
- return _xdsoft_datetime.getCurrentTime();
1580
- };
1590
+ return _xdsoft_datetime.getCurrentTime();
1591
+ };
1581
1592
 
1582
1593
  datetimepicker.setOptions = function (_options) {
1583
- var highlightedDates = {},
1584
- getCaretPos = function (input) {
1585
- try {
1586
- if (document.selection && document.selection.createRange) {
1587
- var range = document.selection.createRange();
1588
- return range.getBookmark().charCodeAt(2) - 2;
1589
- }
1590
- if (input.setSelectionRange) {
1591
- return input.selectionStart;
1592
- }
1593
- } catch (e) {
1594
- return 0;
1595
- }
1596
- },
1597
- setCaretPos = function (node, pos) {
1598
- node = (typeof node === "string" || node instanceof String) ? document.getElementById(node) : node;
1599
- if (!node) {
1600
- return false;
1601
- }
1602
- if (node.createTextRange) {
1603
- var textRange = node.createTextRange();
1604
- textRange.collapse(true);
1605
- textRange.moveEnd('character', pos);
1606
- textRange.moveStart('character', pos);
1607
- textRange.select();
1608
- return true;
1609
- }
1610
- if (node.setSelectionRange) {
1611
- node.setSelectionRange(pos, pos);
1612
- return true;
1613
- }
1614
- return false;
1615
- },
1616
- isValidValue = function (mask, value) {
1617
- var reg = mask
1618
- .replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g, '\\$1')
1619
- .replace(/_/g, '{digit+}')
1620
- .replace(/([0-9]{1})/g, '{digit$1}')
1621
- .replace(/\{digit([0-9]{1})\}/g, '[0-$1_]{1}')
1622
- .replace(/\{digit[\+]\}/g, '[0-9_]{1}');
1623
- return (new RegExp(reg)).test(value);
1624
- };
1594
+ var highlightedDates = {};
1595
+
1625
1596
  options = $.extend(true, {}, options, _options);
1626
1597
 
1627
1598
  if (_options.allowTimes && $.isArray(_options.allowTimes) && _options.allowTimes.length) {
@@ -1639,7 +1610,7 @@ var DateFormatter;
1639
1610
  if (_options.allowDateRe && Object.prototype.toString.call(_options.allowDateRe)==="[object String]") {
1640
1611
  options.allowDateRe = new RegExp(_options.allowDateRe);
1641
1612
  }
1642
-
1613
+
1643
1614
  if (_options.highlightedDates && $.isArray(_options.highlightedDates) && _options.highlightedDates.length) {
1644
1615
  $.each(_options.highlightedDates, function (index, value) {
1645
1616
  var splitData = $.map(value.split(','), $.trim),
@@ -1706,7 +1677,7 @@ var DateFormatter;
1706
1677
  }
1707
1678
 
1708
1679
  if (_options.disabledWeekDays && $.isArray(_options.disabledWeekDays) && _options.disabledWeekDays.length) {
1709
- options.disabledWeekDays = $.extend(true, [], _options.disabledWeekDays);
1680
+ options.disabledWeekDays = $.extend(true, [], _options.disabledWeekDays);
1710
1681
  }
1711
1682
 
1712
1683
  if ((options.open || options.opened) && (!options.inline)) {
@@ -1775,84 +1746,13 @@ var DateFormatter;
1775
1746
  .find('.' + options.next)
1776
1747
  .css('visibility', !options.nextButton ? 'hidden' : 'visible');
1777
1748
 
1778
- if (options.mask) {
1779
- input.off('keydown.xdsoft');
1780
-
1781
- if (options.mask === true) {
1782
- options.mask = options.format
1783
- .replace(/Y/g, '9999')
1784
- .replace(/F/g, '9999')
1785
- .replace(/m/g, '19')
1786
- .replace(/d/g, '39')
1787
- .replace(/H/g, '29')
1788
- .replace(/i/g, '59')
1789
- .replace(/s/g, '59');
1790
- }
1791
-
1792
- if ($.type(options.mask) === 'string') {
1793
- if (!isValidValue(options.mask, input.val())) {
1794
- input.val(options.mask.replace(/[0-9]/g, '_'));
1795
- setCaretPos(input[0], 0);
1796
- }
1797
-
1798
- input.on('keydown.xdsoft', function (event) {
1799
- var val = this.value,
1800
- key = event.which,
1801
- pos,
1802
- digit;
1749
+ setMask(options);
1803
1750
 
1804
- if (((key >= KEY0 && key <= KEY9) || (key >= _KEY0 && key <= _KEY9)) || (key === BACKSPACE || key === DEL)) {
1805
- pos = getCaretPos(this);
1806
- digit = (key !== BACKSPACE && key !== DEL) ? String.fromCharCode((_KEY0 <= key && key <= _KEY9) ? key - KEY0 : key) : '_';
1807
-
1808
- if ((key === BACKSPACE || key === DEL) && pos) {
1809
- pos -= 1;
1810
- digit = '_';
1811
- }
1812
-
1813
- while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
1814
- pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
1815
- }
1816
-
1817
- val = val.substr(0, pos) + digit + val.substr(pos + 1);
1818
- if ($.trim(val) === '') {
1819
- val = options.mask.replace(/[0-9]/g, '_');
1820
- } else {
1821
- if (pos === options.mask.length) {
1822
- event.preventDefault();
1823
- return false;
1824
- }
1825
- }
1826
-
1827
- pos += (key === BACKSPACE || key === DEL) ? 0 : 1;
1828
- while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
1829
- pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
1830
- }
1831
-
1832
- if (isValidValue(options.mask, val)) {
1833
- this.value = val;
1834
- setCaretPos(this, pos);
1835
- } else if ($.trim(val) === '') {
1836
- this.value = options.mask.replace(/[0-9]/g, '_');
1837
- } else {
1838
- input.trigger('error_input.xdsoft');
1839
- }
1840
- } else {
1841
- if (([AKEY, CKEY, VKEY, ZKEY, YKEY].indexOf(key) !== -1 && ctrlDown) || [ESC, ARROWUP, ARROWDOWN, ARROWLEFT, ARROWRIGHT, F5, CTRLKEY, TAB, ENTER].indexOf(key) !== -1) {
1842
- return true;
1843
- }
1844
- }
1845
-
1846
- event.preventDefault();
1847
- return false;
1848
- });
1849
- }
1850
- }
1851
1751
  if (options.validateOnBlur) {
1852
1752
  input
1853
1753
  .off('blur.xdsoft')
1854
1754
  .on('blur.xdsoft', function () {
1855
- if (options.allowBlank && !$.trim($(this).val()).length) {
1755
+ if (options.allowBlank && (!$.trim($(this).val()).length || (typeof options.mask == "string" && $.trim($(this).val()) === options.mask.replace(/[0-9]/g, '_')))) {
1856
1756
  $(this).val(null);
1857
1757
  datetimepicker.data('xdsoft_datetime').empty();
1858
1758
  } else if (!dateHelper.parseDate($(this).val(), options.format)) {
@@ -1874,6 +1774,7 @@ var DateFormatter;
1874
1774
  }
1875
1775
 
1876
1776
  datetimepicker.trigger('changedatetime.xdsoft');
1777
+ datetimepicker.trigger('close.xdsoft');
1877
1778
  });
1878
1779
  }
1879
1780
  options.dayOfWeekStartPrev = (options.dayOfWeekStart === 0) ? 6 : options.dayOfWeekStart - 1;
@@ -2095,12 +1996,12 @@ var DateFormatter;
2095
1996
  _xdsoft_datetime = new XDSoft_datetime();
2096
1997
 
2097
1998
  applyButton.on('touchend click', function (e) {//pathbrite
2098
- e.preventDefault();
2099
- datetimepicker.data('changed', true);
2100
- _xdsoft_datetime.setCurrentTime(getCurrentValue());
2101
- input.val(_xdsoft_datetime.str());
2102
- datetimepicker.trigger('close.xdsoft');
2103
- });
1999
+ e.preventDefault();
2000
+ datetimepicker.data('changed', true);
2001
+ _xdsoft_datetime.setCurrentTime(getCurrentValue());
2002
+ input.val(_xdsoft_datetime.str());
2003
+ datetimepicker.trigger('close.xdsoft');
2004
+ });
2104
2005
  mounth_picker
2105
2006
  .find('.xdsoft_today_button')
2106
2007
  .on('touchend mousedown.xdsoft', function () {
@@ -2167,7 +2068,20 @@ var DateFormatter;
2167
2068
  } else if ($this.hasClass(options.prev) && top - options.timeHeightInTimePicker >= 0) {
2168
2069
  timebox.css('marginTop', '-' + (top - options.timeHeightInTimePicker) + 'px');
2169
2070
  }
2170
- timeboxparent.trigger('scroll_element.xdsoft_scroller', [Math.abs(parseInt(timebox.css('marginTop'), 10) / (height - pheight))]);
2071
+ /**
2072
+ * Fixed bug:
2073
+ * When using css3 transition, it will cause a bug that you cannot scroll the timepicker list.
2074
+ * The reason is that the transition-duration time, if you set it to 0, all things fine, otherwise, this
2075
+ * would cause a bug when you use jquery.css method.
2076
+ * Let's say: * { transition: all .5s ease; }
2077
+ * jquery timebox.css('marginTop') will return the original value which is before you clicking the next/prev button,
2078
+ * meanwhile the timebox[0].style.marginTop will return the right value which is after you clicking the
2079
+ * next/prev button.
2080
+ *
2081
+ * What we should do:
2082
+ * Replace timebox.css('marginTop') with timebox[0].style.marginTop.
2083
+ */
2084
+ timeboxparent.trigger('scroll_element.xdsoft_scroller', [Math.abs(parseInt(timebox[0].style.marginTop, 10) / (height - pheight))]);
2171
2085
  period = (period > 10) ? 10 : period - 10;
2172
2086
  if (!stop) {
2173
2087
  timer = setTimeout(arguments_callee4, v || period);
@@ -2260,11 +2174,11 @@ var DateFormatter;
2260
2174
  }
2261
2175
 
2262
2176
  if(options.allowDateRe && Object.prototype.toString.call(options.allowDateRe) === "[object RegExp]"){
2263
- if(!options.allowDateRe.test(start.dateFormat(options.formatDate))){
2177
+ if(!options.allowDateRe.test(dateHelper.formatDate(start, options.formatDate))){
2264
2178
  classes.push('xdsoft_disabled');
2265
2179
  }
2266
2180
  } else if(options.allowDates && options.allowDates.length>0){
2267
- if(options.allowDates.indexOf(start.dateFormat(options.formatDate)) === -1){
2181
+ if(options.allowDates.indexOf(dateHelper.formatDate(start, options.formatDate)) === -1){
2268
2182
  classes.push('xdsoft_disabled');
2269
2183
  }
2270
2184
  } else if ((maxDate !== false && start > maxDate) || (minDate !== false && start < minDate) || (customDateSettings && customDateSettings[0] === false)) {
@@ -2272,7 +2186,9 @@ var DateFormatter;
2272
2186
  } else if (options.disabledDates.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) {
2273
2187
  classes.push('xdsoft_disabled');
2274
2188
  } else if (options.disabledWeekDays.indexOf(day) !== -1) {
2275
- classes.push('xdsoft_disabled');
2189
+ classes.push('xdsoft_disabled');
2190
+ }else if (input.is('[readonly]')) {
2191
+ classes.push('xdsoft_disabled');
2276
2192
  }
2277
2193
 
2278
2194
  if (customDateSettings && customDateSettings[1] !== "") {
@@ -2346,11 +2262,12 @@ var DateFormatter;
2346
2262
  optionDateTime = new Date(_xdsoft_datetime.currentTime);
2347
2263
  optionDateTime.setHours(h);
2348
2264
  optionDateTime.setMinutes(m);
2349
- classes = [];
2265
+ classes = [];
2350
2266
  if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || (options.maxTime !== false && _xdsoft_datetime.strtotime(options.maxTime).getTime() < now.getTime()) || (options.minTime !== false && _xdsoft_datetime.strtotime(options.minTime).getTime() > now.getTime())) {
2351
2267
  classes.push('xdsoft_disabled');
2352
- }
2353
- if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || ((options.disabledMinTime !== false && now.getTime() > _xdsoft_datetime.strtotime(options.disabledMinTime).getTime()) && (options.disabledMaxTime !== false && now.getTime() < _xdsoft_datetime.strtotime(options.disabledMaxTime).getTime()))) {
2268
+ } else if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || ((options.disabledMinTime !== false && now.getTime() > _xdsoft_datetime.strtotime(options.disabledMinTime).getTime()) && (options.disabledMaxTime !== false && now.getTime() < _xdsoft_datetime.strtotime(options.disabledMaxTime).getTime()))) {
2269
+ classes.push('xdsoft_disabled');
2270
+ } else if (input.is('[readonly]')) {
2354
2271
  classes.push('xdsoft_disabled');
2355
2272
  }
2356
2273
 
@@ -2504,7 +2421,6 @@ var DateFormatter;
2504
2421
  }
2505
2422
  });
2506
2423
 
2507
-
2508
2424
  datepicker
2509
2425
  .on('mousewheel.xdsoft', function (event) {
2510
2426
  if (!options.scrollMonth) {
@@ -2567,59 +2483,131 @@ var DateFormatter;
2567
2483
 
2568
2484
  current_time_index = 0;
2569
2485
 
2486
+ /**
2487
+ * Runs the callback for each of the specified node's ancestors.
2488
+ *
2489
+ * Return FALSE from the callback to stop ascending.
2490
+ *
2491
+ * @param {DOMNode} node
2492
+ * @param {Function} callback
2493
+ * @returns {undefined}
2494
+ */
2495
+ forEachAncestorOf = function (node, callback) {
2496
+ do {
2497
+ node = node.parentNode;
2498
+
2499
+ if (callback(node) === false) {
2500
+ break;
2501
+ }
2502
+ } while (node.nodeName !== 'HTML');
2503
+ };
2504
+
2505
+ /**
2506
+ * Sets the position of the picker.
2507
+ *
2508
+ * @returns {undefined}
2509
+ */
2570
2510
  setPos = function () {
2571
- /**
2572
- * 修复输入框在window最右边,且输入框的宽度小于日期控件宽度情况下,日期控件显示不全的bug。
2573
- * Bug fixed - The datetimepicker will overflow-y when the width of the date input less than its, which
2574
- * could causes part of the datetimepicker being hidden.
2575
- * by Soon start
2576
- */
2577
- var offset = datetimepicker.data('input').offset(),
2578
- datetimepickerelement = datetimepicker.data('input')[0],
2579
- top = offset.top + datetimepickerelement.offsetHeight - 1,
2580
- left = offset.left,
2581
- position = "absolute",
2582
- node;
2583
-
2584
- if ((document.documentElement.clientWidth - offset.left) < datepicker.parent().outerWidth(true)) {
2585
- var diff = datepicker.parent().outerWidth(true) - datetimepickerelement.offsetWidth;
2586
- left = left - diff;
2587
- }
2588
- /**
2589
- * by Soon end
2590
- */
2591
- if (datetimepicker.data('input').parent().css('direction') == 'rtl')
2592
- left -= (datetimepicker.outerWidth() - datetimepicker.data('input').outerWidth());
2511
+ var dateInputOffset,
2512
+ dateInputElem,
2513
+ verticalPosition,
2514
+ left,
2515
+ position,
2516
+ datetimepickerElem,
2517
+ dateInputHasFixedAncestor,
2518
+ $dateInput,
2519
+ windowWidth,
2520
+ verticalAnchorEdge,
2521
+ datetimepickerCss,
2522
+ windowHeight,
2523
+ windowScrollTop;
2524
+
2525
+ $dateInput = datetimepicker.data('input');
2526
+ dateInputOffset = $dateInput.offset();
2527
+ dateInputElem = $dateInput[0];
2528
+
2529
+ verticalAnchorEdge = 'top';
2530
+ verticalPosition = (dateInputOffset.top + dateInputElem.offsetHeight) - 1;
2531
+ left = dateInputOffset.left;
2532
+ position = "absolute";
2533
+
2534
+ windowWidth = $(window).width();
2535
+ windowHeight = $(window).height();
2536
+ windowScrollTop = $(window).scrollTop();
2537
+
2538
+ if ((document.documentElement.clientWidth - dateInputOffset.left) < datepicker.parent().outerWidth(true)) {
2539
+ var diff = datepicker.parent().outerWidth(true) - dateInputElem.offsetWidth;
2540
+ left = left - diff;
2541
+ }
2542
+
2543
+ if ($dateInput.parent().css('direction') === 'rtl') {
2544
+ left -= (datetimepicker.outerWidth() - $dateInput.outerWidth());
2545
+ }
2546
+
2593
2547
  if (options.fixed) {
2594
- top -= $(window).scrollTop();
2548
+ verticalPosition -= windowScrollTop;
2595
2549
  left -= $(window).scrollLeft();
2596
2550
  position = "fixed";
2597
2551
  } else {
2598
- if (top + datetimepickerelement.offsetHeight > $(window).height() + $(window).scrollTop()) {
2599
- top = offset.top - datetimepickerelement.offsetHeight + 1;
2552
+ dateInputHasFixedAncestor = false;
2553
+
2554
+ forEachAncestorOf(dateInputElem, function (ancestorNode) {
2555
+ if (window.getComputedStyle(ancestorNode).getPropertyValue('position') === 'fixed') {
2556
+ dateInputHasFixedAncestor = true;
2557
+ return false;
2558
+ }
2559
+ });
2560
+
2561
+ if (dateInputHasFixedAncestor) {
2562
+ position = 'fixed';
2563
+
2564
+ //If the picker won't fit entirely within the viewport then display it above the date input.
2565
+ if (verticalPosition + datetimepicker.outerHeight() > windowHeight + windowScrollTop) {
2566
+ verticalAnchorEdge = 'bottom';
2567
+ verticalPosition = (windowHeight + windowScrollTop) - dateInputOffset.top;
2568
+ } else {
2569
+ verticalPosition -= windowScrollTop;
2570
+ }
2571
+ } else {
2572
+ if (verticalPosition + dateInputElem.offsetHeight > windowHeight + windowScrollTop) {
2573
+ verticalPosition = dateInputOffset.top - dateInputElem.offsetHeight + 1;
2574
+ }
2600
2575
  }
2601
- if (top < 0) {
2602
- top = 0;
2576
+
2577
+ if (verticalPosition < 0) {
2578
+ verticalPosition = 0;
2603
2579
  }
2604
- if (left + datetimepickerelement.offsetWidth > $(window).width()) {
2605
- left = $(window).width() - datetimepickerelement.offsetWidth;
2580
+
2581
+ if (left + dateInputElem.offsetWidth > windowWidth) {
2582
+ left = windowWidth - dateInputElem.offsetWidth;
2606
2583
  }
2607
2584
  }
2608
2585
 
2609
- node = datetimepicker[0];
2610
- do {
2611
- node = node.parentNode;
2612
- if (window.getComputedStyle(node).getPropertyValue('position') === 'relative' && $(window).width() >= node.offsetWidth) {
2613
- left = left - (($(window).width() - node.offsetWidth) / 2);
2614
- break;
2586
+ datetimepickerElem = datetimepicker[0];
2587
+
2588
+ forEachAncestorOf(datetimepickerElem, function (ancestorNode) {
2589
+ var ancestorNodePosition;
2590
+
2591
+ ancestorNodePosition = window.getComputedStyle(ancestorNode).getPropertyValue('position');
2592
+
2593
+ if (ancestorNodePosition === 'relative' && windowWidth >= ancestorNode.offsetWidth) {
2594
+ left = left - ((windowWidth - ancestorNode.offsetWidth) / 2);
2595
+ return false;
2615
2596
  }
2616
- } while (node.nodeName !== 'HTML');
2617
- datetimepicker.css({
2618
- left: left,
2619
- top: top,
2620
- position: position
2621
2597
  });
2598
+
2599
+ datetimepickerCss = {
2600
+ position: position,
2601
+ left: left,
2602
+ top: '', //Initialize to prevent previous values interfering with new ones.
2603
+ bottom: '' //Initialize to prevent previous values interfering with new ones.
2604
+ };
2605
+
2606
+ datetimepickerCss[verticalAnchorEdge] = verticalPosition;
2607
+
2608
+ datetimepicker.css(datetimepickerCss);
2622
2609
  };
2610
+
2623
2611
  datetimepicker
2624
2612
  .on('open.xdsoft', function (event) {
2625
2613
  var onShow = true;
@@ -2655,7 +2643,7 @@ var DateFormatter;
2655
2643
  }
2656
2644
  event.stopPropagation();
2657
2645
  })
2658
- .on('toggle.xdsoft', function (event) {
2646
+ .on('toggle.xdsoft', function () {
2659
2647
  if (datetimepicker.is(':visible')) {
2660
2648
  datetimepicker.trigger('close.xdsoft');
2661
2649
  } else {
@@ -2665,7 +2653,6 @@ var DateFormatter;
2665
2653
  .data('input', input);
2666
2654
 
2667
2655
  timer = 0;
2668
- timer1 = 0;
2669
2656
 
2670
2657
  datetimepicker.data('xdsoft_datetime', _xdsoft_datetime);
2671
2658
  datetimepicker.setOptions(options);
@@ -2698,11 +2685,139 @@ var DateFormatter;
2698
2685
  return ct || 0;
2699
2686
  }
2700
2687
 
2688
+ function setMask(options) {
2689
+
2690
+ var isValidValue = function (mask, value) {
2691
+ var reg = mask
2692
+ .replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g, '\\$1')
2693
+ .replace(/_/g, '{digit+}')
2694
+ .replace(/([0-9]{1})/g, '{digit$1}')
2695
+ .replace(/\{digit([0-9]{1})\}/g, '[0-$1_]{1}')
2696
+ .replace(/\{digit[\+]\}/g, '[0-9_]{1}');
2697
+ return (new RegExp(reg)).test(value);
2698
+ },
2699
+ getCaretPos = function (input) {
2700
+ try {
2701
+ if (document.selection && document.selection.createRange) {
2702
+ var range = document.selection.createRange();
2703
+ return range.getBookmark().charCodeAt(2) - 2;
2704
+ }
2705
+ if (input.setSelectionRange) {
2706
+ return input.selectionStart;
2707
+ }
2708
+ } catch (e) {
2709
+ return 0;
2710
+ }
2711
+ },
2712
+ setCaretPos = function (node, pos) {
2713
+ node = (typeof node === "string" || node instanceof String) ? document.getElementById(node) : node;
2714
+ if (!node) {
2715
+ return false;
2716
+ }
2717
+ if (node.createTextRange) {
2718
+ var textRange = node.createTextRange();
2719
+ textRange.collapse(true);
2720
+ textRange.moveEnd('character', pos);
2721
+ textRange.moveStart('character', pos);
2722
+ textRange.select();
2723
+ return true;
2724
+ }
2725
+ if (node.setSelectionRange) {
2726
+ node.setSelectionRange(pos, pos);
2727
+ return true;
2728
+ }
2729
+ return false;
2730
+ };
2731
+ if(options.mask) {
2732
+ input.off('keydown.xdsoft');
2733
+ }
2734
+ if (options.mask === true) {
2735
+ if (typeof moment != 'undefined') {
2736
+ options.mask = options.format
2737
+ .replace(/Y{4}/g, '9999')
2738
+ .replace(/Y{2}/g, '99')
2739
+ .replace(/M{2}/g, '19')
2740
+ .replace(/D{2}/g, '39')
2741
+ .replace(/H{2}/g, '29')
2742
+ .replace(/m{2}/g, '59')
2743
+ .replace(/s{2}/g, '59');
2744
+ } else {
2745
+ options.mask = options.format
2746
+ .replace(/Y/g, '9999')
2747
+ .replace(/F/g, '9999')
2748
+ .replace(/m/g, '19')
2749
+ .replace(/d/g, '39')
2750
+ .replace(/H/g, '29')
2751
+ .replace(/i/g, '59')
2752
+ .replace(/s/g, '59');
2753
+ }
2754
+ }
2755
+
2756
+ if ($.type(options.mask) === 'string') {
2757
+ if (!isValidValue(options.mask, input.val())) {
2758
+ input.val(options.mask.replace(/[0-9]/g, '_'));
2759
+ setCaretPos(input[0], 0);
2760
+ }
2761
+
2762
+ input.on('keydown.xdsoft', function (event) {
2763
+ var val = this.value,
2764
+ key = event.which,
2765
+ pos,
2766
+ digit;
2767
+
2768
+ if (((key >= KEY0 && key <= KEY9) || (key >= _KEY0 && key <= _KEY9)) || (key === BACKSPACE || key === DEL)) {
2769
+ pos = getCaretPos(this);
2770
+ digit = (key !== BACKSPACE && key !== DEL) ? String.fromCharCode((_KEY0 <= key && key <= _KEY9) ? key - KEY0 : key) : '_';
2771
+
2772
+ if ((key === BACKSPACE || key === DEL) && pos) {
2773
+ pos -= 1;
2774
+ digit = '_';
2775
+ }
2776
+
2777
+ while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
2778
+ pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
2779
+ }
2780
+
2781
+ val = val.substr(0, pos) + digit + val.substr(pos + 1);
2782
+ if ($.trim(val) === '') {
2783
+ val = options.mask.replace(/[0-9]/g, '_');
2784
+ } else {
2785
+ if (pos === options.mask.length) {
2786
+ event.preventDefault();
2787
+ return false;
2788
+ }
2789
+ }
2790
+
2791
+ pos += (key === BACKSPACE || key === DEL) ? 0 : 1;
2792
+ while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
2793
+ pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
2794
+ }
2795
+
2796
+ if (isValidValue(options.mask, val)) {
2797
+ this.value = val;
2798
+ setCaretPos(this, pos);
2799
+ } else if ($.trim(val) === '') {
2800
+ this.value = options.mask.replace(/[0-9]/g, '_');
2801
+ } else {
2802
+ input.trigger('error_input.xdsoft');
2803
+ }
2804
+ } else {
2805
+ if (([AKEY, CKEY, VKEY, ZKEY, YKEY].indexOf(key) !== -1 && ctrlDown) || [ESC, ARROWUP, ARROWDOWN, ARROWLEFT, ARROWRIGHT, F5, CTRLKEY, TAB, ENTER].indexOf(key) !== -1) {
2806
+ return true;
2807
+ }
2808
+ }
2809
+
2810
+ event.preventDefault();
2811
+ return false;
2812
+ });
2813
+ }
2814
+ }
2815
+
2701
2816
  _xdsoft_datetime.setCurrentTime(getCurrentValue());
2702
2817
 
2703
2818
  input
2704
2819
  .data('xdsoft_datetimepicker', datetimepicker)
2705
- .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function (event) {
2820
+ .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function () {
2706
2821
  if (input.is(':disabled') || (input.data('xdsoft_datetimepicker').is(':visible') && options.closeOnInputClick)) {
2707
2822
  return;
2708
2823
  }
@@ -2714,12 +2829,14 @@ var DateFormatter;
2714
2829
 
2715
2830
  triggerAfterOpen = true;
2716
2831
  _xdsoft_datetime.setCurrentTime(getCurrentValue());
2717
-
2832
+ if(options.mask) {
2833
+ setMask(options);
2834
+ }
2718
2835
  datetimepicker.trigger('open.xdsoft');
2719
2836
  }, 100);
2720
2837
  })
2721
2838
  .on('keydown.xdsoft', function (event) {
2722
- var val = this.value, elementSelector,
2839
+ var elementSelector,
2723
2840
  key = event.which;
2724
2841
  if ([ENTER].indexOf(key) !== -1 && options.enterLikeTab) {
2725
2842
  elementSelector = $("input:visible,textarea:visible,button:visible,a:visible");
@@ -2731,6 +2848,9 @@ var DateFormatter;
2731
2848
  datetimepicker.trigger('close.xdsoft');
2732
2849
  return true;
2733
2850
  }
2851
+ })
2852
+ .on('blur.xdsoft', function () {
2853
+ datetimepicker.trigger('close.xdsoft');
2734
2854
  });
2735
2855
  };
2736
2856
  destroyDateTimePicker = function (input) {
@@ -2760,8 +2880,8 @@ var DateFormatter;
2760
2880
  ctrlDown = false;
2761
2881
  }
2762
2882
  });
2763
-
2764
- this.each(function () {
2883
+
2884
+ this.each(function () {
2765
2885
  var datetimepicker = $(this).data('xdsoft_datetimepicker'), $input;
2766
2886
  if (datetimepicker) {
2767
2887
  if ($.type(opt) === 'string') {
@@ -2790,10 +2910,10 @@ var DateFormatter;
2790
2910
  $input = datetimepicker.data('input');
2791
2911
  $input.trigger('blur.xdsoft');
2792
2912
  break;
2793
- default:
2794
- if (datetimepicker[opt] && $.isFunction(datetimepicker[opt])) {
2795
- result = datetimepicker[opt](opt2);
2796
- }
2913
+ default:
2914
+ if (datetimepicker[opt] && $.isFunction(datetimepicker[opt])) {
2915
+ result = datetimepicker[opt](opt2);
2916
+ }
2797
2917
  }
2798
2918
  } else {
2799
2919
  datetimepicker
@@ -2810,8 +2930,9 @@ var DateFormatter;
2810
2930
  }
2811
2931
  });
2812
2932
 
2813
- return result;
2933
+ return result;
2814
2934
  };
2935
+
2815
2936
  $.fn.datetimepicker.defaults = default_options;
2816
2937
 
2817
2938
  function HighlightedDate(date, desc, style) {
@@ -2820,7 +2941,6 @@ var DateFormatter;
2820
2941
  this.desc = desc;
2821
2942
  this.style = style;
2822
2943
  }
2823
-
2824
2944
  }));
2825
2945
  /*!
2826
2946
  * jQuery Mousewheel 3.1.13