xdan-datetimepicker-rails 2.5.1 → 2.5.2

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