mobiscroll.datetimebase.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792
  1. (function ($, undefined) {
  2. var ms = $.mobiscroll,
  3. datetime = ms.datetime,
  4. date = new Date(),
  5. defaults = {
  6. startYear: date.getFullYear() - 100,
  7. endYear: date.getFullYear() + 1,
  8. separator: ' ',
  9. // Localization
  10. dateFormat: 'mm/dd/yy',
  11. dateOrder: 'mmddy',
  12. timeWheels: 'hhiiA',
  13. timeFormat: 'hh:ii A',
  14. dayText: 'Day',
  15. monthText: 'Month',
  16. yearText: 'Year',
  17. hourText: 'Hours',
  18. minuteText: 'Minutes',
  19. ampmText: ' ',
  20. secText: 'Seconds',
  21. nowText: 'Now'
  22. },
  23. /**
  24. * @class Mobiscroll.datetime
  25. * @extends Mobiscroll
  26. * Mobiscroll Datetime component
  27. */
  28. preset = function (inst) {
  29. var that = $(this),
  30. html5def = {},
  31. format;
  32. // Force format for html5 date inputs (experimental)
  33. if (that.is('input')) {
  34. switch (that.attr('type')) {
  35. case 'date':
  36. format = 'yy-mm-dd';
  37. break;
  38. case 'datetime':
  39. format = 'yy-mm-ddTHH:ii:ssZ';
  40. break;
  41. case 'datetime-local':
  42. format = 'yy-mm-ddTHH:ii:ss';
  43. break;
  44. case 'month':
  45. format = 'yy-mm';
  46. html5def.dateOrder = 'mmyy';
  47. break;
  48. case 'time':
  49. format = 'HH:ii:ss';
  50. break;
  51. }
  52. // Check for min/max attributes
  53. var min = that.attr('min'),
  54. max = that.attr('max');
  55. if (min) {
  56. html5def.minDate = datetime.parseDate(format, min);
  57. }
  58. if (max) {
  59. html5def.maxDate = datetime.parseDate(format, max);
  60. }
  61. }
  62. // Set year-month-day order
  63. var i,
  64. k,
  65. keys,
  66. values,
  67. wg,
  68. start,
  69. end,
  70. hasTime,
  71. mins,
  72. maxs,
  73. orig = $.extend({}, inst.settings),
  74. s = $.extend(inst.settings, ms.datetime.defaults, defaults, html5def, orig),
  75. offset = 0,
  76. validValues = [],
  77. wheels = [],
  78. ord = [],
  79. o = {},
  80. innerValues = {},
  81. f = { y: getYear, m: getMonth, d: getDay, h: getHour, i: getMinute, s: getSecond, u: getMillisecond, a: getAmPm },
  82. invalid = s.invalid,
  83. valid = s.valid,
  84. p = s.preset,
  85. dord = s.dateOrder,
  86. tord = s.timeWheels,
  87. regen = dord.match(/D/),
  88. ampm = tord.match(/a/i),
  89. hampm = tord.match(/h/),
  90. hformat = p == 'datetime' ? s.dateFormat + s.separator + s.timeFormat : p == 'time' ? s.timeFormat : s.dateFormat,
  91. defd = new Date(),
  92. steps = s.steps || {},
  93. stepH = steps.hour || s.stepHour || 1,
  94. stepM = steps.minute || s.stepMinute || 1,
  95. stepS = steps.second || s.stepSecond || 1,
  96. zeroBased = steps.zeroBased,
  97. mind = s.minDate || new Date(s.startYear, 0, 1),
  98. maxd = s.maxDate || new Date(s.endYear, 11, 31, 23, 59, 59),
  99. minH = zeroBased ? 0 : mind.getHours() % stepH,
  100. minM = zeroBased ? 0 : mind.getMinutes() % stepM,
  101. minS = zeroBased ? 0 : mind.getSeconds() % stepS,
  102. maxH = getMax(stepH, minH, (hampm ? 11 : 23)),
  103. maxM = getMax(stepM, minM, 59),
  104. maxS = getMax(stepM, minM, 59);
  105. format = format || hformat;
  106. if (p.match(/date/i)) {
  107. // Determine the order of year, month, day wheels
  108. $.each(['y', 'm', 'd'], function (j, v) {
  109. i = dord.search(new RegExp(v, 'i'));
  110. if (i > -1) {
  111. ord.push({ o: i, v: v });
  112. }
  113. });
  114. ord.sort(function (a, b) { return a.o > b.o ? 1 : -1; });
  115. $.each(ord, function (i, v) {
  116. o[v.v] = i;
  117. });
  118. wg = [];
  119. for (k = 0; k < 3; k++) {
  120. if (k == o.y) {
  121. offset++;
  122. values = [];
  123. keys = [];
  124. start = s.getYear(mind);
  125. end = s.getYear(maxd);
  126. for (i = start; i <= end; i++) {
  127. keys.push(i);
  128. values.push((dord.match(/yy/i) ? i : (i + '').substr(2, 2)) + (s.yearSuffix || ''));
  129. }
  130. addWheel(wg, keys, values, s.yearText);
  131. } else if (k == o.m) {
  132. offset++;
  133. values = [];
  134. keys = [];
  135. for (i = 0; i < 12; i++) {
  136. var str = dord.replace(/[dy]/gi, '').replace(/mm/, (i < 9 ? '0' + (i + 1) : i + 1) + (s.monthSuffix || '')).replace(/m/, i + 1 + (s.monthSuffix || ''));
  137. keys.push(i);
  138. values.push(str.match(/MM/) ? str.replace(/MM/, '<span class="dw-mon">' + s.monthNames[i] + '</span>') : str.replace(/M/, '<span class="dw-mon">' + s.monthNamesShort[i] + '</span>'));
  139. }
  140. addWheel(wg, keys, values, s.monthText);
  141. } else if (k == o.d) {
  142. offset++;
  143. values = [];
  144. keys = [];
  145. for (i = 1; i < 32; i++) {
  146. keys.push(i);
  147. values.push((dord.match(/dd/i) && i < 10 ? '0' + i : i) + (s.daySuffix || ''));
  148. }
  149. addWheel(wg, keys, values, s.dayText);
  150. }
  151. }
  152. wheels.push(wg);
  153. }
  154. if (p.match(/time/i)) {
  155. hasTime = true;
  156. // Determine the order of hours, minutes, seconds wheels
  157. ord = [];
  158. $.each(['h', 'i', 's', 'a'], function (i, v) {
  159. i = tord.search(new RegExp(v, 'i'));
  160. if (i > -1) {
  161. ord.push({ o: i, v: v });
  162. }
  163. });
  164. ord.sort(function (a, b) {
  165. return a.o > b.o ? 1 : -1;
  166. });
  167. $.each(ord, function (i, v) {
  168. o[v.v] = offset + i;
  169. });
  170. wg = [];
  171. for (k = offset; k < offset + 4; k++) {
  172. if (k == o.h) {
  173. offset++;
  174. values = [];
  175. keys = [];
  176. for (i = minH; i < (hampm ? 12 : 24); i += stepH) {
  177. keys.push(i);
  178. values.push(hampm && i === 0 ? 12 : tord.match(/hh/i) && i < 10 ? '0' + i : i);
  179. }
  180. addWheel(wg, keys, values, s.hourText);
  181. } else if (k == o.i) {
  182. offset++;
  183. values = [];
  184. keys = [];
  185. for (i = minM; i < 60; i += stepM) {
  186. keys.push(i);
  187. values.push(tord.match(/ii/) && i < 10 ? '0' + i : i);
  188. }
  189. addWheel(wg, keys, values, s.minuteText);
  190. } else if (k == o.s) {
  191. offset++;
  192. values = [];
  193. keys = [];
  194. for (i = minS; i < 60; i += stepS) {
  195. keys.push(i);
  196. values.push(tord.match(/ss/) && i < 10 ? '0' + i : i);
  197. }
  198. addWheel(wg, keys, values, s.secText);
  199. } else if (k == o.a) {
  200. offset++;
  201. var upper = tord.match(/A/);
  202. addWheel(wg, [0, 1], upper ? [s.amText.toUpperCase(), s.pmText.toUpperCase()] : [s.amText, s.pmText], s.ampmText);
  203. }
  204. }
  205. wheels.push(wg);
  206. }
  207. function get(d, i, def) {
  208. if (o[i] !== undefined) {
  209. return +d[o[i]];
  210. }
  211. if (innerValues[i] !== undefined) {
  212. return innerValues[i];
  213. }
  214. if (def !== undefined) {
  215. return def;
  216. }
  217. return f[i](defd);
  218. }
  219. function addWheel(wg, k, v, lbl) {
  220. wg.push({
  221. values: v,
  222. keys: k,
  223. label: lbl
  224. });
  225. }
  226. function step(v, st, min, max) {
  227. return Math.min(max, Math.floor(v / st) * st + min);
  228. }
  229. function getYear(d) {
  230. return s.getYear(d);
  231. }
  232. function getMonth(d) {
  233. return s.getMonth(d);
  234. }
  235. function getDay(d) {
  236. return s.getDay(d);
  237. }
  238. function getHour(d) {
  239. var hour = d.getHours();
  240. hour = hampm && hour >= 12 ? hour - 12 : hour;
  241. return step(hour, stepH, minH, maxH);
  242. }
  243. function getMinute(d) {
  244. return step(d.getMinutes(), stepM, minM, maxM);
  245. }
  246. function getSecond(d) {
  247. return step(d.getSeconds(), stepS, minS, maxS);
  248. }
  249. function getMillisecond(d) {
  250. return d.getMilliseconds();
  251. }
  252. function getAmPm(d) {
  253. return ampm && d.getHours() > 11 ? 1 : 0;
  254. }
  255. function getDate(d) {
  256. if (d === null) {
  257. return d;
  258. }
  259. var year = get(d, 'y'),
  260. month = get(d, 'm'),
  261. day = Math.min(get(d, 'd', 1), s.getMaxDayOfMonth(year, month)),
  262. hour = get(d, 'h', 0);
  263. return s.getDate(year, month, day, get(d, 'a', 0) ? hour + 12 : hour, get(d, 'i', 0), get(d, 's', 0), get(d, 'u', 0));
  264. }
  265. function getMax(step, min, max) {
  266. return Math.floor((max - min) / step) * step + min;
  267. }
  268. function getClosestValidDate(d, dir) {
  269. var next,
  270. prev,
  271. nextValid = false,
  272. prevValid = false,
  273. up = 0,
  274. down = 0;
  275. // Normalize min and max dates for comparing later (set default values where there are no values from wheels)
  276. mind = getDate(getArray(mind));
  277. maxd = getDate(getArray(maxd));
  278. if (isValid(d)) {
  279. return d;
  280. }
  281. if (d < mind) {
  282. d = mind;
  283. }
  284. if (d > maxd) {
  285. d = maxd;
  286. }
  287. next = d;
  288. prev = d;
  289. if (dir !== 2) {
  290. nextValid = isValid(next);
  291. while (!nextValid && next < maxd) {
  292. next = new Date(next.getTime() + 1000 * 60 * 60 * 24);
  293. nextValid = isValid(next);
  294. up++;
  295. }
  296. }
  297. if (dir !== 1) {
  298. prevValid = isValid(prev);
  299. while (!prevValid && prev > mind) {
  300. prev = new Date(prev.getTime() - 1000 * 60 * 60 * 24);
  301. prevValid = isValid(prev);
  302. down++;
  303. }
  304. }
  305. if (dir === 1 && nextValid) {
  306. return next;
  307. }
  308. if (dir === 2 && prevValid) {
  309. return prev;
  310. }
  311. return down <= up && prevValid ? prev : next;
  312. }
  313. function isValid(d) {
  314. if (d < mind) {
  315. return false;
  316. }
  317. if (d > maxd) {
  318. return false;
  319. }
  320. if (isInObj(d, valid)) {
  321. return true;
  322. }
  323. if (isInObj(d, invalid)) {
  324. return false;
  325. }
  326. return true;
  327. }
  328. function isInObj(d, obj) {
  329. var curr,
  330. j,
  331. v;
  332. if (obj) {
  333. for (j = 0; j < obj.length; j++) {
  334. curr = obj[j];
  335. v = curr + '';
  336. if (!curr.start) {
  337. if (curr.getTime) { // Exact date
  338. if (d.getFullYear() == curr.getFullYear() && d.getMonth() == curr.getMonth() && d.getDate() == curr.getDate()) {
  339. return true;
  340. }
  341. } else if (!v.match(/w/i)) { // Day of month
  342. v = v.split('/');
  343. if (v[1]) {
  344. if ((v[0] - 1) == d.getMonth() && v[1] == d.getDate()) {
  345. return true;
  346. }
  347. } else if (v[0] == d.getDate()) {
  348. return true;
  349. }
  350. } else { // Day of week
  351. v = +v.replace('w', '');
  352. if (v == d.getDay()) {
  353. return true;
  354. }
  355. }
  356. }
  357. }
  358. }
  359. return false;
  360. }
  361. function validateDates(obj, y, m, first, maxdays, idx, val) {
  362. var j, d, v;
  363. if (obj) {
  364. for (j = 0; j < obj.length; j++) {
  365. d = obj[j];
  366. v = d + '';
  367. if (!d.start) {
  368. if (d.getTime) { // Exact date
  369. if (s.getYear(d) == y && s.getMonth(d) == m) {
  370. idx[s.getDay(d) - 1] = val;
  371. }
  372. } else if (!v.match(/w/i)) { // Day of month
  373. v = v.split('/');
  374. if (v[1]) {
  375. if (v[0] - 1 == m) {
  376. idx[v[1] - 1] = val;
  377. }
  378. } else {
  379. idx[v[0] - 1] = val;
  380. }
  381. } else { // Day of week
  382. v = +v.replace('w', '');
  383. for (k = v - first; k < maxdays; k += 7) {
  384. if (k >= 0) {
  385. idx[k] = val;
  386. }
  387. }
  388. }
  389. }
  390. }
  391. }
  392. }
  393. function validateTimes(vobj, i, v, temp, y, m, d, target, valid) {
  394. var dd, ss, str, parts1, parts2, prop1, prop2, v1, v2, j, i1, i2, add, remove, all, hours1, hours2, hours3,
  395. spec = {},
  396. steps = { h: stepH, i: stepM, s: stepS, a: 1 },
  397. day = s.getDate(y, m, d),
  398. w = ['a', 'h', 'i', 's'];
  399. if (vobj) {
  400. $.each(vobj, function (i, obj) {
  401. if (obj.start) {
  402. obj.apply = false;
  403. dd = obj.d;
  404. ss = dd + '';
  405. str = ss.split('/');
  406. if (dd && ((dd.getTime && y == s.getYear(dd) && m == s.getMonth(dd) && d == s.getDay(dd)) || // Exact date
  407. (!ss.match(/w/i) && ((str[1] && d == str[1] && m == str[0] - 1) || (!str[1] && d == str[0]))) || // Day of month
  408. (ss.match(/w/i) && day.getDay() == +ss.replace('w', '')) // Day of week
  409. )) {
  410. obj.apply = true;
  411. spec[day] = true; // Prevent applying generic rule on day, if specific exists
  412. }
  413. }
  414. });
  415. $.each(vobj, function (x, obj) {
  416. add = 0;
  417. remove = 0;
  418. i1 = 0;
  419. i2 = undefined;
  420. prop1 = true;
  421. prop2 = true;
  422. all = false;
  423. if (obj.start && (obj.apply || (!obj.d && !spec[day]))) {
  424. // Define time parts
  425. parts1 = obj.start.split(':');
  426. parts2 = obj.end.split(':');
  427. for (j = 0; j < 3; j++) {
  428. if (parts1[j] === undefined) {
  429. parts1[j] = 0;
  430. }
  431. if (parts2[j] === undefined) {
  432. parts2[j] = 59;
  433. }
  434. parts1[j] = +parts1[j];
  435. parts2[j] = +parts2[j];
  436. }
  437. parts1.unshift(parts1[0] > 11 ? 1 : 0);
  438. parts2.unshift(parts2[0] > 11 ? 1 : 0);
  439. if (hampm) {
  440. if (parts1[1] >= 12) {
  441. parts1[1] = parts1[1] - 12;
  442. }
  443. if (parts2[1] >= 12) {
  444. parts2[1] = parts2[1] - 12;
  445. }
  446. }
  447. // Look behind
  448. for (j = 0; j < i; j++) {
  449. if (validValues[j] !== undefined) {
  450. v1 = step(parts1[j], steps[w[j]], mins[w[j]], maxs[w[j]]);
  451. v2 = step(parts2[j], steps[w[j]], mins[w[j]], maxs[w[j]]);
  452. hours1 = 0;
  453. hours2 = 0;
  454. hours3 = 0;
  455. if (hampm && j == 1) {
  456. hours1 = parts1[0] ? 12 : 0;
  457. hours2 = parts2[0] ? 12 : 0;
  458. hours3 = validValues[0] ? 12 : 0;
  459. }
  460. if (!prop1) {
  461. v1 = 0;
  462. }
  463. if (!prop2) {
  464. v2 = maxs[w[j]];
  465. }
  466. if ((prop1 || prop2) && (v1 + hours1 < validValues[j] + hours3 && validValues[j] + hours3 < v2 + hours2)) {
  467. all = true;
  468. }
  469. if (validValues[j] != v1) {
  470. prop1 = false;
  471. }
  472. if (validValues[j] != v2) {
  473. prop2 = false;
  474. }
  475. }
  476. }
  477. // Look ahead
  478. if (!valid) {
  479. for (j = i + 1; j < 4; j++) {
  480. if (parts1[j] > 0) {
  481. add = steps[v];
  482. }
  483. if (parts2[j] < maxs[w[j]]) {
  484. remove = steps[v];
  485. }
  486. }
  487. }
  488. if (!all) {
  489. // Calculate min and max values
  490. v1 = step(parts1[i], steps[v], mins[v], maxs[v]) + add;
  491. v2 = step(parts2[i], steps[v], mins[v], maxs[v]) - remove;
  492. if (prop1) {
  493. i1 = getValidIndex(target, v1, maxs[v], 0);
  494. }
  495. if (prop2) {
  496. i2 = getValidIndex(target, v2, maxs[v], 1);
  497. }
  498. }
  499. // Disable values
  500. if (prop1 || prop2 || all) {
  501. if (valid) {
  502. $('.dw-li', target).slice(i1, i2).addClass('dw-v');
  503. } else {
  504. $('.dw-li', target).slice(i1, i2).removeClass('dw-v');
  505. }
  506. }
  507. }
  508. });
  509. }
  510. }
  511. function getIndex(t, v) {
  512. return $('.dw-li', t).index($('.dw-li[data-val="' + v + '"]', t));
  513. }
  514. function getValidIndex(t, v, max, add) {
  515. if (v < 0) {
  516. return 0;
  517. }
  518. if (v > max) {
  519. return $('.dw-li', t).length;
  520. }
  521. return getIndex(t, v) + add;
  522. }
  523. function getArray(d, fillInner) {
  524. var ret = [];
  525. if (d === null || d === undefined) {
  526. return d;
  527. }
  528. $.each(['y', 'm', 'd', 'a', 'h', 'i', 's', 'u'], function (x, i) {
  529. if (o[i] !== undefined) {
  530. ret[o[i]] = f[i](d);
  531. }
  532. if (fillInner) {
  533. innerValues[i] = f[i](d);
  534. }
  535. });
  536. return ret;
  537. }
  538. function convertRanges(arr) {
  539. var i, v, start,
  540. ret = [];
  541. if (arr) {
  542. for (i = 0; i < arr.length; i++) {
  543. v = arr[i];
  544. if (v.start && v.start.getTime) {
  545. start = new Date(v.start);
  546. while (start <= v.end) {
  547. ret.push(new Date(start.getFullYear(), start.getMonth(), start.getDate()));
  548. start.setDate(start.getDate() + 1);
  549. }
  550. } else {
  551. ret.push(v);
  552. }
  553. }
  554. return ret;
  555. }
  556. return arr;
  557. }
  558. // Extended methods
  559. // ---
  560. inst.getVal = function (temp) {
  561. return inst._hasValue || temp ? getDate(inst.getArrayVal(temp)) : null;
  562. };
  563. /**
  564. * Sets the selected date
  565. *
  566. * @param {Date} d Date to select.
  567. * @param {Boolean} [fill=false] Also set the value of the associated input element. Default is true.
  568. * @param {Number} [time=0] Animation time to scroll to the selected date.
  569. * @param {Boolean} [temp=false] Set temporary value only.
  570. * @param {Boolean} [change=fill] Trigger change on input element.
  571. */
  572. inst.setDate = function (d, fill, time, temp, change) {
  573. inst.setArrayVal(getArray(d), fill, change, temp, time);
  574. };
  575. /**
  576. * Returns the selected date.
  577. *
  578. * @param {Boolean} [temp=false] If true, return the currently shown date on the picker, otherwise the last selected one.
  579. * @return {Date}
  580. */
  581. inst.getDate = inst.getVal;
  582. // ---
  583. // Initializations
  584. // ---
  585. inst.format = hformat;
  586. inst.order = o;
  587. inst.handlers.now = function () { inst.setDate(new Date(), false, 0.3, true, true); };
  588. inst.buttons.now = { text: s.nowText, handler: 'now' };
  589. invalid = convertRanges(invalid);
  590. valid = convertRanges(valid);
  591. mins = { y: mind.getFullYear(), m: 0, d: 1, h: minH, i: minM, s: minS, a: 0 };
  592. maxs = { y: maxd.getFullYear(), m: 11, d: 31, h: maxH, i: maxM, s: maxS, a: 1 };
  593. // ---
  594. return {
  595. wheels: wheels,
  596. headerText: s.headerText ? function () {
  597. return datetime.formatDate(hformat, getDate(inst.getArrayVal(true)), s);
  598. } : false,
  599. formatValue: function (d) {
  600. return datetime.formatDate(format, getDate(d), s);
  601. },
  602. parseValue: function (val) {
  603. if (!val) {
  604. innerValues = {};
  605. }
  606. return getArray(val ? datetime.parseDate(format, val, s) : (s.defaultValue || new Date()), !!val && !!val.getTime);
  607. },
  608. validate: function (dw, i, time, dir) {
  609. var validated = getClosestValidDate(getDate(inst.getArrayVal(true)), dir),
  610. temp = getArray(validated),
  611. y = get(temp, 'y'),
  612. m = get(temp, 'm'),
  613. minprop = true,
  614. maxprop = true;
  615. $.each(['y', 'm', 'd', 'a', 'h', 'i', 's'], function (x, i) {
  616. if (o[i] !== undefined) {
  617. var min = mins[i],
  618. max = maxs[i],
  619. maxdays = 31,
  620. val = get(temp, i),
  621. t = $('.dw-ul', dw).eq(o[i]);
  622. if (i == 'd') {
  623. maxdays = s.getMaxDayOfMonth(y, m);
  624. max = maxdays;
  625. if (regen) {
  626. $('.dw-li', t).each(function () {
  627. var that = $(this),
  628. d = that.data('val'),
  629. w = s.getDate(y, m, d).getDay(),
  630. str = dord.replace(/[my]/gi, '').replace(/dd/, (d < 10 ? '0' + d : d) + (s.daySuffix || '')).replace(/d/, d + (s.daySuffix || ''));
  631. $('.dw-i', that).html(str.match(/DD/) ? str.replace(/DD/, '<span class="dw-day">' + s.dayNames[w] + '</span>') : str.replace(/D/, '<span class="dw-day">' + s.dayNamesShort[w] + '</span>'));
  632. });
  633. }
  634. }
  635. if (minprop && mind) {
  636. min = f[i](mind);
  637. }
  638. if (maxprop && maxd) {
  639. max = f[i](maxd);
  640. }
  641. if (i != 'y') {
  642. var i1 = getIndex(t, min),
  643. i2 = getIndex(t, max);
  644. $('.dw-li', t).removeClass('dw-v').slice(i1, i2 + 1).addClass('dw-v');
  645. if (i == 'd') { // Hide days not in month
  646. $('.dw-li', t).removeClass('dw-h').slice(maxdays).addClass('dw-h');
  647. }
  648. }
  649. if (val < min) {
  650. val = min;
  651. }
  652. if (val > max) {
  653. val = max;
  654. }
  655. if (minprop) {
  656. minprop = val == min;
  657. }
  658. if (maxprop) {
  659. maxprop = val == max;
  660. }
  661. // Disable some days
  662. if (i == 'd') {
  663. var first = s.getDate(y, m, 1).getDay(),
  664. idx = {};
  665. // Set invalid indexes
  666. validateDates(invalid, y, m, first, maxdays, idx, 1);
  667. // Delete indexes which are valid
  668. validateDates(valid, y, m, first, maxdays, idx, 0);
  669. $.each(idx, function (i, v) {
  670. if (v) {
  671. $('.dw-li', t).eq(i).removeClass('dw-v');
  672. }
  673. });
  674. }
  675. }
  676. });
  677. // Invalid times
  678. if (hasTime) {
  679. $.each(['a', 'h', 'i', 's'], function (i, v) {
  680. var val = get(temp, v),
  681. d = get(temp, 'd'),
  682. t = $('.dw-ul', dw).eq(o[v]);
  683. if (o[v] !== undefined) {
  684. validateTimes(invalid, i, v, temp, y, m, d, t, 0);
  685. validateTimes(valid, i, v, temp, y, m, d, t, 1);
  686. // Get valid value
  687. validValues[i] = +inst.getValidCell(val, t, dir).val;
  688. }
  689. });
  690. }
  691. inst._tempWheelArray = temp;
  692. }
  693. };
  694. };
  695. $.each(['date', 'time', 'datetime'], function (i, v) {
  696. ms.presets.scroller[v] = preset;
  697. });
  698. })(jQuery);