1/* customDatepicker v4.5.2, @license MIT */ 2(function (global, factory) { 3 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 4 typeof define === 'function' && define.amd ? define(factory) : 5 (global.customDatepicker = factory()); 6}(this, (function () { 'use strict'; 7 8 var pad = function pad(number) { 9 return ("0" + number).slice(-2); 10 }; 11 var int = function int(bool) { 12 return bool === true ? 1 : 0; 13 }; 14 function debounce(func, wait, immediate) { 15 if (immediate === void 0) { 16 immediate = false; 17 } 18 19 var timeout; 20 return function () { 21 var context = this, 22 args = arguments; 23 timeout !== null && clearTimeout(timeout); 24 timeout = window.setTimeout(function () { 25 timeout = null; 26 if (!immediate) func.apply(context, args); 27 }, wait); 28 if (immediate && !timeout) func.apply(context, args); 29 }; 30 } 31 var arrayify = function arrayify(obj) { 32 return obj instanceof Array ? obj : [obj]; 33 }; 34 35 var do_nothing = function do_nothing() { 36 return undefined; 37 }; 38 39 var monthToStr = function monthToStr(monthNumber, shorthand, locale) { 40 return locale.months[shorthand ? "shorthand" : "longhand"][monthNumber]; 41 }; 42 var revFormat = { 43 D: do_nothing, 44 F: function F(dateObj, monthName, locale) { 45 dateObj.setMonth(locale.months.longhand.indexOf(monthName)); 46 }, 47 G: function G(dateObj, hour) { 48 dateObj.setHours(parseFloat(hour)); 49 }, 50 H: function H(dateObj, hour) { 51 dateObj.setHours(parseFloat(hour)); 52 }, 53 J: function J(dateObj, day) { 54 dateObj.setDate(parseFloat(day)); 55 }, 56 K: function K(dateObj, amPM, locale) { 57 dateObj.setHours(dateObj.getHours() % 12 + 12 * int(new RegExp(locale.amPM[1], "i").test(amPM))); 58 }, 59 M: function M(dateObj, shortMonth, locale) { 60 dateObj.setMonth(locale.months.shorthand.indexOf(shortMonth)); 61 }, 62 S: function S(dateObj, seconds) { 63 dateObj.setSeconds(parseFloat(seconds)); 64 }, 65 U: function U(_, unixSeconds) { 66 return new Date(parseFloat(unixSeconds) * 1000); 67 }, 68 W: function W(dateObj, weekNum) { 69 var weekNumber = parseInt(weekNum); 70 return new Date(dateObj.getFullYear(), 0, 2 + (weekNumber - 1) * 7, 0, 0, 0, 0); 71 }, 72 Y: function Y(dateObj, year) { 73 dateObj.setFullYear(parseFloat(year)); 74 }, 75 Z: function Z(_, ISODate) { 76 return new Date(ISODate); 77 }, 78 d: function d(dateObj, day) { 79 dateObj.setDate(parseFloat(day)); 80 }, 81 h: function h(dateObj, hour) { 82 dateObj.setHours(parseFloat(hour)); 83 }, 84 i: function i(dateObj, minutes) { 85 dateObj.setMinutes(parseFloat(minutes)); 86 }, 87 j: function j(dateObj, day) { 88 dateObj.setDate(parseFloat(day)); 89 }, 90 l: do_nothing, 91 m: function m(dateObj, month) { 92 dateObj.setMonth(parseFloat(month) - 1); 93 }, 94 n: function n(dateObj, month) { 95 dateObj.setMonth(parseFloat(month) - 1); 96 }, 97 s: function s(dateObj, seconds) { 98 dateObj.setSeconds(parseFloat(seconds)); 99 }, 100 w: do_nothing, 101 y: function y(dateObj, year) { 102 dateObj.setFullYear(2000 + parseFloat(year)); 103 } 104 }; 105 var tokenRegex = { 106 D: "(\\w+)", 107 F: "(\\w+)", 108 G: "(\\d\\d|\\d)", 109 H: "(\\d\\d|\\d)", 110 J: "(\\d\\d|\\d)\\w+", 111 K: "", 112 M: "(\\w+)", 113 S: "(\\d\\d|\\d)", 114 U: "(.+)", 115 W: "(\\d\\d|\\d)", 116 Y: "(\\d{4})", 117 Z: "(.+)", 118 d: "(\\d\\d|\\d)", 119 h: "(\\d\\d|\\d)", 120 i: "(\\d\\d|\\d)", 121 j: "(\\d\\d|\\d)", 122 l: "(\\w+)", 123 m: "(\\d\\d|\\d)", 124 n: "(\\d\\d|\\d)", 125 s: "(\\d\\d|\\d)", 126 w: "(\\d\\d|\\d)", 127 y: "(\\d{2})" 128 }; 129 var formats = { 130 Z: function Z(date) { 131 return date.toISOString(); 132 }, 133 D: function D(date, locale, options) { 134 return locale.weekdays.shorthand[formats.w(date, locale, options)]; 135 }, 136 F: function F(date, locale, options) { 137 return monthToStr(formats.n(date, locale, options) - 1, false, locale); 138 }, 139 G: function G(date, locale, options) { 140 return pad(formats.h(date, locale, options)); 141 }, 142 H: function H(date) { 143 return pad(date.getHours()); 144 },
145 J: function J(date, locale) { 146 return locale.ordinal !== undefined ? date.getDate() + locale.ordinal(date.getDate()) : date.getDate(); 147 }, 148 K: function K(date, locale) { 149 return locale.amPM[int(date.getHours() > 11)]; 150 }, 151 M: function M(date, locale) { 152 return monthToStr(date.getMonth(), true, locale); 153 }, 154 S: function S(date) { 155 return pad(date.getSeconds()); 156 }, 157 U: function U(date) { 158 return date.getTime() / 1000; 159 }, 160 W: function W(date, _, options) { 161 return options.getWeek(date); 162 }, 163 Y: function Y(date) { 164 return date.getFullYear(); 165 }, 166 d: function d(date) { 167 return pad(date.getDate()); 168 }, 169 h: function h(date) { 170 return date.getHours() % 12 ? date.getHours() % 12 : 12; 171 }, 172 i: function i(date) { 173 return pad(date.getMinutes()); 174 }, 175 j: function j(date) { 176 return date.getDate(); 177 }, 178 l: function l(date, locale) { 179 return locale.weekdays.longhand[date.getDay()]; 180 }, 181 m: function m(date) { 182 return pad(date.getMonth() + 1); 183 }, 184 n: function n(date) { 185 return date.getMonth() + 1; 186 }, 187 s: function s(date) { 188 return date.getSeconds(); 189 }, 190 w: function w(date) { 191 return date.getDay(); 192 }, 193 y: function y(date) { 194 return String(date.getFullYear()).substring(2); 195 } 196 }; 197 198 var english = { 199 weekdays: { 200 shorthand: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], 201 longhand: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] 202 }, 203 months: { 204 shorthand: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], 205 longhand: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
205November", "December"] 206 }, 207 daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], 208 firstDayOfWeek: 0, 209 ordinal: function ordinal(nth) { 210 var s = nth % 100; 211 if (s > 3 && s < 21) return "th"; 212 213 switch (s % 10) { 214 case 1: 215 return "st"; 216 217 case 2: 218 return "nd"; 219 220 case 3: 221 return "rd"; 222 223 default: 224 return "th"; 225 } 226 }, 227 rangeSeparator: " to ", 228 weekAbbreviation: "Wk", 229 scrollTitle: "Scroll to increment", 230 toggleTitle: "Click to toggle", 231 amPM: ["AM", "PM"], 232 yearAriaLabel: "Year" 233 }; 234 235 var createDateFormatter = function createDateFormatter(_ref) { 236 var _ref$config = _ref.config, 237 config = _ref$config === void 0 ? defaults : _ref$config, 238 _ref$l10n = _ref.l10n, 239 l10n = _ref$l10n === void 0 ? english : _ref$l10n; 240 return function (dateObj, frmt, overrideLocale) { 241 var locale = overrideLocale || l10n; 242 243 if (config.formatDate !== undefined) { 244 return config.formatDate(dateObj, frmt, locale); 245 } 246 247 return frmt.split("").map(function (c, i, arr) { 248 return formats[c] && arr[i - 1] !== "\\" ? formats[c](dateObj, locale, config) : c !== "\\" ? c : ""; 249 }).join(""); 250 }; 251 }; 252 var createDateParser = function createDateParser(_ref2) { 253 var _ref2$config = _ref2.config, 254 config = _ref2$config === void 0 ? defaults : _ref2$config, 255 _ref2$l10n = _ref2.l10n, 256 l10n = _ref2$l10n === void 0 ? english : _ref2$l10n; 257 return function (date, givenFormat, timeless, customLocale) { 258 if (date !== 0 && !date) return undefined; 259 var locale = customLocale || l10n; 260 var parsedDate; 261 var date_orig = date; 262 if (date instanceof Date) parsedDate = new Date(date.getTime());else if (typeof date !== "string" && date.toFixed !== undefined) parsedDate = new Date(date);else if (typeof date === "string") { 263 var format = givenFormat || (config || defaults).dateFormat; 264 var datestr = String(date).trim(); 265 266 if (datestr === "today") { 267 parsedDate = new Date(); 268 timeless = true; 269 } else if (/Z$/.test(datestr) || /GMT$/.test(datestr)) parsedDate = new Date(date);else if (config && config.parseDate) parsedDate = config.parseDate(date, format);else { 270 parsedDate = !config || !config.noCalendar ? new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0) : new Date(new Date().setHours(0, 0, 0, 0)); 271 var matched, 272 ops = []; 273 274 for (var i = 0, matchIndex = 0, regexStr = ""; i < format.length; i++) { 275 var token = format[i]; 276 var isBackSlash = token === "\\"; 277 var escaped = format[i - 1] === "\\" || isBackSlash; 278 279 if (tokenRegex[token] && !escaped) { 280 regexStr += tokenRegex[token]; 281 var match = new RegExp(regexStr).exec(date); 282 283 if (match && (matched = true)) { 284 ops[token !== "Y" ? "push" : "unshift"]({ 285 fn: revFormat[token], 286 val: match[++matchIndex] 287 }); 288 } 289 } else if (!isBackSlash) regexStr += "."; 290 291 ops.forEach(function (_ref3) { 292 var fn = _ref3.fn, 293 val = _ref3.val; 294 return parsedDate = fn(parsedDate, val, locale) || parsedDate; 295 }); 296 } 297 298 parsedDate = matched ? parsedDate : undefined; 299 } 300 } 301 302 if (!(parsedDate instanceof Date && !isNaN(parsedDate.getTime()))) { 303 config.errorHandler(new Error("Invalid date provided: " + date_orig)); 304 return undefined; 305 } 306 307 if (timeless === true) parsedDate.setHours(0, 0, 0, 0); 308 return parsedDate; 309 }; 310 }; 311 function compareDates(date1, date2, timeless) { 312 if (timeless === void 0) { 313 timeless = true; 314 } 315 316 if (timeless !== false) { 317 return new Date(date1.getTime()).setHours(0, 0, 0, 0) - new Date(date2.getTime()).setHours(0, 0, 0, 0); 318 } 319 320 return date1.getTime() - date2.getTime(); 321 } 322 var getWeek = function getWeek(givenDate) { 323 var date = new Date(givenDate.getTime()); 324 date.setHours(0, 0, 0, 0); 325 date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7); 326 var week1 = new Date(date.getFullYear(), 0, 4); 327 return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7); 328 }; 329 var isBetween = function isBetween(ts, ts1, ts2) { 330 return ts > Math.min(ts1, ts2) && ts < Math.max(ts1, ts2); 331 }; 332 var duration = { 333 DAY: 86400000 334 }; 335 336 var HOOKS = ["onChange", "onClose", "onDayCreate", "onDestroy", "onKeyDown", "onMonthChange", "onOpen", "onParseConfig", "onReady", "onValueUpdate", "onYearChange", "onPreCalendarPosition"]; 337 var defaults = { 338 _disable: [], 339 _enable: [], 340 allowInput: false, 341 altFormat: "F j, Y", 342 altInput: false, 343 altInputClass: "form-control input", 344 animate: typeof window === "object" && window.navigator.userAgent.indexOf("MSIE") === -1, 345 ariaDateFormat: "F j, Y", 346 clickOpens: true, 347 closeOnSelect: true, 348 conjunction: ", ", 349 dateFormat: "Y-m-d", 350 defaultHour: 12, 351 defaultMinute: 0, 352 defaultSeconds: 0, 353 disable: [], 354 disableMobile: false, 355 enable: [], 356 enableSeconds: false, 357 enableTime: false, 358 errorHandler: function errorHandler(err) { 359 return typeof console !== "undefined" && console.warn(err); 360 }, 361 getWeek: getWeek, 362 hourIncrement: 1, 363 ignoredFocusElements: [], 364 inline: false, 365 locale: "default", 366 minuteIncrement: 5, 367 mode: "single", 368 nextArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewB
368ox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>", 369 noCalendar: false, 370 now: new Date(), 371 onChange: [], 372 onClose: [], 373 onDayCreate: [], 374 onDestroy: [], 375 onKeyDown: [], 376 onMonthChange: [], 377 onOpen: [], 378 onParseConfig: [], 379 onReady: [], 380 onValueUpdate: [], 381 onYearChange: [], 382 onPreCalendarPosition: [], 383 plugins: [], 384 position: "auto", 385 positionElement: undefined, 386 prevArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>", 387 shorthandCurrentMonth: false, 388 showMonths: 1, 389 static: false, 390 time_24hr: false, 391 weekNumbers: false, 392 wrap: false 393 }; 394 395 function toggleClass(elem, className, bool) { 396 if (bool === true) return elem.classList.add(className); 397 elem.classList.remove(className); 398 } 399 function createElement(tag, className, content) { 400 var e = window.document.createElement(tag); 401 className = className || ""; 402 content = content || ""; 403 e.className = className; 404 if (content !== undefined) e.textContent = content; 405 return e; 406 } 407 function clearNode(node) { 408 while (node.firstChild) { 409 node.removeChild(node.firstChild); 410 } 411 } 412 function findParent(node, condition) { 413 if (condition(node)) return node;else if (node.parentNode) return findParent(node.parentNode, condition); 414 return undefined; 415 } 416 function createNumberInput(inputClassName, opts) { 417 var wrapper = createElement("div", "numInputWrapper"), 418 numInput = createElement("input", "numInput " + inputClassName), 419 arrowUp = createElement("span", "arrowUp"), 420 arrowDown = createElement("span", "arrowDown"); 421 numInput.type = "text"; 422 numInput.pattern = "\\d*"; 423 if (opts !== undefined) for (var key in opts) { 424 numInput.setAttribute(key, opts[key]); 425 } 426 wrapper.appendChild(numInput); 427 wrapper.appendChild(arrowUp); 428 wrapper.appendChild(arrowDown); 429 return wrapper; 430 } 431 432 if (typeof Object.assign !== "function") { 433 Object.assign = function (target) { 434 if (!target) { 435 throw TypeError("Cannot convert undefined or null to object"); 436 } 437 438 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 439 args[_key - 1] = arguments[_key]; 440 } 441 442 var _loop = function _loop() { 443 var source = args[_i]; 444 445 if (source) { 446 Object.keys(source).forEach(function (key) { 447 return target[key] = source[key]; 448 }); 449 } 450 }; 451 452 for (var _i = 0; _i < args.length; _i++) { 453 _loop(); 454 } 455 456 return target; 457 }; 458 } 459 460 var DEBOUNCED_CHANGE_MS = 300; 461 462 function FlatpickrInstance(element, instanceConfig) { 463 var self = { 464 config: Object.assign({}, customDatepicker.defaultConfig), 465 l10n: english 466 }; 467 self.parseDate = createDateParser({ 468 config: self.config, 469 l10n: self.l10n 470 }); 471 self._handlers = []; 472 self._bind = bind; 473 self._setHoursFromDate = setHoursFromDate; 474 self._positionCalendar = positionCalendar; 475 self.changeMonth = changeMonth; 476 self.changeYear = changeYear; 477 self.clear = clear; 478 self.close = close; 479 self._createElement = createElement; 480 self.destroy = destroy; 481 self.isEnabled = isEnabled; 482 self.jumpToDate = jumpToDate; 483 self.open = open; 484 self.redraw = redraw; 485 self.set = set; 486 self.setDate = setDate; 487 self.toggle = toggle; 488 489 function setupHelperFunctions() { 490 self.utils = { 491 getDaysInMonth: function getDaysInMonth(month, yr) { 492 if (month === void 0) { 493 month = self.currentMonth; 494 } 495 496 if (yr === void 0) { 497 yr = self.currentYear; 498 } 499 500 if (month === 1 && (yr % 4 === 0 && yr % 100 !== 0 || yr % 400 === 0)) return 29; 501 return self.l10n.daysInMonth[month]; 502 } 503 }; 504 } 505
506 function init() { 507 self.element = self.input = element; 508 self.isOpen = false; 509 parseConfig(); 510 setupLocale(); 511 setupInputs(); 512 setupDates(); 513 setupHelperFunctions(); 514 if (!self.isMobile) build(); 515 bindEvents(); 516 517 if (self.selectedDates.length || self.config.noCalendar) { 518 if (self.config.enableTime) { 519 setHoursFromDate(self.config.noCalendar ? self.latestSelectedDateObj || self.config.minDate : undefined); 520 } 521 522 updateValue(false); 523 } 524 525 setCalendarWidth(); 526 self.showTimeInput = self.selectedDates.length > 0 || self.config.noCalendar; 527 var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); 528 529 if (!self.isMobile && isSafari) { 530 positionCalendar(); 531 } 532 533 triggerEvent("onReady"); 534 } 535 536 function bindToInstance(fn) { 537 return fn.bind(self); 538 } 539 540 function setCalendarWidth() { 541 var config = self.config; 542 if (config.weekNumbers === false && config.showMonths === 1) return;else if (config.noCalendar !== true) { 543 window.requestAnimationFrame(function () { 544 self.calendarContainer.style.visibility = "hidden"; 545 self.calendarContainer.style.display = "block"; 546 547 if (self.daysContainer !== undefined) { 548 var daysWidth = (self.days.offsetWidth + 1) * config.showMonths; 549 self.daysContainer.style.width = daysWidth + "px"; 550 self.calendarContainer.style.width = daysWidth + (self.weekWrapper !== undefined ? self.weekWrapper.offsetWidth : 0) + "px"; 551 self.calendarContainer.style.removeProperty("visibility"); 552 self.calendarContainer.style.removeProperty("display"); 553 } 554 }); 555 } 556 } 557 558 function updateTime(e) { 559 if (self.selectedDates.length === 0) return; 560 561 if (e !== undefined && e.type !== "blur") { 562 timeWrapper(e); 563 } 564 565 var prevValue = self._input.value; 566 setHoursFromInputs(); 567 updateValue(); 568 569 if (self._input.value !== prevValue) { 570 self._debouncedChange(); 571 } 572 } 573 574 function ampm2military(hour, amPM) { 575 return hour % 12 + 12 * int(amPM === self.l10n.amPM[1]); 576 } 577 578 function military2ampm(hour) { 579 switch (hour % 24) { 580 case 0: 581 case 12: 582 return 12; 583 584 default: 585 return hour % 12; 586 } 587 } 588 589 function setHoursFromInputs() { 590 if (self.hourElement === undefined || self.minuteElement === undefined) return; 591 var hours = (parseInt(self.hourElement.value.slice(-2), 10) || 0) % 24, 592 minutes = (parseInt(self.minuteElement.value, 10) || 0) % 60, 593 seconds = self.secondElement !== undefined ? (parseInt(self.secondElement.value, 10) || 0) % 60 : 0; 594 595 if (self.amPM !== undefined) { 596 hours = ampm2military(hours, self.amPM.textContent); 597 } 598 599 var limitMinHours = self.config.minTime !== undefined || self.config.minDate && self.minDateHasTime && self.latestSelectedDateObj && compareDates(self.latestSelectedDateObj, self.config.minDate, true) === 0; 600 var limitMaxHours = self.config.maxTime !== undefined || self.config.maxDate && self.maxDateHasTime && self.latestSelectedDateObj && compareDates(self.latestSelectedDateObj, self.config.maxDate, true) === 0; 601 602 if (limitMaxHours) { 603 var maxTime = self.config.maxTime !== undefined ? self.config.maxTime : self.config.maxDate; 604 hours = Math.min(hours, maxTime.getHours()); 605 if (hours === maxTime.getHours()) minutes = Math.min(minutes, maxTime.getMinutes()); 606 if (minutes === maxTime.getMinutes()) seconds = Math.min(seconds, maxTime.getSeconds()); 607 } 608 609 if (limitMinHours) { 610 var minTime = self.config.minTime !== undefined ? self.config.minTime : self.config.minDate; 611 hours = Math.max(hours, minTime.getHours()); 612 if (hours === minTime.getHours()) minutes = Math.max(minutes, minTime.getMinutes()); 613 if (minutes === minTime.getMinutes()) seconds = Math.max(seconds, minTime.getSeconds()); 614 } 615 616 setHours(hours, minutes, seconds); 617 } 618 619 function setHoursFromDate(dateObj) { 620 var date = dateObj || self.latestSelectedDateObj; 621 if (date) setHours(date.getHours(), date.getMinutes(), date.getSeconds()); 622 } 623 624 function setDefaultHours() { 625 var hours = self.config.defaultHour; 626 var minutes = self.config.defaultMinute; 627 var seconds = self.config.defaultSeconds; 628 629 if (self.config.minDate !== undefined) { 630 var min_hr = self.config.minDate.getHours(); 631 var min_minutes = self.config.minDate.getMinutes(); 632 hours = Math.max(hours, min_hr); 633 if (hours === min_hr) minutes = Math.max(min_minutes, minutes); 634 if (hours === min_hr && minutes === min_minutes) seconds = self.config.minDate.getSeconds(); 635 } 636 637 if (self.config.maxDate !== undefined) { 638 var max_hr = self.config.maxDate.getHours(); 639 var max_minutes = self.config.maxDate.getMinutes(); 640 hours = Math.min(hours, max_hr); 641 if (hours === max_hr) minutes = Math.min(max_minutes, minutes); 642 if (hours === max_hr && minutes === max_minutes) seconds = self.config.maxDate.getSeconds(); 643 } 644 645 setHours(hours, minutes, seconds); 646 } 647 648 function setHours(hours, minutes, seconds) { 649 if (self.latestSelectedDateObj !== undefined) { 650 self.latestSelectedDateObj.setHours(hours % 24, minutes, seconds || 0, 0); 651 } 652 653 if (!self.hourElement || !self.minuteElement || self.isMobile) return; 654 self.hourElement.value = pad(!self.config.time_24hr ? (12 + hours) % 12 + 12 * int(hours % 12 === 0) : hours); 655 self.minuteElement.value = pad(minutes); 656 if (self.amPM !== undefined) self.amPM.textContent = self.l10n.amPM[int(hours >= 12)]; 657 if (self.secondElement !== undefined) self.secondElement.value = pad(seconds); 658 } 659 660 function onYearInput(event) { 661 var year = parseInt(event.target.value) + (event.delta || 0); 662 663 if (year / 1000 > 1 || event.key === "Enter" && !/[^\d]/.test(year.toString())) { 664 changeYear(year); 665 } 666 } 667 668 function bind(element, event, handler, options) { 669 if (event instanceof Array) return event.forEach(function (ev) { 670 return bind(element, ev, handler, options); 671 }); 672 if (element instanceof Array) return element.forEach(function (el) { 673 return bind(el, event, handler, options); 674 }); 675 element.addEventListener(event, handler, options); 676 677 self._handlers.push({ 678 element: element, 679 event: event, 680 handler: handler, 681 options: options 682 }); 683 } 684 685 function onClick(handler) { 686 return function (evt) { 687 evt.which === 1 && handler(evt); 688 }; 689 } 690 691 function triggerChange() { 692 triggerEvent("onChange"); 693 } 694 695 function bindEvents() { 696 if (self.config.wrap) { 697 ["open", "close", "toggle", "clear"].forEach(function (evt) { 698 Array.prototype.forEach.call(self.element.querySelectorAll("[data-" + evt + "]"), function (el) { 699 return bind(el, "click", self[evt]); 700 }); 701 }); 702 } 703 704 if (self.isMobile) { 705 setupMobile(); 706 return; 707 } 708 709 var debouncedResize = debounce(onResize, 50);
vendor: 12,984 bytes, lines 710-998
710 self._debouncedChange = debounce(triggerChange, DEBOUNCED_CHANGE_MS); 711 if (self.daysContainer && !/iPhone|iPad|iPod/i.test(navigator.userAgent)) bind(self.daysContainer, "mouseover", function (e) { 712 if (self.config.mode === "range") onMouseOver(e.target); 713 }); 714 bind(window.document.body, "keydown", onKeyDown); 715 if (!self.config.static) bind(self._input, "keydown", onKeyDown); 716 if (!self.config.inline && !self.config.static) bind(window, "resize", debouncedResize); 717 if (window.ontouchstart !== undefined) bind(window.document, "click", documentClick);else bind(window.document, "mousedown", onClick(documentClick)); 718 bind(window.document, "focus", documentClick, { 719 capture: true 720 }); 721 722 if (self.config.clickOpens === true) { 723 bind(self._input, "focus", self.open); 724 bind(self._input, "mousedown", onClick(self.open)); 725 } 726 727 if (self.daysContainer !== undefined) { 728 bind(self.monthNav, "mousedown", onClick(onMonthNavClick)); 729 bind(self.monthNav, ["keyup", "increment"], onYearInput); 730 bind(self.daysContainer, "mousedown", onClick(selectDate)); 731 } 732 733 if (self.timeContainer !== undefined && self.minuteElement !== undefined && self.hourElement !== undefined) { 734 var selText = function selText(e) { 735 return e.target.select(); 736 }; 737 738 bind(self.timeContainer, ["increment"], updateTime); 739 bind(self.timeContainer, "blur", updateTime, { 740 capture: true 741 }); 742 bind(self.timeContainer, "mousedown", onClick(timeIncrement)); 743 bind([self.hourElement, self.minuteElement], ["focus", "click"], selText); 744 if (self.secondElement !== undefined) bind(self.secondElement, "focus", function () { 745 return self.secondElement && self.secondElement.select(); 746 }); 747 748 if (self.amPM !== undefined) { 749 bind(self.amPM, "mousedown", onClick(function (e) { 750 updateTime(e); 751 triggerChange(); 752 })); 753 } 754 } 755 } 756 757 function jumpToDate(jumpDate) { 758 var jumpTo = jumpDate !== undefined ? self.parseDate(jumpDate) : self.latestSelectedDateObj || (self.config.minDate && self.config.minDate > self.now ? self.config.minDate : self.config.maxDate && self.config.maxDate < self.now ? self.config.maxDate : self.now); 759 760 try { 761 if (jumpTo !== undefined) { 762 self.currentYear = jumpTo.getFullYear(); 763 self.currentMonth = jumpTo.getMonth(); 764 } 765 } catch (e) { 766 e.message = "Invalid date supplied: " + jumpTo; 767 self.config.errorHandler(e); 768 } 769 770 self.redraw(); 771 } 772 773 function timeIncrement(e) { 774 if (~e.target.className.indexOf("arrow")) incrementNumInput(e, e.target.classList.contains("arrowUp") ? 1 : -1); 775 } 776 777 function incrementNumInput(e, delta, inputElem) { 778 var target = e && e.target; 779 var input = inputElem || target && target.parentNode && target.parentNode.firstChild; 780 var event = createEvent("increment"); 781 event.delta = delta; 782 input && input.dispatchEvent(event); 783 } 784 785 function build() { 786 var fragment = window.document.createDocumentFragment(); 787 self.calendarContainer = createElement("div", "customDatepicker-calendar"); 788 self.calendarContainer.tabIndex = -1; 789 790 if (!self.config.noCalendar) { 791 fragment.appendChild(buildMonthNav()); 792 self.innerContainer = createElement("div", "customDatepicker-innerContainer"); 793 794 if (self.config.weekNumbers) { 795 var _buildWeeks = buildWeeks(), 796 weekWrapper = _buildWeeks.weekWrapper, 797 weekNumbers = _buildWeeks.weekNumbers; 798 799 self.innerContainer.appendChild(weekWrapper); 800 self.weekNumbers = weekNumbers; 801 self.weekWrapper = weekWrapper; 802 } 803 804 self.rContainer = createElement("div", "customDatepicker-rContainer"); 805 self.rContainer.appendChild(buildWeekdays()); 806 807 if (!self.daysContainer) { 808 self.daysContainer = createElement("div", "customDatepicker-days"); 809 self.daysContainer.tabIndex = -1; 810 } 811 812 buildDays(); 813 self.rContainer.appendChild(self.daysContainer); 814 self.innerContainer.appendChild(self.rContainer); 815 fragment.appendChild(self.innerContainer); 816 } 817 818 if (self.config.enableTime) { 819 fragment.appendChild(buildTime()); 820 } 821 822 toggleClass(self.calendarContainer, "rangeMode", self.config.mode === "range"); 823 toggleClass(self.calendarContainer, "animate", self.config.animate === true); 824 toggleClass(self.calendarContainer, "multiMonth", self.config.showMonths > 1); 825 self.calendarContainer.appendChild(fragment); 826 var customAppend = self.config.appendTo !== undefined && self.config.appendTo.nodeType !== undefined; 827 828 if (self.config.inline || self.config.static) { 829 self.calendarContainer.classList.add(self.config.inline ? "inline" : "static"); 830 831 if (self.config.inline) { 832 if (!customAppend && self.element.parentNode) self.element.parentNode.insertBefore(self.calendarContainer, self._input.nextSibling);else if (self.config.appendTo !== undefined) self.config.appendTo.appendChild(self.calendarContainer); 833 } 834 835 if (self.config.static) { 836 var wrapper = createElement("div", "customDatepicker-wrapper"); 837 if (self.element.parentNode) self.element.parentNode.insertBefore(wrapper, self.element); 838 wrapper.appendChild(self.element); 839 if (self.altInput) wrapper.appendChild(self.altInput); 840 wrapper.appendChild(self.calendarContainer); 841 } 842 } 843 844 if (!self.config.static && !self.config.inline) (self.config.appendTo !== undefined ? self.config.appendTo : window.document.body).appendChild(self.calendarContainer); 845 } 846 847 function createDay(className, date, dayNumber, i) { 848 var dateIsEnabled = isEnabled(date, true), 849 dayElement = createElement("span", "customDatepicker-day " + className, date.getDate().toString()); 850 dayElement.dateObj = date; 851 dayElement.$i = i; 852 dayElement.setAttribute("aria-label", self.formatDate(date, self.config.ariaDateFormat)); 853 854 if (className.indexOf("hidden") === -1 && compareDates(date, self.now) === 0) { 855 self.todayDateElem = dayElement; 856 dayElement.classList.add("today"); 857 dayElement.setAttribute("aria-current", "date"); 858 } 859 860 if (dateIsEnabled) { 861 dayElement.tabIndex = -1; 862 863 if (isDateSelected(date)) { 864 dayElement.classList.add("selected"); 865 self.selectedDateElem = dayElement; 866 867 if (self.config.mode === "range") { 868 toggleClass(dayElement, "startRange", self.selectedDates[0] && compareDates(date, self.selectedDates[0], true) === 0); 869 toggleClass(dayElement, "endRange", self.selectedDates[1] && compareDates(date, self.selectedDates[1], true) === 0); 870 if (className === "nextMonthDay") dayElement.classList.add("inRange"); 871 } 872 } 873 } else { 874 dayElement.classList.add("disabled"); 875 } 876 877 if (self.config.mode === "range") { 878 if (isDateInRange(date) && !isDateSelected(date)) dayElement.classList.add("inRange"); 879 } 880 881 if (self.weekNumbers && self.config.showMonths === 1 && className !== "prevMonthDay" && dayNumber % 7 === 1) { 882 self.weekNumbers.insertAdjacentHTML("beforeend", "<span class='customDatepicker-day'>" + self.config.getWeek(date) + "</span>"); 883 } 884 885 triggerEvent("onDayCreate", dayElement); 886 return dayElement; 887 } 888 889 function focusOnDayElem(targetNode) { 890 targetNode.focus(); 891 if (self.config.mode === "range") onMouseOver(targetNode); 892 } 893 894 function getFirstAvailableDay(delta) { 895 var startMonth = delta > 0 ? 0 : self.config.showMonths - 1; 896 var endMonth = delta > 0 ? self.config.showMonths : -1; 897 898 for (var m = startMonth; m != endMonth; m += delta) { 899 var month = self.daysContainer.children[m]; 900 var startIndex = delta > 0 ? 0 : month.children.length - 1; 901 var endIndex = delta > 0 ? month.children.length : -1; 902 903 for (var i = startIndex; i != endIndex; i += delta) { 904 var c = month.children[i]; 905 if (c.className.indexOf("hidden") === -1 && isEnabled(c.dateObj)) return c; 906 } 907 } 908 909 return undefined; 910 } 911 912 function getNextAvailableDay(current, delta) { 913 var givenMonth = current.className.indexOf("Month") === -1 ? current.dateObj.getMonth() : self.currentMonth; 914 var endMonth = delta > 0 ? self.config.showMonths : -1; 915 var loopDelta = delta > 0 ? 1 : -1; 916 917 for (var m = givenMonth - self.currentMonth; m != endMonth; m += loopDelta) { 918 var month = self.daysContainer.children[m]; 919 var startIndex = givenMonth - self.currentMonth === m ? current.$i + delta : delta < 0 ? month.children.length - 1 : 0; 920 var numMonthDays = month.children.length; 921 922 for (var i = startIndex; i >= 0 && i < numMonthDays && i != (delta > 0 ? numMonthDays : -1); i += loopDelta) { 923 var c = month.children[i]; 924 if (c.className.indexOf("hidden") === -1 && isEnabled(c.dateObj) && Math.abs(current.$i - i) >= Math.abs(delta)) return focusOnDayElem(c); 925 } 926 } 927 928 self.changeMonth(loopDelta); 929 focusOnDay(getFirstAvailableDay(loopDelta), 0); 930 return undefined; 931 } 932 933 function focusOnDay(current, offset) { 934 var dayFocused = isInView(document.activeElement || document.body); 935 var startElem = current !== undefined ? current : dayFocused ? document.activeElement : self.selectedDateElem !== undefined && isInView(self.selectedDateElem) ? self.selectedDateElem : self.todayDateElem !== undefined && isInView(self.todayDateElem) ? self.todayDateElem : getFirstAvailableDay(offset > 0 ? 1 : -1); 936 if (startElem === undefined) return self._input.focus(); 937 if (!dayFocused) return focusOnDayElem(startElem); 938 getNextAvailableDay(startElem, offset); 939 } 940 941 function buildMonthDays(year, month) { 942 var firstOfMonth = (new Date(year, month, 1).getDay() - self.l10n.firstDayOfWeek + 7) % 7; 943 var prevMonthDays = self.utils.getDaysInMonth((month - 1 + 12) % 12); 944 var daysInMonth = self.utils.getDaysInMonth(month), 945 days = window.document.createDocumentFragment(), 946 isMultiMonth = self.config.showMonths > 1, 947 prevMonthDayClass = isMultiMonth ? "prevMonthDay hidden" : "prevMonthDay", 948 nextMonthDayClass = isMultiMonth ? "nextMonthDay hidden" : "nextMonthDay"; 949 var dayNumber = prevMonthDays + 1 - firstOfMonth, 950 dayIndex = 0; 951 952 for (; dayNumber <= prevMonthDays; dayNumber++, dayIndex++) { 953 days.appendChild(createDay(prevMonthDayClass, new Date(year, month - 1, dayNumber), dayNumber, dayIndex)); 954 } 955 956 for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++, dayIndex++) { 957 days.appendChild(createDay("", new Date(year, month, dayNumber), dayNumber, dayIndex)); 958 } 959 960 for (var dayNum = daysInMonth + 1; dayNum <= 42 - firstOfMonth && (self.config.showMonths === 1 || dayIndex % 7 !== 0); dayNum++, dayIndex++) { 961 days.appendChild(createDay(nextMonthDayClass, new Date(year, month + 1, dayNum % daysInMonth), dayNum, dayIndex)); 962 } 963 964 var dayContainer = createElement("div", "dayContainer"); 965 dayContainer.appendChild(days); 966 return dayContainer; 967 } 968 969 function buildDays() { 970 if (self.daysContainer === undefined) { 971 return; 972 } 973 974 clearNode(self.daysContainer); 975 if (self.weekNumbers) clearNode(self.weekNumbers); 976 var frag = document.createDocumentFragment(); 977 978 for (var i = 0; i < self.config.showMonths; i++) { 979 var d = new Date(self.currentYear, self.currentMonth, 1); 980 d.setMonth(self.currentMonth + i); 981 frag.appendChild(buildMonthDays(d.getFullYear(), d.getMonth())); 982 } 983 984 self.daysContainer.appendChild(frag); 985 self.days = self.daysContainer.firstChild; 986 987 if (self.config.mode === "range" && self.selectedDates.length === 1) { 988 onMouseOver(); 989 } 990 } 991 992 function buildMonth() { 993 var container = createElement("div", "customDatepicker-month"); 994 var monthNavFragment = window.document.createDocumentFragment(); 995 var monthElement = createElement("span", "cur-month"); 996 var yearInput = createNumberInput("cur-year", { 997 tabindex: "-1" 998 });
999 var yearElement = yearInput.getElementsByTagName("input")[0]; 1000 yearElement.setAttribute("aria-label", self.l10n.yearAriaLabel); 1001 if (self.config.minDate) yearElement.setAttribute("data-min", self.config.minDate.getFullYear().toString()); 1002 1003 if (self.config.maxDate) { 1004 yearElement.setAttribute("data-max", self.config.maxDate.getFullYear().toString()); 1005 yearElement.disabled = !!self.config.minDate && self.config.minDate.getFullYear() === self.config.maxDate.getFullYear(); 1006 } 1007 1008 var currentMonth = createElement("div", "customDatepicker-current-month"); 1009 currentMonth.appendChild(monthElement); 1010 currentMonth.appendChild(yearInput); 1011 monthNavFragment.appendChild(currentMonth); 1012 container.appendChild(monthNavFragment); 1013 return { 1014 container: container, 1015 yearElement: yearElement, 1016 monthElement: monthElement 1017 }; 1018 } 1019 1020 function buildMonths() { 1021 clearNode(self.monthNav); 1022 self.monthNav.appendChild(self.prevMonthNav); 1023 1024 for (var m = self.config.showMonths; m--;) { 1025 var month = buildMonth(); 1026 self.yearElements.push(month.yearElement); 1027 self.monthElements.push(month.monthElement); 1028 self.monthNav.appendChild(month.container); 1029 } 1030 1031 self.monthNav.appendChild(self.nextMonthNav); 1032 } 1033 1034 function buildMonthNav() { 1035 self.monthNav = createElement("div", "customDatepicker-months"); 1036 self.yearElements = []; 1037 self.monthElements = []; 1038 self.prevMonthNav = createElement("span", "customDatepicker-prev-month"); 1039 self.prevMonthNav.innerHTML = self.config.prevArrow; 1040 self.nextMonthNav = createElement("span", "customDatepicker-next-month"); 1041 self.nextMonthNav.innerHTML = self.config.nextArrow; 1042 buildMonths(); 1043 Object.defineProperty(self, "_hidePrevMonthArrow", { 1044 get: function get() { 1045 return self.__hidePrevMonthArrow; 1046 }, 1047 set: function set(bool) { 1048 if (self.__hidePrevMonthArrow !== bool) { 1049 toggleClass(self.prevMonthNav, "disabled", bool); 1050 self.__hidePrevMonthArrow = bool; 1051 } 1052 } 1053 }); 1054 Object.defineProperty(self, "_hideNextMonthArrow", { 1055 get: function get() { 1056 return self.__hideNextMonthArrow; 1057 }, 1058 set: function set(bool) { 1059 if (self.__hideNextMonthArrow !== bool) { 1060 toggleClass(self.nextMonthNav, "disabled", bool); 1061 self.__hideNextMonthArrow = bool; 1062 } 1063 } 1064 }); 1065 self.currentYearElement = self.yearElements[0]; 1066 updateNavigationCurrentMonth(); 1067 return self.monthNav; 1068 } 1069 1070 function buildTime() { 1071 self.calendarContainer.classList.add("hasTime"); 1072 if (self.config.noCalendar) self.calendarContainer.classList.add("noCalendar"); 1073 self.timeContainer = createElement("div", "customDatepicker-time"); 1074 self.timeContainer.tabIndex = -1; 1075 var separator = createElement("span", "customDatepicker-time-separator", ":"); 1076 var hourInput = createNumberInput("customDatepicker-hour"); 1077 self.hourElement = hourInput.getElementsByTagName("input")[0]; 1078 var minuteInput = createNumberInput("customDatepicker-minute"); 1079 self.minuteElement = minuteInput.getElementsByTagName("input")[0]; 1080 self.hourElement.tabIndex = self.minuteElement.tabIndex = -1; 1081 self.hourElement.value = pad(self.latestSelectedDateObj ? self.latestSelectedDateObj.getHours() : self.config.time_24hr ? self.config.defaultHour : military2ampm(self.config.defaultHour)); 1082 self.minuteElement.value = pad(self.latestSelectedDateObj ? self.latestSelectedDateObj.getMinutes() : self.config.defaultMinute); 1083 self.hourElement.setAttribute("data-step", self.config.hourIncrement.toString()); 1084 self.minuteElement.setAttribute("data-step", self.config.minuteIncrement.toString()); 1085 self.hourElement.setAttribute("data-min", self.config.time_24hr ? "0" : "1"); 1086 self.hourElement.setAttribute("data-max", self.config.time_24hr ? "23" : "12"); 1087 self.minuteElement.setAttribute("data-min", "0"); 1088 self.minuteElement.setAttribute("data-max", "59");
vendor: 4,221 bytes, lines 1089-1183
1089 self.timeContainer.appendChild(hourInput); 1090 self.timeContainer.appendChild(separator); 1091 self.timeContainer.appendChild(minuteInput); 1092 if (self.config.time_24hr) self.timeContainer.classList.add("time24hr"); 1093 1094 if (self.config.enableSeconds) { 1095 self.timeContainer.classList.add("hasSeconds"); 1096 var secondInput = createNumberInput("customDatepicker-second"); 1097 self.secondElement = secondInput.getElementsByTagName("input")[0]; 1098 self.secondElement.value = pad(self.latestSelectedDateObj ? self.latestSelectedDateObj.getSeconds() : self.config.defaultSeconds); 1099 self.secondElement.setAttribute("data-step", self.minuteElement.getAttribute("data-step")); 1100 self.secondElement.setAttribute("data-min", self.minuteElement.getAttribute("data-min")); 1101 self.secondElement.setAttribute("data-max", self.minuteElement.getAttribute("data-max")); 1102 self.timeContainer.appendChild(createElement("span", "customDatepicker-time-separator", ":")); 1103 self.timeContainer.appendChild(secondInput); 1104 } 1105 1106 if (!self.config.time_24hr) { 1107 self.amPM = createElement("span", "customDatepicker-am-pm", self.l10n.amPM[int((self.latestSelectedDateObj ? self.hourElement.value : self.config.defaultHour) > 11)]); 1108 self.amPM.title = self.l10n.toggleTitle; 1109 self.amPM.tabIndex = -1; 1110 self.timeContainer.appendChild(self.amPM); 1111 } 1112 1113 return self.timeContainer; 1114 } 1115 1116 function buildWeekdays() { 1117 if (!self.weekdayContainer) self.weekdayContainer = createElement("div", "customDatepicker-weekdays");else clearNode(self.weekdayContainer); 1118 1119 for (var i = self.config.showMonths; i--;) { 1120 var container = createElement("div", "customDatepicker-weekdaycontainer"); 1121 self.weekdayContainer.appendChild(container); 1122 } 1123 1124 updateWeekdays(); 1125 return self.weekdayContainer; 1126 } 1127 1128 function updateWeekdays() { 1129 var firstDayOfWeek = self.l10n.firstDayOfWeek; 1130 var weekdays = self.l10n.weekdays.shorthand.concat(); 1131 1132 if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) { 1133 weekdays = weekdays.splice(firstDayOfWeek, weekdays.length).concat(weekdays.splice(0, firstDayOfWeek)); 1134 } 1135 1136 for (var i = self.config.showMonths; i--;) { 1137 self.weekdayContainer.children[i].innerHTML = "\n <span class=customDatepicker-weekday>\n " + weekdays.join("</span><span class=customDatepicker-weekday>") + "\n </span>\n "; 1138 } 1139 } 1140 1141 function buildWeeks() { 1142 self.calendarContainer.classList.add("hasWeeks"); 1143 var weekWrapper = createElement("div", "customDatepicker-weekwrapper"); 1144 weekWrapper.appendChild(createElement("span", "customDatepicker-weekday", self.l10n.weekAbbreviation)); 1145 var weekNumbers = createElement("div", "customDatepicker-weeks"); 1146 weekWrapper.appendChild(weekNumbers); 1147 return { 1148 weekWrapper: weekWrapper, 1149 weekNumbers: weekNumbers 1150 }; 1151 } 1152 1153 function changeMonth(value, is_offset) { 1154 if (is_offset === void 0) { 1155 is_offset = true; 1156 } 1157 1158 var delta = is_offset ? value : value - self.currentMonth; 1159 if (delta < 0 && self._hidePrevMonthArrow === true || delta > 0 && self._hideNextMonthArrow === true) return; 1160 self.currentMonth += delta; 1161 1162 if (self.currentMonth < 0 || self.currentMonth > 11) { 1163 self.currentYear += self.currentMonth > 11 ? 1 : -1; 1164 self.currentMonth = (self.currentMonth + 12) % 12; 1165 triggerEvent("onYearChange"); 1166 } 1167 1168 buildDays(); 1169 triggerEvent("onMonthChange"); 1170 updateNavigationCurrentMonth(); 1171 } 1172 1173 function clear(triggerChangeEvent) { 1174 if (triggerChangeEvent === void 0) { 1175 triggerChangeEvent = true; 1176 } 1177 1178 self.input.value = ""; 1179 if (self.altInput !== undefined) self.altInput.value = ""; 1180 if (self.mobileInput !== undefined) self.mobileInput.value = ""; 1181 self.selectedDates = []; 1182 self.latestSelectedDateObj = undefined; 1183 self.showTimeInput = false;
1184 1185 if (self.config.enableTime === true) { 1186 setDefaultHours(); 1187 } 1188 1189 self.redraw(); 1190 if (triggerChangeEvent) triggerEvent("onChange"); 1191 } 1192 1193 function close() { 1194 self.isOpen = false; 1195 1196 if (!self.isMobile) { 1197 self.calendarContainer.classList.remove("open"); 1198 1199 self._input.classList.remove("active"); 1200 } 1201 1202 triggerEvent("onClose"); 1203 } 1204 1205 function destroy() { 1206 if (self.config !== undefined) triggerEvent("onDestroy"); 1207 1208 for (var i = self._handlers.length; i--;) { 1209 var h = self._handlers[i]; 1210 h.element.removeEventListener(h.event, h.handler, h.options); 1211 } 1212 1213 self._handlers = []; 1214 1215 if (self.mobileInput) { 1216 if (self.mobileInput.parentNode) self.mobileInput.parentNode.removeChild(self.mobileInput); 1217 self.mobileInput = undefined; 1218 } else if (self.calendarContainer && self.calendarContainer.parentNode) { 1219 if (self.config.static && self.calendarContainer.parentNode) { 1220 var wrapper = self.calendarContainer.parentNode; 1221 wrapper.lastChild && wrapper.removeChild(wrapper.lastChild); 1222 1223 if (wrapper.parentNode) { 1224 while (wrapper.firstChild) { 1225 wrapper.parentNode.insertBefore(wrapper.firstChild, wrapper); 1226 } 1227 1228 wrapper.parentNode.removeChild(wrapper); 1229 } 1230 } else self.calendarContainer.parentNode.removeChild(self.calendarContainer); 1231 } 1232 1233 if (self.altInput) { 1234 self.input.type = "text"; 1235 if (self.altInput.parentNode) self.altInput.parentNode.removeChild(self.altInput); 1236 delete self.altInput; 1237 } 1238 1239 if (self.input) { 1240 self.input.type = self.input._type; 1241 self.input.classList.remove("customDatepicker-input"); 1242 self.input.removeAttribute("readonly"); 1243 self.input.value = ""; 1244 } 1245 1246 ["_showTimeInput", "latestSelectedDateObj", "_hideNextMonthArrow", "_hidePrevMonthArrow", "__hideNextMonthArrow", "__hidePrevMonthArrow", "isMobile", "isOpen", "selectedDateElem", "minDateHasTime", "maxDateHasTime", "days", "daysContainer", "_input", "_positionElement", "innerContainer", "rContainer", "monthNav", "todayDateElem", "calendarContainer", "weekdayContainer", "prevMonthNav", "nextMonthNav", "currentMonthElement", "currentYearElement", "navigationCurrentMonth", "selectedDateElem", "config"].forEach(function (k) { 1247 try { 1248 delete self[k]; 1249 } catch (_) {} 1250 }); 1251 } 1252 1253 function isCalendarElem(elem) { 1254 if (self.config.appendTo && self.config.appendTo.contains(elem)) return true; 1255 return self.calendarContainer.contains(elem); 1256 } 1257 1258 function documentClick(e) { 1259 if (self.isOpen && !self.config.inline) { 1260 var isCalendarElement = isCalendarElem(e.target); 1261 var isInput = e.target === self.input || e.target === self.altInput || self.element.contains(e.target) || e.path && e.path.indexOf && (~e.path.indexOf(self.input) || ~e.path.indexOf(self.altInput)); 1262 var lostFocus = e.type === "blur" ? isInput && e.relatedTarget && !isCalendarElem(e.relatedTarget) : !isInput && !isCalendarElement; 1263 var isIgnored = !self.config.ignoredFocusElements.some(function (elem) { 1264 return elem.contains(e.target); 1265 }); 1266 1267 if (lostFocus && isIgnored) { 1268 self.close(); 1269 1270 if (self.config.mode === "range" && self.selectedDates.length === 1) { 1271 self.clear(false); 1272 self.redraw(); 1273 } 1274 } 1275 } 1276 } 1277 1278 function changeYear(newYear) { 1279 if (!newYear || self.config.minDate && newYear < self.config.minDate.getFullYear() || self.config.maxDate && newYear > self.config.maxDate.getFullYear()) return; 1280 var newYearNum = newYear, 1281 isNewYear = self.currentYear !== newYearNum; 1282 self.currentYear = newYearNum || self.currentYear; 1283 1284 if (self.config.maxDate && self.currentYear === self.config.maxDate.getFullYear()) { 1285 self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth); 1286 } else if (self.config.minDate && self.currentYear === self.config.minDate.getFullYear()) { 1287 self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth); 1288 } 1289 1290 if (isNewYear) { 1291 self.redraw(); 1292 triggerEvent("onYearChange"); 1293 } 1294 } 1295 1296 function isEnabled(date, timeless) { 1297 if (timeless === void 0) { 1298 timeless = true; 1299 } 1300 1301 var dateToCheck = self.parseDate(date, undefined, timeless); 1302 if (self.config.minDate && dateToCheck && compareDates(dateToCheck, self.config.minDate, timeless !== undefined ? timeless : !self.minDateHasTime) < 0 || self.config.maxDate && dateToCheck && compareDates(dateToCheck, self.config.maxDate, timeless !== undefined ? timeless : !self.maxDateHasTime) > 0) return false;
1303 if (self.config.enable.length === 0 && self.config.disable.length === 0) return true; 1304 if (dateToCheck === undefined) return false; 1305 var bool = self.config.enable.length > 0, 1306 array = bool ? self.config.enable : self.config.disable; 1307 1308 for (var i = 0, d; i < array.length; i++) { 1309 d = array[i]; 1310 if (typeof d === "function" && d(dateToCheck)) return bool;else if (d instanceof Date && dateToCheck !== undefined && d.getTime() === dateToCheck.getTime()) return bool;else if (typeof d === "string" && dateToCheck !== undefined) { 1311 var parsed = self.parseDate(d, undefined, true); 1312 return parsed && parsed.getTime() === dateToCheck.getTime() ? bool : !bool; 1313 } else if (typeof d === "object" && dateToCheck !== undefined && d.from && d.to && dateToCheck.getTime() >= d.from.getTime() && dateToCheck.getTime() <= d.to.getTime()) return bool; 1314 } 1315 1316 return !bool; 1317 } 1318 1319 function isInView(elem) { 1320 if (self.daysContainer !== undefined) return elem.className.indexOf("hidden") === -1 && self.daysContainer.contains(elem); 1321 return false; 1322 } 1323 1324 function onKeyDown(e) { 1325 var isInput = e.target === self._input; 1326 var allowInput = self.config.allowInput; 1327 var allowKeydown = self.isOpen && (!allowInput || !isInput); 1328 var allowInlineKeydown = self.config.inline && isInput && !allowInput; 1329 1330 if (e.keyCode === 13 && isInput) { 1331 if (allowInput) { 1332 self.setDate(self._input.value, true, e.target === self.altInput ? self.config.altFormat : self.config.dateFormat); 1333 return e.target.blur(); 1334 } else self.open(); 1335 } else if (isCalendarElem(e.target) || allowKeydown || allowInlineKeydown) { 1336 var isTimeObj = !!self.timeContainer && self.timeContainer.contains(e.target); 1337 1338 switch (e.keyCode) { 1339 case 13: 1340 if (isTimeObj) updateTime();else selectDate(e); 1341 break; 1342 1343 case 27: 1344 e.preventDefault(); 1345 focusAndClose(); 1346 break; 1347 1348 case 8: 1349 case 46: 1350 if (isInput && !self.config.allowInput) { 1351 e.preventDefault(); 1352 self.clear(); 1353 } 1354 1355 break; 1356 1357 case 37: 1358 case 39: 1359 if (!isTimeObj) { 1360 e.preventDefault(); 1361 1362 if (self.daysContainer !== undefined && (allowInput === false || isInView(document.activeElement))) { 1363 var _delta = e.keyCode === 39 ? 1 : -1; 1364 1365 if (!e.ctrlKey) focusOnDay(undefined, _delta);else { 1366 changeMonth(_delta); 1367 focusOnDay(getFirstAvailableDay(1), 0); 1368 } 1369 } 1370 } else if (self.hourElement) self.hourElement.focus(); 1371 1372 break; 1373 1374 case 38: 1375 case 40: 1376 e.preventDefault(); 1377 var delta = e.keyCode === 40 ? 1 : -1; 1378 1379 if (self.daysContainer && e.target.$i !== undefined) { 1380 if (e.ctrlKey) { 1381 changeYear(self.currentYear - delta); 1382 focusOnDay(getFirstAvailableDay(1), 0); 1383 } else if (!isTimeObj) focusOnDay(undefined, delta * 7); 1384 } else if (self.config.enableTime) { 1385 if (!isTimeObj && self.hourElement) self.hourElement.focus(); 1386 updateTime(e); 1387 1388 self._debouncedChange(); 1389 } 1390 1391 break; 1392 1393 case 9: 1394 if (!isTimeObj) { 1395 self.element.focus(); 1396 break; 1397 } 1398 1399 var elems = [self.hourElement, self.minuteElement, self.secondElement, self.amPM
1399].filter(function (x) { 1400 return x; 1401 }); 1402 var i = elems.indexOf(e.target); 1403 1404 if (i !== -1) { 1405 var target = elems[i + (e.shiftKey ? -1 : 1)]; 1406 1407 if (target !== undefined) { 1408 e.preventDefault(); 1409 target.focus(); 1410 } else { 1411 self.element.focus(); 1412 } 1413 } 1414 1415 break; 1416 1417 default: 1418 break; 1419 } 1420 } 1421 1422 if (self.amPM !== undefined && e.target === self.amPM) { 1423 switch (e.key) { 1424 case self.l10n.amPM[0].charAt(0): 1425 case self.l10n.amPM[0].charAt(0).toLowerCase(): 1426 self.amPM.textContent = self.l10n.amPM[0]; 1427 setHoursFromInputs(); 1428 updateValue(); 1429 break; 1430 1431 case self.l10n.amPM[1].charAt(0): 1432 case self.l10n.amPM[1].charAt(0).toLowerCase(): 1433 self.amPM.textContent = self.l10n.amPM[1]; 1434 setHoursFromInputs(); 1435 updateValue(); 1436 break; 1437 } 1438 } 1439 1440 triggerEvent("onKeyDown", e); 1441 } 1442 1443 function onMouseOver(elem) { 1444 if (self.selectedDates.length !== 1 || elem && (!elem.classList.contains("customDatepicker-day") || elem.classList.contains("disabled"))) return; 1445 var hoverDate = elem ? elem.dateObj.getTime() : self.days.firstElementChild.dateObj.getTime(), 1446 initialDate = self.parseDate(self.selectedDates[0], undefined, true).getTime(), 1447 rangeStartDate = Math.min(hoverDate, self.selectedDates[0].getTime()), 1448 rangeEndDate = Math.max(hoverDate, self.selectedDates[0].getTime()), 1449 lastDate = self.daysContainer.lastChild.lastChild.dateObj.getTime(); 1450 var containsDisabled = false; 1451 var minRange = 0, 1452 maxRange = 0; 1453 1454 for (var t = rangeStartDate; t < lastDate; t += duration.DAY) { 1455 if (!isEnabled(new Date(t), true)) { 1456 containsDisabled = containsDisabled || t > rangeStartDate && t < rangeEndDate; 1457 if (t < initialDate && (!minRange || t > minRange)) minRange = t;else if (t > initialDate && (!maxRange || t < maxRange)) maxRange = t; 1458 } 1459 } 1460 1461 for (var m = 0; m < self.config.showMonths; m++) { 1462 var month = self.daysContainer.children[m]; 1463 var prevMonth = self.daysContainer.children[m - 1]; 1464 1465 var _loop = function _loop(i, l) { 1466 var dayElem = month.children[i], 1467 date = dayElem.dateObj; 1468 var timestamp = date.getTime(); 1469 var outOfRange = minRange > 0 && timestamp < minRange || maxRange > 0 && timestamp > maxRange; 1470 1471 if (outOfRange) { 1472 dayElem.classList.add("notAllowed"); 1473 ["inRange", "startRange", "endRange"].forEach(function (c) { 1474 dayElem.classList.remove(c); 1475 }); 1476 return "continue"; 1477 } else if (containsDisabled && !outOfRange) return "continue"; 1478 1479 ["startRange", "inRange", "endRange", "notAllowed"].forEach(function (c) { 1480 dayElem.classList.remove(c); 1481 }); 1482 1483 if (elem !== undefined) { 1484 elem.classList.add(hoverDate < self.selectedDates[0].getTime() ? "startRange" : "endRange"); 1485 1486 if (month.contains(elem) || !(m > 0 && prevMonth && prevMonth.lastChild.dateObj.getTime() >= timestamp)) { 1487 if (initialDate < hoverDate && timestamp === initialDate) dayElem.classList.add("startRange");else if (initialDate > hoverDate && timestamp === initialDate) dayElem.classList.add("endRange"); 1488 if (timestamp >= minRange && (maxRange === 0 || timestamp <= maxRange) && isBetween(timestamp, initialDate, hoverDate)) dayElem.classList.add("inRange"); 1489 } 1490 } 1491 }; 1492 1493 for (var i = 0, l = month.children.length; i < l; i++) { 1494 var _ret = _loop(i, l); 1495 1496 if (_ret === "continue") continue; 1497 } 1498 } 1499 } 1500 1501 function onResize() { 1502 if (self.isOpen && !self.config.static && !self.config.inline) positionCalendar(
1502); 1503 } 1504 1505 function open(e, positionElement) { 1506 if (positionElement === void 0) { 1507 positionElement = self._positionElement; 1508 } 1509 1510 if (self.isMobile === true) { 1511 if (e) { 1512 e.preventDefault(); 1513 e.target && e.target.blur(); 1514 } 1515 1516 if (self.mobileInput !== undefined) { 1517 self.mobileInput.focus(); 1518 self.mobileInput.click(); 1519 } 1520 1521 triggerEvent("onOpen"); 1522 return; 1523 } 1524 1525 if (self._input.disabled || self.config.inline) return; 1526 var wasOpen = self.isOpen; 1527 self.isOpen = true; 1528 1529 if (!wasOpen) { 1530 self.calendarContainer.classList.add("open"); 1531 1532 self._input.classList.add("active"); 1533 1534 triggerEvent("onOpen"); 1535 positionCalendar(positionElement); 1536 } 1537 1538 if (self.config.enableTime === true && self.config.noCalendar === true) { 1539 if (self.selectedDates.length === 0) { 1540 self.setDate(self.config.minDate !== undefined ? new Date(self.config.minDate.getTime()) : new Date(), false); 1541 setDefaultHours(); 1542 updateValue(); 1543 } 1544 1545 if (self.config.allowInput === false && (e === undefined || !self.timeContainer.contains(e.relatedTarget))) { 1546 setTimeout(function () { 1547 return self.hourElement.select(); 1548 }, 50); 1549 } 1550 } 1551 } 1552 1553 function minMaxDateSetter(type) { 1554 return function (date) { 1555 var dateObj = self.config["_" + type + "Date"] = self.parseDate(date, self.config.dateFormat); 1556 var inverseDateObj = self.config["_" + (type === "min" ? "max" : "min") + "Date"]; 1557 1558 if (dateObj !== undefined) { 1559 self[type === "min" ? "minDateHasTime" : "maxDateHasTime"] = dateObj.getHours() > 0 || dateObj.getMinutes() > 0 || dateObj.getSeconds() > 0; 1560 } 1561 1562 if (self.selectedDates) { 1563 self.selectedDates = self.selectedDates.filter(function (d) { 1564 return isEnabled(d); 1565 }); 1566 if (!self.selectedDates.length && type === "min") setHoursFromDate(dateObj); 1567 updateValue(); 1568 } 1569 1570 if (self.daysContainer) { 1571 redraw(); 1572 if (dateObj !== undefined) self.currentYearElement[type] = dateObj.getFullYear().toString();else self.currentYearElement.removeAttribute(type); 1573 self.currentYearElement.disabled = !!inverseDateObj && dateObj !== undefined && inverseDateObj.getFullYear() === dateObj.getFullYear(); 1574 } 1575 }; 1576 } 1577 1578 function parseConfig() { 1579 var boolOpts = ["wrap", "weekNumbers", "allowInput", "clickOpens", "time_24hr", "enableTime", "noCalendar", "altInput", "shorthandCurrentMonth", "inline", "static", "enableSeconds", "disableMobile"]; 1580 var userConfig = Object.assign({}, instanceConfig, JSON.parse(JSON.stringify(element.dataset || {}))); 1581 var formats$$1 = {}; 1582 self.config.parseDate = userConfig.parseDate; 1583 self.config.formatDate = userConfig.formatDate; 1584 Object.defineProperty(self.config, "enable", { 1585 get: function get() { 1586 return self.config._enable; 1587 }, 1588 set: function set(dates) { 1589 self.config._enable = parseDateRules(dates); 1590 } 1591 }); 1592 Object.defineProperty(self.config, "disable", { 1593 get: function get() { 1594 return self.config._disable; 1595 }, 1596 set: function set(dates) { 1597 self.config._disable = parseDateRules(dates); 1598 } 1599 }); 1600 var timeMode = userConfig.mode === "time"; 1601 1602 if (!userConfig.dateFormat && (userConfig.enableTime || timeMode)) { 1603 formats$$1.dateFormat = userConfig.noCalendar || timeMode ? "H:i" + (userConfig.enableSeconds ? ":S" : "") : customDatepicker.defaultConfig.dateFormat + " H:i" + (userConfig.enableSeconds ? ":S" : ""); 1604 } 1605 1606 if (userConfig.altInput && (userConfig.enableTime || timeMode) && !userConfig.altFormat) { 1607 formats$$1.altFormat = userConfig.noCalendar || timeMode ? "h:i" + (userConfig.enableSeconds ? ":S K" : " K") : customDatepicker.defaultConfig.altFormat + (" h:i"
1607+ (userConfig.enableSeconds ? ":S" : "") + " K"); 1608 } 1609 1610 Object.defineProperty(self.config, "minDate", { 1611 get: function get() { 1612 return self.config._minDate; 1613 }, 1614 set: minMaxDateSetter("min") 1615 }); 1616 Object.defineProperty(self.config, "maxDate", { 1617 get: function get() { 1618 return self.config._maxDate; 1619 }, 1620 set: minMaxDateSetter("max") 1621 }); 1622 1623 var minMaxTimeSetter = function minMaxTimeSetter(type) { 1624 return function (val) { 1625 self.config[type === "min" ? "_minTime" : "_maxTime"] = self.parseDate(val, "H:i"); 1626 }; 1627 }; 1628 1629 Object.defineProperty(self.config, "minTime", { 1630 get: function get() { 1631 return self.config._minTime; 1632 }, 1633 set: minMaxTimeSetter("min") 1634 }); 1635 Object.defineProperty(self.config, "maxTime", { 1636 get: function get() { 1637 return self.config._maxTime; 1638 }, 1639 set: minMaxTimeSetter("max") 1640 }); 1641 1642 if (userConfig.mode === "time") { 1643 self.config.noCalendar = true; 1644 self.config.enableTime = true; 1645 } 1646 1647 Object.assign(self.config, formats$$1, userConfig); 1648 1649 for (var i = 0; i < boolOpts.length; i++) { 1650 self.config[boolOpts[i]] = self.config[boolOpts[i]] === true || self.config[boolOpts[i]] === "true"; 1651 } 1652 1653 HOOKS.filter(function (hook) { 1654 return self.config[hook] !== undefined; 1655 }
1655).forEach(function (hook) { 1656 self.config[hook] = arrayify(self.config[hook] || []).map(bindToInstance); 1657 }); 1658 self.isMobile = !self.config.disableMobile && !self.config.inline && self.config.mode === "single" && !self.config.disable.length && !self.config.enable.length && !self.config.weekNumbers && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); 1659 1660 for (var _i = 0; _i < self.config.plugins.length; _i++) { 1661 var pluginConf = self.config.plugins[_i](self) || {}; 1662 1663 for (var key in pluginConf) { 1664 if (HOOKS.indexOf(key) > -1) { 1665 self.config[key] = arrayify(pluginConf[key]).map(bindToInstance).concat(self.config[key]); 1666 } else if (typeof userConfig[key] === "undefined") self.config[key] = pluginConf[key]; 1667 } 1668 } 1669 1670 triggerEvent("onParseConfig"); 1671 } 1672 1673 function setupLocale() { 1674 if (typeof self.config.locale !== "object" && typeof customDatepicker.l10ns[self.config.locale] === "undefined") self.config.errorHandler(new Error("customDatepicker: invalid locale " + self.config.locale)); 1675 self.l10n = Object.assign({}, customDatepicker.l10ns.default, typeof self.config.locale === "object" ? self.config.locale : self.config.locale !== "default" ? customDatepicker.l10ns[self.config.locale] : undefined); 1676 tokenRegex.K = "(" + self.l10n.amPM[0] + "|" + self.l10n.amPM[1] + "|" + self.l10n.amPM[0].toLowerCase() + "|" + self.l10n.amPM[1].toLowerCase() + ")"; 1677 self.formatDate = createDateFormatter(self); 1678 self.parseDate = createDateParser({ 1679 config: self.config, 1680 l10n: self.l10n 1681 }); 1682 } 1683 1684 function positionCalendar(customPositionElement) { 1685 if (self.calendarContainer === undefined) return; 1686 triggerEvent("onPreCalendarPosition"); 1687 var positionElement = customPositionElement || self._positionElement; 1688 var calendarHeight = Array.prototype.reduce.call(self.calendarContainer.children, function (acc, child) { 1689 return acc + child.offsetHeight; 1690 }, 0), 1691 calendarWidth = self.calendarContainer.offsetWidth, 1692 configPos = self.config.position.split(" "), 1693 configPosVertical = configPos[0], 1694 configPosHorizontal = configPos.length > 1 ? configPos[1] : null, 1695 inputBounds = positionElement.getBoundingClientRect(), 1696 distanceFromBottom = window.innerHeight - inputBounds.bottom, 1697 showOnTop = configPosVertical === "above" || configPosVertical !== "below" && distanceFromBottom < calendarHeight && inputBounds.top > calendarHeight; 1698 var top = window.pageYOffset + inputBounds.top + (!showOnTop ? positionElement.offsetHeight + 2 : -calendarHeight - 2); 1699 toggleClass(self.calendarContainer, "arrowTop", !showOnTop); 1700 toggleClass(self.calendarContainer, "arrowBottom", showOnTop); 1701 if (self.config.inline) return; 1702 var left = window.pageXOffset + inputBounds.left - (configPosHorizontal != null && configPosHorizontal === "center" ? (calendarWidth - inputBounds.width) / 2 : 0); 1703 var right = window.document.body.offsetWidth - inputBounds.right; 1704 var rightMost = left + calendarWidth > window.document.body.offsetWidth; 1705 toggleClass(self.calendarContainer, "rightMost", rightMost); 1706 if (self.config.static) return; 1707 self.calendarContainer.style.top = top + "px"; 1708 1709 if (!rightMost) { 1710 self.calendarContainer.style.left = left + "px"; 1711 self.calendarContainer.style.right = "auto"; 1712 } else { 1713 self.calendarContainer.style.left = "auto"; 1714 self.calendarContainer.style.right = right + "px"; 1715 } 1716 } 1717 1718 function redraw() { 1719 if (self.config.noCalendar || self.isMobile) return; 1720 updateNavigationCurrentMonth(); 1721 buildDays(); 1722 } 1723 1724 function focusAndClose() { 1725 self._input.focus(); 1726 1727 if (window.navigator.userAgent.indexOf("MSIE") !== -1 || navigator.msMaxTouchPoints !== undefined) { 1728 setTimeout(self.close, 0); 1729 } else { 1730 self.close(); 1731 } 1732 } 1733 1734 function selectDate(e) { 1735 e.preventDefault(); 1736 e.stopPropagation(); 1737 1738 var isSelectable = function isSelectable(day) { 1739 return day.classList && day.classList.contains("customDatepicker-day") && !day.classList.contains("disabled") && !day.classList.contains("notAllowed"); 1740 }; 1741 1742 var t = findParent(e.target, isSelectable); 1743 if (t === undefined) return; 1744 var target = t; 1745 var selectedDate = self.latestSelectedDateObj = new Date(target.dateObj.getTime()); 1746 var shouldChangeMonth = (selectedDate.getMonth() < self.currentMonth || selectedDate.getMonth() > self.currentMonth + self.config.showMonths - 1) && self.config.mode !== "range"; 1747 self.selectedDateElem = target; 1748 if (self.config.mode === "single") self.selectedDates = [selectedDate];else if (self.config.mode === "multiple") { 1749 var selectedIndex = isDateSelected(selectedDate); 1750 if (selectedIndex) self.selectedDates.splice(parseInt(selectedIndex), 1);else self.selectedDates.push(selectedDate); 1751 } else if (self.config.mode === "range") { 1752 if (self.selectedDates.length === 2) self.clear(false); 1753 self.selectedDates.push(selectedDate); 1754 if (compareDates(selectedDate, self.selectedDates[0], true) !== 0) self.selectedDates.sort(function (a, b) { 1755 return a.getTime() - b.getTime(); 1756 }); 1757 } 1758 setHoursFromInputs(); 1759 1760 if (shouldChangeMonth) { 1761 var isNewYear = self.currentYear !== selectedDate.getFullYear(); 1762 self.currentYear = selectedDate.getFullYear(); 1763 self.currentMonth = selectedDate.getMonth(); 1764 if (isNewYear) triggerEvent("onYearChange"); 1765 triggerEvent("onMonthChange"); 1766 } 1767 1768 updateNavigationCurrentMonth(); 1769 buildDays();
1770 updateValue(); 1771 if (self.config.enableTime) setTimeout(function () { 1772 return self.showTimeInput = true; 1773 }, 50); 1774 if (!shouldChangeMonth && self.config.mode !== "range" && self.config.showMonths === 1) focusOnDayElem(target);else self.selectedDateElem && self.selectedDateElem.focus(); 1775 if (self.hourElement !== undefined) setTimeout(function () { 1776 return self.hourElement !== undefined && self.hourElement.select(); 1777 }, 451); 1778 1779 if (self.config.closeOnSelect) { 1780 var single = self.config.mode === "single" && !self.config.enableTime; 1781 var range = self.config.mode === "range" && self.selectedDates.length === 2 && !self.config.enableTime; 1782 1783 if (single || range) { 1784 focusAndClose(); 1785 } 1786 } 1787 1788 triggerChange(); 1789 } 1790 1791 var CALLBACKS = { 1792 locale: [setupLocale, updateWeekdays], 1793 showMonths: [buildMonths, setCalendarWidth, buildWeekdays] 1794 }; 1795 1796 function set(option, value) { 1797 if (option !== null && typeof option === "object") Object.assign(self.config, option);else { 1798 self.config[option] = value; 1799 if (CALLBACKS[option] !== undefined) CALLBACKS[option].forEach(function (x) { 1800 return x(); 1801 });else if (HOOKS.indexOf(option) > -1) self.config[option] = arrayify(value); 1802 } 1803 self.redraw(); 1804 jumpToDate(); 1805 updateValue(false); 1806 } 1807 1808 function setSelectedDate(inputDate, format) { 1809 var dates = []; 1810 if (inputDate instanceof Array) dates = inputDate.map(function (d) { 1811 return self.parseDate(d, format); 1812 });else if (inputDate instanceof Date || typeof inputDate === "number") dates = [self.parseDate(inputDate, format)];else if (typeof inputDate === "string") { 1813 switch (self.config.mode) { 1814 case "single": 1815 case "time": 1816 dates = [self.parseDate(inputDate, format)]; 1817 break; 1818 1819 case "multiple": 1820 dates = inputDate.split(self.config.conjunction).map(function (date) { 1821 return self.parseDate(date, format); 1822 }); 1823 break; 1824 1825 case "range": 1826 dates = inputDate.split(self.l10n.rangeSeparator).map(function (date) { 1827 return self.parseDate(date, format); 1828 }); 1829 break; 1830 1831 default: 1832 break; 1833 } 1834 } else self.config.errorHandler(new Error("Invalid date supplied: " + JSON.stringify(inputDate))); 1835 self.selectedDates = dates.filter(function (d) { 1836 return d instanceof Date && isEnabled(d, false); 1837 }); 1838 if (self.config.mode === "range") self.selectedDates.sort(function (a, b) { 1839 return a.getTime() - b.getTime(); 1840 }); 1841 } 1842 1843 function setDate(date, triggerChange, format) { 1844 if (triggerChange === void 0) { 1845 triggerChange = false; 1846 } 1847 1848 if (format === void 0) { 1849 format = self.config.dateFormat; 1850 } 1851 1852 if (date !== 0 && !date || date instanceof Array && date.length === 0) return self.clear(triggerChange); 1853 setSelectedDate(date, format); 1854 self.showTimeInput = self.selectedDates.length > 0; 1855 self.latestSelectedDateObj = self.selectedDates[0]; 1856 self.redraw(); 1857 jumpToDate(); 1858 setHoursFromDate(); 1859 updateValue(triggerChange); 1860 if (triggerChange) triggerEvent("onChange"); 1861 } 1862 1863 function parseDateRules(arr) { 1864 return arr.slice().map(function (rule) { 1865 if (typeof rule === "string" || typeof rule === "number" || rule instanceof Date) { 1866 return self.parseDate(rule, undefined, true); 1867 } else if (rule && typeof rule === "object" && rule.from && rule.to) return { 1868 from: self.parseDate(rule.from, undefined), 1869 to: self.parseDate(rule.to, undefined) 1870 }; 1871 1872 return rule; 1873 }).filter(function (x) { 1874 return x; 1875 }); 1876 } 1877 1878 function setupDates() { 1879 self.selectedDates = []; 1880 self.now = self.parseDate(self.config.now) || new Date(); 1881 var preloadedDate = self.config.defaultDate || ((self.input.nodeName === "INPUT" || self.input.nodeName === "TEXTAREA") && self.input.placeholder && self.input.value === self.input.placeholder ? null : self.input.value); 1882 if (preloadedDate) setSelectedDate(preloadedDate, self.config.dateFormat); 1883 var initialDate = self.selectedDates.length > 0 ? self.selectedDates[0] : self.config.minDate && self.config.minDate.getTime() > self.now.getTime() ? self.config.minDate : self.config.maxDate && self.config.maxDate.getTime() < self.now.getTime() ? self.config.maxDate : self.now; 1884 self.currentYear = initialDate.getFullYear(); 1885 self.currentMonth = initialDate.getMonth(); 1886 if (self.selectedDates.length > 0) self.latestSelectedDateObj = self.selectedDates[0]; 1887 if (self.config.minTime !== undefined) self.config.minTime = self.parseDate(self.config.minTime, "H:i"); 1888 if (self.config.maxTime !== undefined) self.config.maxTime = self.parseDate(self.config.maxTime, "H:i"); 1889 self.minDateHasTime = !!self.config.minDate && (self.config.minDate.getHours() > 0 || self.config.minDate.getMinutes() > 0 || self.config.minDate.getSeconds() > 0); 1890 self.maxDateHasTime = !!self.config.maxDate && (self.config.maxDate.getHours() > 0 || self.config.maxDate.getMinutes() > 0 || self.config.maxDate.getSeconds() > 0); 1891 Object.defineProperty(self, "showTimeInput", { 1892 get: function get() { 1893 return self._showTimeInput; 1894 }, 1895 set: function set(bool) { 1896 self._showTimeInput = bool; 1897 if (self.calendarContainer) toggleClass(self.calendarContainer, "showTimeInput", bool);
1898 self.isOpen && positionCalendar(); 1899 } 1900 }); 1901 } 1902 1903 function setupInputs() { 1904 self.input = self.config.wrap ? element.querySelector("[data-input]") : element; 1905 1906 if (!self.input) { 1907 self.config.errorHandler(new Error("Invalid input element specified")); 1908 return; 1909 } 1910 1911 self.input._type = self.input.type; 1912 self.input.type = "text"; 1913 self.input.classList.add("customDatepicker-input"); 1914 self._input = self.input; 1915 1916 if (self.config.altInput) { 1917 self.altInput = createElement(self.input.nodeName, self.input.className + " " + self.config.altInputClass); 1918 self._input = self.altInput; 1919 self.altInput.placeholder = self.input.placeholder; 1920 self.altInput.disabled = self.input.disabled; 1921 self.altInput.required = self.input.required; 1922 self.altInput.tabIndex = self.input.tabIndex; 1923 self.altInput.type = "text"; 1924 self.input.setAttribute("type", "hidden"); 1925 if (!self.config.static && self.input.parentNode) self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling); 1926 } 1927 1928 if (!self.config.allowInput) self._input.setAttribute("readonly", "readonly"); 1929 self._positionElement = self.config.positionElement || self._input; 1930 } 1931 1932 function setupMobile() { 1933 var inputType = self.config.enableTime ? self.config.noCalendar ? "time" : "datetime-local" : "date"; 1934 self.mobileInput = createElement("input", self.input.className + " customDatepicker-mobile"); 1935 self.mobileInput.step = self.input.getAttribute("step") || "any"; 1936 self.mobileInput.tabIndex = 1; 1937 self.mobileInput.type = inputType; 1938 self.mobileInput.disabled = self.input.disabled; 1939 self.mobileInput.required = self.input.required; 1940 self.mobileInput.placeholder = self.input.placeholder; 1941 self.mobileFormatStr = inputType === "datetime-local" ? "Y-m-d\\TH:i:S" : inputType === "date" ? "Y-m-d" : "H:i:S"; 1942 1943 if (self.selectedDates.length > 0) { 1944 self.mobileInput.defaultValue = self.mobileInput.value = self.formatDate(self.selectedDates[0], self.mobileFormatStr); 1945 } 1946 1947 if (self.config.minDate) self.mobileInput.min = self.formatDate(self.config.minDate, "Y-m-d"); 1948 if (self.config.maxDate) self.mobileInput.max = self.formatDate(self.config.maxDate, "Y-m-d"); 1949 self.input.type = "hidden"; 1950 if (self.altInput !== undefined) self.altInput.type = "hidden"; 1951 1952 try { 1953 if (self.input.parentNode) self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling); 1954 } catch (_a) {} 1955 1956 bind(self.mobileInput, "change", function (e) { 1957 self.setDate(e.target.value, false, self.mobileFormatStr); 1958 triggerEvent("onChange"); 1959 triggerEvent("onClose"); 1960 }); 1961 } 1962 1963 function toggle(e) { 1964 if (self.isOpen === true) return self.close(); 1965 self.open(e); 1966 } 1967 1968 function triggerEvent(event, data) { 1969 if (self.config === undefined) return; 1970 var hooks = self.config[event]; 1971 1972 if (hooks !== undefined && hooks.length > 0) { 1973 for (var i = 0; hooks[i] && i < hooks.length; i++) { 1974 hooks[i](self.selectedDates, self.input.value, self, data); 1975 } 1976 } 1977 1978 if (event === "onChange") { 1979 self.input.dispatchEvent(createEvent("change")); 1980 self.input.dispatchEvent(createEvent("input")); 1981 } 1982 } 1983 1984 function createEvent(name) { 1985 var e = document.createEvent("Event"); 1986 e.initEvent(name, true, true); 1987 return e; 1988 } 1989 1990 function isDateSelected(date) { 1991 for (var i = 0; i < self.selectedDates.length; i++) { 1992 if (compareDates(self.selectedDates[i], date) === 0) return "" + i; 1993 } 1994 1995 return false; 1996 } 1997 1998 function isDateInRange(date) { 1999 if (self.config.mode !== "range" || self.selectedDates.length < 2) return false; 2000 return compareDates(date, self.selectedDates[0]) >= 0 && compareDates(date, self.selectedDates[1]) <= 0; 2001 } 2002 2003 function updateNavigationCurrentMonth() { 2004 if (self.config.noCalendar || self.isMobile || !self.monthNav) return;
2005 self.yearElements.forEach(function (yearElement, i) { 2006 var d = new Date(self.currentYear, self.currentMonth, 1); 2007 d.setMonth(self.currentMonth + i); 2008 self.monthElements[i].textContent = monthToStr(d.getMonth(), self.config.shorthandCurrentMonth, self.l10n) + " "; 2009 yearElement.value = d.getFullYear().toString(); 2010 }); 2011 self._hidePrevMonthArrow = self.config.minDate !== undefined && (self.currentYear === self.config.minDate.getFullYear() ? self.currentMonth <= self.config.minDate.getMonth() : self.currentYear < self.config.minDate.getFullYear()); 2012 self._hideNextMonthArrow = self.config.maxDate !== undefined && (self.currentYear === self.config.maxDate.getFullYear() ? self.currentMonth + 1 > self.config.maxDate.getMonth() : self.currentYear > self.config.maxDate.getFullYear()); 2013 } 2014 2015 function getDateStr(format) { 2016 return self.selectedDates.map(function (dObj) { 2017 return self.formatDate(dObj, format); 2018 }).filter(function (d, i, arr) { 2019 return self.config.mode !== "range" || self.config.enableTime || arr.indexOf(d) === i; 2020 }).join(self.config.mode !== "range" ? self.config.conjunction : self.l10n.rangeSeparator); 2021 } 2022 2023 function updateValue(triggerChange) { 2024 if (triggerChange === void 0) { 2025 triggerChange = true; 2026 } 2027 2028 if (self.selectedDates.length === 0) return self.clear(triggerChange); 2029 2030 if (self.mobileInput !== undefined && self.mobileFormatStr) { 2031 self.mobileInput.value = self.latestSelectedDateObj !== undefined ? self.formatDate(self.latestSelectedDateObj, self.mobileFormatStr) : ""; 2032 } 2033 2034 self.input.value = getDateStr(self.config.dateFormat); 2035 2036 if (self.altInput !== undefined) { 2037 self.altInput.value = getDateStr(self.config.altFormat); 2038 } 2039 2040 if (triggerChange !== false) triggerEvent("onValueUpdate"); 2041 } 2042 2043 function onMonthNavClick(e) { 2044 e.preventDefault(); 2045 var isPrevMonth = self.prevMonthNav.contains(e.target); 2046 var isNextMonth = self.nextMonthNav.contains(e.target); 2047 2048 if (isPrevMonth || isNextMonth) { 2049 changeMonth(isPrevMonth ? -1 : 1); 2050 } else if (self.yearElements.indexOf(e.target) >= 0) { 2051 e.target.select(); 2052 } else if (e.target.classList.contains("arrowUp")) { 2053 self.changeYear(self.currentYear + 1); 2054 } else if (e.target.classList.contains("arrowDown")) { 2055 self.changeYear(self.currentYear - 1); 2056 } 2057 } 2058 2059 function timeWrapper(e) { 2060 e.preventDefault(); 2061 var isKeyDown = e.type === "keydown", 2062 input = e.target; 2063 2064 if (self.amPM !== undefined && e.target === self.amPM) { 2065 self.amPM.textContent = self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])]; 2066 } 2067 2068 var min = parseFloat(input.getAttribute("data-min")), 2069 max = parseFloat(input.getAttribute("data-max")), 2070 step = parseFloat(input.getAttribute("data-step")), 2071 curValue = parseInt(input.value, 10), 2072 delta = e.delta || (isKeyDown ? e.which === 38 ? 1 : -1 : 0); 2073 var newValue = curValue + step * delta; 2074 2075 if (typeof input.value !== "undefined" && input.value.length === 2) { 2076 var isHourElem = input === self.hourElement, 2077 isMinuteElem = input === self.minuteElement; 2078 2079 if (newValue < min) { 2080 newValue = max + newValue + int(!isHourElem) + (int(isHourElem) && int(!self.amPM)); 2081 if (isMinuteElem) incrementNumInput(undefined, -1, self.hourElement); 2082 } else if (newValue > max) { 2083 newValue = input === self.hourElement ? newValue - max - int(!self.amPM) : min; 2084 if (isMinuteElem) incrementNumInput(undefined, 1, self.hourElement); 2085 } 2086 2087 if (self.amPM && isHourElem && (step === 1 ? newValue + curValue === 23 : Math.abs(newValue - curValue) > step)) { 2088 self.amPM.textContent = self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])]; 2089 } 2090 2091 input.value = pad(newValue); 2092 } 2093 } 2094 2095 init(); 2096 return self; 2097 } 2098 2099 function _customDatepicker(nodeList, config) { 2100 var nodes = Array.prototype.slice.call(nodeList); 2101 var instances = []; 2102 2103 for (var i = 0; i < nodes.length; i++) { 2104 var node = nodes[i]; 2105 2106 try { 2107 if (node.getAttribute("data-fp-omit") !== null) continue; 2108 2109 if (node._customDatepicker !== undefined) { 2110 node._customDatepicker.destroy(); 2111 2112 node._customDatepicker = undefined; 2113 } 2114 2115 node._customDatepicker = FlatpickrInstance(node, config || {}); 2116 instances.push(node._customDatepicker); 2117 } catch (e) { 2118 console.error(e); 2119 } 2120 } 2121 2122 return instances.length === 1 ? instances[0] : instances; 2123 } 2124 2125 if (typeof HTMLElement !== "undefined") { 2126 HTMLCollection.prototype.customDatepicker = NodeList.prototype.customDatepicker = function (config) { 2127 return _customDatepicker(this, config); 2128 }; 2129 2130 HTMLElement.prototype.customDatepicker = function (config) { 2131 return _customDatepicker([this], config); 2132 }; 2133 } 2134 2135 var customDatepicker = function customDatepicker(selector, config) { 2136 if (selector instanceof NodeList) return _customDatepicker(selector, config);else if (typeof selector === "string") return _customDatepicker(window.document.querySelectorAll(selector), config); 2137 return _customDatepicker([selector], config); 2138 }; 2139 2140 customDatepicker.defaultConfig = defaults; 2141 customDatepicker.l10ns = { 2142 en: Object.assign({}, english), 2143 default: Object.assign({}, english) 2144 }; 2145 2146 customDatepicker.localize = function (l10n) { 2147 customDatepicker.l10ns.default = Object.assign({}, customDatepicker.l10ns.default, l10n); 2148 }; 2149 2150 customDatepicker.setDefaults = function (config) { 2151 customDatepicker.defaultConfig = Object.assign({}, customDatepicker.defaultConfig, config); 2152 }; 2153 2154 customDatepicker.parseDate = createDateParser({}); 2155 customDatepicker.formatDate = createDateFormatter({}); 2156 customDatepicker.compareDates = compareDates; 2157 2158 if (typeof jQuery !== "undefined") { 2159 jQuery.fn.customDatepicker = function (config) { 2160 return _customDatepicker(this, config); 2161 }; 2162 } 2163 2164 Date.prototype.fp_incr = function (days) { 2165 return new Date(this.getFullYear(), this.getMonth(), this.getDate() + (typeof days === "string" ? parseInt(days, 10) : days)); 2166 }; 2167 2168 if (typeof window !== "undefined") { 2169 window.customDatepicker = customDatepicker; 2170 } 2171 2172 return customDatepicker; 2173 2174}))); 2175 2176/* customDatepicker v4.5.2, @license MIT */ 2177(function (global, factory) { 2178 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 2179 typeof define === 'function' && define.amd ? define(['exports'], factory) : 2180 (factory((global.ru = {}))); 2181}(this, (function (exports) { 'use strict'; 2182 2183 var fp = typeof window !== "undefined" && window.customDatepicker !== undefined ? window.customDatepicker : { 2184 l10ns: {} 2185 }; 2186 var Russian = { 2187 weekdays: { 2188 shorthand: ["ÐÑ", "Ðн", "ÐÑ", "СÑ", "ЧÑ", "ÐÑ", "Сб"], 2189 longhand: ["ÐоÑкÑеÑенÑе", "ÐонеделÑник", "ÐÑоÑник", "СÑеда", "ЧеÑвеÑг", "ÐÑÑниÑа", "СÑббоÑа"] 2190 }, 2191 months: { 2192 shorthand: ["Янв", "Фев", "ÐаÑÑ", "ÐпÑ", "Ðай", "ÐÑнÑ", "ÐÑлÑ", "Ðвг", "Сен", "ÐкÑ", "ÐоÑ", "Ðек"], 2193 longhand: ["ЯнваÑÑ", "ФевÑалÑ", "ÐаÑÑ", "ÐпÑелÑ", "Ðай", "ÐÑнÑ", "ÐÑлÑ", "ÐвгÑÑÑ", "СенÑÑбÑÑ", "ÐкÑÑбÑÑ", "ÐоÑбÑÑ", "ÐекабÑÑ"] 2194 }, 2195 firstDayOfWeek: 1, 2196 ordinal: function ordinal() { 2197 return ""; 2198 }, 2199 rangeSeparator: " â ", 2200 weekAbbreviation: "Ðед.", 2201 scrollTitle: "ÐÑокÑÑÑиÑе Ð´Ð»Ñ ÑвелиÑениÑ", 2202 toggleTitle: "ÐажмиÑе Ð´Ð»Ñ Ð¿ÐµÑеклÑÑениÑ", 2203 amPM: ["ÐÐ", "ÐÐ"], 2204 yearAriaLabel: "Ðод" 2205 }; 2206 fp.l10ns.ru = Russian; 2207 var ru = fp.l10ns; 2208 2209 exports.Russian = Russian; 2210 exports.default = ru; 2211 2212 Object.defineProperty(exports, '__esModule', { value: true }); 2213 2214}))); 2215 2216 2217/** 2218 2219 ÐÐÐÐÐÐЫ 2220 2221*/ 2222 2223 2224 2225customDatepicker("#customDatepicker", { 2226 altInput: true, 2227 altFormat: "F j, Y", 2228 dateFormat: "F j, Y", 2229 locale: 'ru', 2230 disable: [ 2231 function(date) { 2232 var d = new Date(); 2233 return ( date <= d.setDate(d.getDate()-1) ); 2234 2235 } 2236], 2237 onChange: function(selectedDates, dateStr, instance, e) { 2238 2239 if( customFormValidation($('#customDatepicker')) ){ 2240 mainStepChange(true); 2241 } 2242 2243 2244 } 2245}); 2246 2247 2248 2249 2250$("[data-toggle=popover]") 2251.popover({html:true}) 2252 2253 2254/** 2255 2256 ÐÐÐ 2257 2258*/ 2259 2260 2261 2262$('html').bind('keydown', function(e) 2263{ 2264 2265 2266 if(e.keyCode == 13) 2267 { 2268 return false;
2269 } 2270 2271 2272}); 2273 2274var scrollStepG = 0; 2275var scrollStepOnceG = 0; 2276var dtsG; 2277changeTitle(0); 2278changeScale(0); 2279 2280 2281 2282$('.block__test_sub_step').first().addClass('active__step'); 2283 2284 2285function changeTitle(index){ 2286 2287 var title = $($('.block__test_sub_step')[index]).attr('data-title'); 2288 2289 if( typeof( title ) === 'undefined' ){ 2290 title = 'ÐаÑа заÑвка ÑÑпеÑно оÑпÑавлена на ÑаÑÑеÑ! ÐжидайÑе'; 2291 } 2292 2293 $('.block__test_sub_2 .h2').html(title); 2294 2295} 2296 2297function changeScale(index){ 2298 2299 var percent = $($('.block__test_sub_step')[index]).attr('data-percent'); 2300 2301 if( typeof( percent ) === 'undefined' ){ 2302 percent = 100; 2303 } 2304 2305 $('.block__test_sub_3_ready').children('span:eq(0)').text(' ' + percent); 2306 $('.block__test_sub_3_scale').children('span').css('width', percent + '%'); 2307 2308} 2309 2310function buttonActivity(buttons, active){ 2311 if( buttons ){ 2312 2313 buttons.forEach(function(button){ 2314 var $button = $('.' + button); 2315 active ? $button.removeClass('not-active').addClass('active') : $button.removeClass('active').addClass('not-active'); 2316 }); 2317 2318 } 2319 2320} 2321 2322 2323 2324 2325// обÑзаÑелÑ-необÑзаÑелÑно Ð´Ð»Ñ Ð¿ÐµÑвого Ñага
2326let stepObl1 = $($('.block__test_sub_step')[0]).attr('data-step'); 2327if( stepObl1 === 'true' ){ 2328 buttonActivity(['button-next' ], false); 2329}else{ 2330 buttonActivity(['button-next' ], true); 2331} 2332 2333 2334 2335 2336 2337function mainStepChange(next){ 2338 2339 scrollStepG = 0; 2340 scrollStepOnceG = 0; 2341 2342 // полÑÑаем акÑивнÑй блок Ñага 2343 var $stepBlock; 2344 $('.block__test_sub_step').each(function(e){ 2345 if( $(this).hasClass('active__step') ){ 2346 $stepBlock = $(this); 2347 } 2348 }) 2349 2350 2351 // еÑли ÑледÑÑÑего блока неÑ, Ñо акÑивнÑм ÑÑановиÑÑÑ ÑекÑÑий ( Ð´Ð»Ñ Ð¾Ð±ÑаÑнÑÑ Ñагов ) 2352 var a = $('.block__test_sub_step').length; 2353 if( typeof( $stepBlock) === 'undefined' ){ 2354 2355 $stepBlock = $('.block__test_sub_step')[a-1]; 2356 } 2357 2358 2359 // полÑÑаем Ð¸Ð½Ð´ÐµÐºÑ ÑекÑÑего ( акÑивного ) блока 2360 var index = $stepBlock.index(); 2361 2362 2363 2364 // добавлÑем ÐµÐ¼Ñ ÐºÐ»Ð°ÑÑ Ð°ÐºÑивноÑÑи 2365 $stepBlock.removeClass('active__step'); 2366 2367 // ÑоÑмиÑÑем Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð¾Ð²Ð¾Ð³Ð¾ блока ( ÑледÑÑÑего Ñага ) 2368 var indexNew = next ? ( index + 1 ) : ( index - 1 ) ; 2369 2370 2371 // Ñаг обÑзаÑелÑнÑй-необÑзаÑелÑнÑй 2372 let stepObl = $($('.block__test_sub_step')[indexNew]).attr('data-step'); 2373 2374 // менÑем заголовок и ÑÐºÐ°Ð»Ñ 2375 changeTitle(indexNew); 2376 changeScale(indexNew); 2377 2378 // полÑÑаем ÑледÑÑÑий блок в каÑ-ве ÐÐÐ - ÑлеменÑа 2379 var nextStepBlock = $('.block__test_sub_step')[indexNew]; 2380 2381 // ÑбиÑаем ÑекÑÑий блок --- 2382 setTimeout(function(){ 2383 $stepBlock.slideUp(); 2384 },300); 2385 // ------------------------ 2386 2387 // делаем акÑивнÑм обе кнопки 2388 buttonActivity(['button-next' , 'button-prev' ], true); 2389 2390 // заÑем ÑбиÑаем акÑивноÑÑÑ Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ Ðазад, еÑли возвÑÐ°Ñ Ðº 0 ÑÐ°Ð³Ñ 2391 if( indexNew === 0 ){ 2392 buttonActivity(['button-prev' ], false); 2393 } 2394 // ------------------------------------------------------------------------------------------ 2395 2396 // в поÑледнем Ñаге ÑбиÑаем ÑолÑко ÐºÐ½Ð¾Ð¿ÐºÑ Ðалее --- 2397 if( indexNew === ( a - 1 ) ){ 2398 $('.block__test_sub_5_btn').last().slideUp(); 2399 }else{ 2400 $('.block__test_sub_5_btn').last().slideDown(); 2401 } 2402 // ------------------------ ---------------------- 2403 2404 // добавлÑем клаÑÑ ÑÑÑекÑа молнии на кнопке Ðалее 2405 var $p = $('.button-next').parents(); 2406 $p.addClass('highlight'); 2407 // ----------------------------- 2408 2409 // еÑли не поÑледний Ñаг, Ñо пÑи пеÑÐµÑ Ð¾Ð´Ðµ на новÑй блок, ... 2410 if( typeof( nextStepBlock ) !== 'undefined' ){ 2411 2412 // ... ÑбиÑаем акÑивноÑÑÑ Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ Ðалее 2413 setTimeout(function(){ 2414 2415 2416 2417 // еÑли блок не обÑзаÑелÑнÑй, вÑÑÑавлÑем акÑивноÑÑÑ Ñнова ( next = true - ÑолÑко Ð´Ð»Ñ Ñага впеÑÑд ) 2418 2419 if( stepObl === 'true' && next ){ 2420 // кнопка Ðалее ÑÑановиÑÑÑ Ð°ÐºÑивной-не акÑивной поÑле валидаÑии блока, Ñ.е. неакÑивна, еÑли ниÑего не оÑмеÑено и наобоÑÐ¾Ñ 2421 if( !nextStepBlockValidation(nextStepBlock) ){ 2422 buttonActivity(['button-next' ], false); 2423 }else{ 2424 buttonActivity(['button-next' ], true); 2425 } 2426 }else{ 2427 buttonActivity(['button-next' ], true); 2428 } 2429 2430 },300); 2431 2432 // ... добавлÑем active__step Ð½Ð¾Ð²Ð¾Ð¼Ñ Ð¿Ð¾ÑвивÑемÑÑÑ Ð±Ð»Ð¾ÐºÑ Ð¸ коллбеком ÑбиÑаем клаÑÑ Ð¿Ð¾Ð´ÑвеÑки Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ Ðалее 2433 var $nextStepBlock = $(nextStepBlock); 2434 setTimeout(function(){ 2435 $nextStepBlock.addClass('active__step').slideDown(function(){ 2436 $p.removeClass('highlight'); 2437 2438 }); 2439 2440 },600) 2441 2442 2443 2444 }else{ 2445 console.log('last step'); 2446 return false;
2447 } 2448 2449 2450} 2451 2452 2453function nextStepBlockValidation(nextStepBlock){ 2454 var $nextStepBlock = $(nextStepBlock); 2455 var flag = false; 2456 2457 if( $nextStepBlock.hasClass('data-slider__block') || $nextStepBlock.hasClass('data-options__block') ){ 2458 $nextStepBlock.find('input[type=radio], input[type=checkbox]').each(function(){ 2459 2460 if( $(this).prop('checked') ){ 2461 2462 flag = true; 2463 return false; 2464 } 2465 }); 2466 } 2467 2468 if( $nextStepBlock.hasClass('data-insert__block') ){ 2469 2470 $nextStepBlock.find("textarea[name^='step_'], input[name^='step_']").each(function(){ 2471 2472 if( $(this)[0].tagName === 'INPUT' ){ 2473 2474 if( $(this)[0].checkValidity() ){ 2475 flag = true; 2476 return false; 2477 } 2478 2479 }else 2480 if( $(this)[0].tagName === 'TEXTAREA' ){ 2481 2482 if( 0 < $(this).val().length){ 2483 flag = true; 2484 return false; 2485 } 2486 2487 } 2488 2489 2490 }); 2491 2492 } 2493 2494 2495 if( $nextStepBlock.hasClass('data-num__block') ){ 2496 2497 $nextStepBlock.find("input[type=number]").each(function(){ 2498 let val = $(this).val(); 2499 if( typeof val !== 'undefined' ){ 2500 val = parseFloat(val.trim()); 2501 if( val > 0 ){ 2502 flag = true; 2503 return false; 2504 } 2505 } 2506 2507 }) 2508 2509 } 2510 2511 2512 if( $nextStepBlock.hasClass('data-pic__block') ) { 2513 2514 if( gFileToServer ) return true; 2515 2516 } 2517 2518 return flag; 2519} 2520 2521function showTextIputs($this, checked){ 2522 2523 checked ? $this 2524 .closest('.block__test_sub_4_move_img') 2525 .find('input[type=text]') 2526 .slideDown() 2527 .focus() 2528 : $this 2529 .closest('.block__test_sub_4_move_img') 2530 .find('input[type=text]') 2531 .val('') 2532 .slideUp() 2533} 2534 2535 2536 2537function requiredStep($this){ 2538 2539 if( $this.closest('.block__test_sub_step').attr('data-step') === 'false' || 2540 typeof ( $this.closest('.block__test_sub_step').attr('data-step') ) === 'undefined' ) return false; 2541 else 2542 if ( $this.closest('.block__test_sub_step').attr('data-step') === 'true' ) return true; 2543} 2544 2545 2546 2547 2548$('.block__test_sub_4_move_img').find('input').on('change', function(){ 2549 2550 var flag = 0; 2551 $(this).closest('.block__test_sub_4_move').find('input').each(function(){ 2552 2553 if( $(this).prop('checked') ){ 2554 2555 $(this).siblings('.overlay').addClass('overlay__active'); 2556 flag++; 2557 2558 }else{ 2559 2560 $(this).siblings('.overlay').removeClass('overlay__active'); 2561 2562 } 2563 2564 }); 2565 2566 2567 2568 2569 if( $(this).attr('type') === 'radio' ){ 2570 2571 if( requiredStep($(this)) ) { 2572 2573 mainStepChange(true); 2574 2575 } 2576 2577 2578 2579 }else 2580 if( $(this).attr('type') === 'checkbox' ){ 2581 2582 showTextIputs($(this), $(this).prop('checked')); 2583 2584 if( requiredStep($(this)) ) { 2585 2586 if( flag > 0 ) { 2587 buttonActivity(['button-next' ], true); 2588 }else{ 2589 buttonActivity(['button-next' ], false); 2590 } 2591 2592 } 2593 2594 } 2595 2596 2597 2598 2599 2600}); 2601 2602 2603 2604/** 2605 2606 ÐÐÐÐÐРСÐÐÐÐÐРРблока data-slider__block 2607 2608*/ 2609 2610 2611function crossBrowserTranslateX(moveBlock, scale){ 2612 moveBlock.css("-webkit-transform",'translateX(-' + scale + 'px)') 2613 moveBlock.css("-moz-transform",'translateX(-' + scale + 'px)') 2614 moveBlock.css("-ms-transform",'translateX(-' + scale + 'px)') 2615 moveBlock.css("-o-transform",'translateX(-' + scale + 'px)') 2616 moveBlock.css("transform",'translateX(-' + scale + 'px)'); 2617} 2618 2619 2620$('.block__test_sub_4_slider_next').mousedown(function(){ 2621 2622const a = []; 2623 2624 2625 $(this).closest('.block__test_sub_4_slider').prev('.block__test_sub_4_slider_prev').fadeIn('fast'); 2626 var $moveBlock = $(this).closest('.block__test_sub_step').find('.block__test_sub_4_move'); 2627 $moveBlock.find('img').each(function(){ 2628 a.push($(this).width()); 2629 }); 2630 var moveLag = Math.min.apply(Math, a); 2631 var visibleBlockWidth = $moveBlock.width(); 2632 var blockFullWidth = $moveBlock[0].scrollWidth; 2633 // blockFullWidth - ÑиÑина блока пÑокÑÑÑки, Ñ.е. ÑиÑина вÑего блока вклÑÑÐ°Ñ Ð½ÐµÐ²Ð¸Ð´Ð¸Ð¼ÑÑ ÑаÑÑÑ 2634 var blockHiddenWidth = blockFullWidth - visibleBlockWidth; 2635 var visibleBlockWidth = visibleBlockWidth - moveLag / 1.50; 2636 2637 scrollStepG++; 2638 visibleBlockWidth *= scrollStepG; 2639 var scrollControll = blockHiddenWidth - visibleBlockWidth; 2640
2641 if( scrollControll <= 0 ){ 2642 scrollStepOnceG++; 2643 } 2644 2645 if( scrollStepOnceG > 1 ){ 2646 return false; 2647 } 2648 2649 if( scrollStepOnceG === 1 ){ 2650 visibleBlockWidth = blockHiddenWidth; 2651 } 2652 2653 crossBrowserTranslateX($moveBlock, visibleBlockWidth); 2654 2655}); 2656 2657$('.block__test_sub_4_slider_prev').mousedown(function(){ 2658 2659 var $moveBlock = $(this).closest('.block__test_sub_step').find('.block__test_sub_4_move'); 2660 2661 crossBrowserTranslateX($moveBlock, 0); 2662 2663 scrollStepG = 0; 2664 scrollStepOnceG = 0; 2665 2666}) 2667 2668 2669$('.button-prev').click(function(){ 2670 if( $(this).hasClass('not-active') ){ 2671 return false; 2672 } 2673 2674 mainStepChange(false); 2675 2676 2677}); 2678 2679$('.button-next').click(function(){ 2680 if( $(this).hasClass('not-active') ){ 2681 return false; 2682 } 2683 2684 mainStepChange(true); 2685 2686}); 2687 2688 2689$('.block__test_sub_4_step_2_options').on('change','input',function(){ 2690 2691 var flag = 0; 2692 2693 $(this).closest('.block__test_sub_4_step_2_options').find('input').each(function(){ 2694 2695 if( !$(this).prop('checked') ){ 2696 2697 $(this).siblings('div').children('span').removeClass('scale_full'); 2698 2699 2700 }else{ 2701 2702 $(this).siblings('div').children('span').addClass('scale_full'); 2703 flag++; 2704 2705 } 2706 2707 }); 2708 2709 if( requiredStep($(this)) ) { 2710 2711 2712 if( $(this).attr('type') === 'radio' ){ 2713 2714 mainStepChange(true); 2715 2716 }else 2717 if( $(this).attr('type') === 'checkbox' ){ 2718 2719 if( flag > 0 ) { 2720 buttonActivity(['button-next' ], true); 2721 }else{ 2722 buttonActivity(['button-next' ], false); 2723 } 2724 2725 } 2726 2727 } 2728 2729 2730}); 2731 2732 2733 2734$("textarea[name^='step_'], input[name^='step_'], .datepicker").on('input',function(e){ 2735 2736 if( customFormValidation($(this)) ){ 2737 buttonActivity(['button-next' ], true); 2738 }else{ 2739 if( requiredStep($(this)) ) { 2740 buttonActivity(['button-next' ], false); 2741 } 2742 2743 } 2744}); 2745 2746/** 2747 2748 ШÐРС ФÐТР2749 2750*/ 2751 2752let gFileToServer; 2753function previewFile() { 2754 let $preview = $('.add_file label[for="upload_pic"]'); 2755 fileToServer = $('#upload_pic')[0].files[0]; 2756 let reader = new FileReader(); 2757 2758 reader.onloadend = function () { 2759 2760 2761 $preview 2762 .attr('title','') 2763 .css({ 2764 'background': 'url(' + reader.result + ')', 2765 'background-repeat': 'no-repeat', 2766 'background-size': 'contain', 2767 'background-position': 'center' 2768 }).find('#remove_pic').removeClass('d-none'); 2769 2770 } 2771 2772 if (fileToServer) { 2773 reader.readAsDataURL(fileToServer); 2774 2775 gFileToServer = fileToServer; 2776 2777 buttonActivity(['button-next' ], true); 2778 2779 } 2780} 2781 2782 2783$('#upload_pic').change( function(e){ 2784 2785 previewFile(); 2786 2787 }) 2788 2789$('#remove_pic').click( function(e) { 2790 2791 e.preventDefault(); 2792 e.stopPropagation(); 2793 2794 2795 let $this = $(e.target); 2796 let $preview = $('.add_file label[for="upload_pic"]'); 2797 2798 $('#upload_pic').val(''); 2799 2800 $preview.css({ 2801 'background': '' 2802 }).find('#remove_pic').addClass('d-none'); 2803 2804 gFileToServer = ''; 2805 2806 buttonActivity(['button-next' ], false); 2807 2808}); 2809 2810/** 2811 2812 VALIDATION 2813 2814*/ 2815 2816var dtsG = {}; 2817 2818function customFormValidation($this){ 2819 2820 if( !requiredStep($this) ){ 2821 return true; 2822 } 2823 2824 var title = '<div class="error-text">' + $this.attr('title') + '</div>'; 2825 var maxlength = $this.attr('maxlength') * 1; // ÑолÑко Ð´Ð»Ñ textarea 2826 $this.siblings('.error-text').remove(); 2827 if( !$this[0].checkValidity() || $this.val() == 0 || $this.val().length >= maxlength ){ 2828 $this.removeClass('success-validation').addClass('error-validation'); 2829 $this[0].focus(); 2830 $this.after(title); 2831 return false; 2832 }else{ 2833 $this.removeClass('error-validation').addClass('success-validation'); 2834 return true; 2835 } 2836} 2837 2838function collectData(){ 2839 2840 var dts = {}, checkboxes = {}; 2841 2842 dts['sub-category'] = $('.block__test_sub_4').attr('data-sub-category'); 2843 2844 $('form#send_data').find('input, select').each(function(){ 2845 dts[$(this).attr('data-name')] = $(this).val(); 2846 }); 2847 2848
2849 $('.block__test_sub_4').find('.data-slider__block, .data-insert__block, .data-options__block, .data-num__block, .data-date__block').find('input, textarea').each(function(){ 2850 2851 2852 if( $(this)[0].tagName === 'INPUT' ){ 2853 2854 2855 if( $(this).attr('type') === 'radio' ){ 2856 2857 if( $(this).prop('checked') ){ 2858 var name = $(this).attr('data-name'); 2859 if( typeof( name ) !== 'undefined' ){ 2860 dts[name] = $(this).val(); 2861 } 2862 } 2863 2864 }else 2865 if( $(this).attr('type') === 'text' || $(this).attr('type') === 'number' || $(this).attr('type') === 'hidden' ){ 2866 if( $(this).val().trim() != '' ){ 2867 var name = $(this).attr('data-name'); 2868 if( typeof( name ) !== 'undefined' ){ 2869 dts[name] = $(this).val(); 2870 } 2871 } 2872 2873 } 2874 }else 2875 if( $(this)[0].tagName === 'TEXTAREA' ){ 2876 2877 if( $(this).val().trim() != '' ){ 2878 var name = $(this).attr('data-name'); 2879 if( typeof( name ) !== 'undefined' ){ 2880 dts[name] = $(this).val(); 2881 } 2882 } 2883 2884 } 2885 2886 2887 2888 }) 2889 2890 2891 // ÑекбокÑÑ ÑобиÑаем в оÑделÑнÑй маÑÑив - data-slider__block 2892 $('.data-slider__block').each(function(){ 2893 var title = $(this).attr('data-name'); 2894 var a = []; 2895 $(this).find("input[type='checkbox']").each(function(){ 2896 if($(this).prop('checked') ){ 2897 var b = {}; 2898 b['checkbox'] = $(this).attr('data-name'); 2899 var inputVal = $(this).closest('.block__test_sub_4_move_img').find('input[type=text]').val(); 2900 if( inputVal ){ 2901 if( inputVal.trim() != '' ){ 2902 b['text'] = inputVal.trim(); 2903 } 2904 } 2905 a.push(b); 2906 } 2907 }); 2908 if( typeof( title ) !== 'undefined' ){ 2909 dts[title] = a; 2910 } 2911 }); 2912 2913 2914 // ÑекбокÑÑ ÑобиÑаем в оÑделÑнÑй маÑÑив - data-options__block 2915 $('.data-options__block').each(function(){ 2916 var title = $(this).attr('data-title'); 2917 var a = []; 2918 $(this).find("input[type='checkbox']").each(function(){ 2919 if($(this).prop('checked') ){ 2920 var b = {}; 2921 b['checkbox'] = $(this).attr('data-name'); 2922 b['text'] = $(this).val(); 2923 a.push(b); 2924 } 2925 }); 2926 if( typeof( title ) !== 'undefined' ){ 2927 dts[title] = a; 2928 } 2929 }); 2930 2931 2932 return dts; 2933 2934} 2935 2936 2937jQuery("input[name=final_tel]").inputmask("+7 (999) 999-99-99"); 2938 2939$("input[name^='final_']").on('input',function(){ 2940 customFormValidation($(this)); 2941}); 2942 2943$("select[name^='final_']").on('change',function(){ 2944 customFormValidation($(this)); 2945}); 2946 2947 2948$('form#send_data').on('submit',function(e){ 2949 2950 e.preventDefault(); 2951 2952 var validity; 2953 2954 $(this).closest('form').find('input, select').each(function(){ 2955 validity = customFormValidation($(this)); 2956 return validity ? true : false; 2957 }); 2958 if( !validity ) return false; 2959 2960 2961 var dts = collectData(); 2962 2963 let data = new FormData(); 2964 2965 if( typeof gFileToServer !== 'undefined' ) data.append('file', gFileToServer); 2966 2967 data.append('post', $.param(dts)); 2968 2969 dtsG = dts; 2970 2971 $.ajax({ 2972 type: "POST", 2973 url: "processing/action_page.php", 2974 data: data, 2975 cache: false, 2976 contentType: false, 2977 processData: false, 2978 beforeSend: function(){ 2979 $('form#send_data').hide(); 2980 $('.button-prev').slideUp(); 2981 $('.block__test_sub_4_step_3_form').prepend('<div class="ajax__preloader"><img src="https://maykopm.ru/images/preloader.gif" /></div>'); 2982 //$('#additional__block').children('h3').children('span').text(dts['ÐÐ¼Ñ ÐºÐ»Ð¸ÐµÐ½Ñа']); 2983 //$('#additional__block').fadeIn(); 2984 }, 2985 success: function(data){ 2986 2987 console.log('data: ',data); 2988 2989 if( data[0] === true ){ 2990 2991 var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" fill="#48B437" viewBox="0 0 24 24">
2991<path d="M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z"/></svg>'; 2992 setTimeout(function(){ 2993 $('.ajax__preloader').html(svg); 2994 changeScale(100); 2995 changeTitle(100); 2996 $('.block__test_sub_3_scale span').css({ 2997 'border-top-right-radius': '5px', 2998 'border-bottom-right-radius': '5px', 2999 }); 3000 },500); 3001 3002 }else{ 3003 3004 var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" fill="#48B437" viewBox="0 0 24 24"><path d="M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z"/></svg>'; 3005 setTimeout(function(){ 3006 $('.ajax__preloader').html(svg); 3007 changeScale(100); 3008 changeTitle(100); 3009 $('.block__test_sub_3_scale span').css({ 3010 'border-top-right-radius': '5px', 3011 'border-bottom-right-radius': '5px', 3012 }); 3013 },500); 3014 3015 } 3016 3017 }, 3018 3019 error: function(error){ 3020 console.log(error); 3021 console.log(error.responseText); 3022 }, 3023 complete: function(data){}, 3024 }); // ÐºÐ¾Ð½ÐµÑ Ð¾ÑпÑавки на ÑеÑÐ²ÐµÑ 3025 3026 3027}); 3028 3029$('form#feedback').find('textarea').on('input', function(){ 3030 if( !$(this)[0].checkValidity() || $(this).val().trim() == '' ){ 3031 $(this).removeClass('is-valid').addClass('is-invalid') 3032 return false; 3033 }else{ 3034 $(this).removeClass('is-invalid').addClass('is-valid'); 3035 } 3036}) 3037 3038$('form#feedback').on('submit',function(e){ 3039 3040 e.preventDefault(); 3041 3042 var $this = $(this); 3043 var $textArea = $this.find('textarea'); 3044 3045 3046 if( !$textArea[0].checkValidity() || $textArea.val().trim() == '' ){ 3047 $textArea[0].focus(); 3048 $textArea.removeClass('is-valid').addClass('is-invalid') 3049 return false; 3050 } 3051 3052 var data = {}; 3053 3054 data['sub-category'] = dtsG['sub-category']; 3055 data['оÑзÑв'] = $(this).find('textarea').val(); 3056 3057 3058 3059 $.ajax({ 3060 type: "POST", 3061 url: "processing/feedback.php", 3062 data: data, 3063 beforeSend: function(){ 3064 $this.find('button[type=submit]').attr('disabled','disabled'); 3065 }, 3066 success: function(data){ 3067 3068 console.log('data: ',data); 3069 3070 if( data[0] === true ){ 3071 3072 3073 $this.slideUp(function(){ 3074 $this.prev('p').addClass('text-success').text('СпаÑибо за оÑзÑв'); 3075 }); 3076 3077 3078 }else{ 3079 3080 alert('ÐÑибка. ÐбÑаÑиÑеÑÑ Ðº ÑазÑабоÑÑикÑ'); 3081 3082 } 3083 3084 }, 3085 3086 error: function(error){ 3087 console.log(error); 3088 console.log(error.responseText); 3089 }, 3090 complete: function(data){}, 3091 }); // ÐºÐ¾Ð½ÐµÑ Ð¾ÑпÑавки на ÑеÑÐ²ÐµÑ 3092 3093 3094}); 3095 3096 3097$('body').on('click','button.add, button.sub',function(){ 3098 3099 if( customFormValidation($(this).closest('fieldset').find('input[type=number]')) ){ 3100 buttonActivity(['button-next' ], true); 3101 }else{ 3102 buttonActivity(['button-next' ], false); 3103 } 3104 3105 3106}); 3107 3108 3109$('body').on('keyup','input[type=number]',function(){ 3110 3111 if( customFormValidation($(this)) ){ 3112 buttonActivity(['button-next' ], true); 3113 }else{ 3114 buttonActivity(['button-next' ], false); 3115 } 3116 3117}); 3118 3119 3120/** 3121 3122 3123 ÐÐСТÐÐÐÐÐ ÐÐÐÐ ÐÐÐÐРЦÐФР3124 3125 3126*/ 3127 3128 3129/** 3130 * @class 3131 * @function Quantity 3132 * @param {DOMobject} element to create a quantity wrapper around 3133 */ 3134class QuantityInput { 3135 constructor(self, decreaseText, increaseText) { 3136 // Create input 3137 this.input = document.createElement('input'); 3138 this.input.value = 0; 3139 this.input.type = 'number'; 3140 this.input.name = 'quantity'; 3141 this.input.title = 'ЦелÑе или ÑеÑез запÑÑÑÑ. ЧиÑла болÑÑе 0'; 3142 self 3143 this.input.setAttribute('data-name', self.getAttribute('data-name')); 3144 this.input.pattern = '(\d+)|(\d+(\.|,)\d+)'; 3145 this.input.step= '0.01'; 3146 3147 // Get text for buttons 3148 this.decreaseText = decreaseText || 'Decrease quantity'; 3149 this.increaseText = increaseText || 'Increase quantity'; 3150 3151 // Button constructor 3152 function Button(text, className){ 3153 this.button = document.createElement('button'); 3154 this.button.type = 'button'; 3155 this.button.innerHTML = text; 3156 this.button.title = text; 3157 this.button.classList.add(className); 3158 3159 return this.button; 3160 } 3161 3162 // Create buttons 3163 this.subtract = new Button(this.decreaseText, 'sub'); 3164 this.add = new Button(this.increaseText, 'add'); 3165 3166 // Add functionality to buttons 3167 this.subtract.addEventListener('click', () => this.change_quantity(-1)); 3168 this.add.addEventListener('click', () => this.change_quantity(1)); 3169 3170 // Add input and buttons to wrapper 3171 self.appendChild(this.subtract); 3172 self.appendChild(this.input); 3173 self.appendChild(this.add); 3174 } 3175 3176 change_quantity(change) { 3177 3178 // Get current value 3179 let quantity = parseFloat(this.input.value); 3180 3181 if( quantity < 0 ) return false;
3182 3183 // Ensure quantity is a valid number 3184 if (isNaN(quantity)) quantity = 1; 3185 3186 // Change quantity 3187 quantity += change; 3188 3189 quantity = parseFloat(quantity).toFixed(1); 3190 3191 // Ensure quantity is always a number 3192 quantity = Math.max(quantity, 1); 3193 3194 // Output number 3195 this.input.value = quantity; 3196 3197 } 3198} 3199 3200 3201 3202// Set up quantity forms 3203(function(){ 3204 let quantities = document.querySelectorAll('[data-quantity]'); 3205 /* 3206 quantities instanceof Node - пÑовеÑÑеÑ, Ñвл ли quantities об-Ñом клаÑÑа Node 3207 3208 ??? ÐÐЯ ЧÐÐÐ. ЧТÐÐЫ ÐÐÐÐÐ ÐЫÐÐ ÐСÐÐÐЬÐÐÐÐТЬ Ð NODE.JS ??? 3209 3210 3211 */ 3212 if (quantities instanceof Node) quantities = [quantities]; 3213 /* 3214 [].slice.call(quantities) - ÑокÑаÑÑÐ½Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑ 3215 пÑеобÑазование маÑÑивоподобного об-Ñа ( или коллекÑии ) в маÑÑив 3216 подÑобно: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/slice 3217 3218 аналог Ð´Ð»Ñ quantities = [].slice.call(quantities) : quantities = Array.from(quantities); 3219 3220 */ 3221 if (quantities instanceof NodeList) quantities = [].slice.call(quantities); 3222 if (quantities instanceof Array) { 3223 /* 3224 3225 1) forEach(div => (div - ТРÐРСÐÐÐÐ, ЧТРdiv Ñо Ñкобками: forEach( (div) => (div 3226 3227 2) заÑем Ñо ÑоздаÑм Ñв-во div.quantity ( код ÑабоÑÐ°ÐµÑ Ð¸ без него, еÑли Ð¼Ñ Ð¿ÑоÑÑо в div ÑÐ¾Ñ ÑанÑем ) 3228 3229 */ 3230 quantities.forEach(div => (div.quantity = new QuantityInput(div, 'Ðниз', 'ÐвеÑÑ '))); 3231 } 3232})(); 3233 3234 3235 3236/** 3237 3238 3239 Beuty Scroll like 3240 3241 3242*/ 3243 3244var ticking = false; 3245 3246const defaultScroll = function (e) { 3247 e.preventDefault(); 3248 if (!ticking) { 3249 let el = this; 3250 window.requestAnimationFrame(function () { 3251 el.scrollLeft += e.deltaY; 3252 console.log(el.scrollLeft, el.scrollWidth, el.parentNode.clientWidth, el.parentNode.offsetWidth); 3253 ticking = false; 3254 }); 3255 3256 ticking = true; 3257 } 3258}; 3259 3260class customScroll { 3261 constructor(elembase, elemhidden) { 3262 this.el = elemhidden; 3263 this.container = elembase; 3264 elembase.appendChild(document.createElement('div')).classList.add('scrollbar-track'); 3265 elembase.appendChild(document.createElement('div')).classList.add('scrollbar-thumb'); 3266 elemhidden.style.width = elemhidden.scrollWidth + 'px'; 3267 elembase.addEventListener('wheel', this.scroll.bind(this), { passive: true }); 3268 } 3269 3270 scroll(e) { 3271 e.preventDefault(); 3272 if (!ticking) { 3273 window.requestAnimationFrame(function () { 3274 console.log('scroll', this); 3275 let curTranslate = 3276 +this.el.style.transform.replace(/[^-0-9.]/g, ''); 3277 let setTranslate = curTranslate - e.deltaY; 3278 let maxPossibleTranslate = this.el.scrollWidth - this.container.clientWidth; 3279 if (setTranslate > 0) setTranslate = 0;else 3280 if (setTranslate < -maxPossibleTranslate) 3281 setTranslate = -maxPossibleTranslate; 3282 this.el.style.transform = 3283 'translateX(' + setTranslate + 'px)'; 3284 let newTranslate = this.el.style.transform; 3285 console.log(newTranslate, this.el.scrollWidth, this.container.clientWidth, this.container.offsetWidth); 3286 ticking = false; 3287 }); 3288 3289 ticking = true; 3290 3291 } 3292 }} 3293 3294 3295window.addEventListener('load', function () { 3296 const elem = document.querySelector('.block__test_sub_4'); 3297 const elemhidden = document.querySelector('.customscroll'); 3298 3299 3300 if (elem) elem.addEventListener('wheel', defaultScroll.bind(elem)); 3301 if (elemhidden) 3302 custScroll = new customScroll(elemhidden.parentNode, elemhidden); 3303 3304 3305 3306 3307}); 3308 3309 3310/** 3311 3312 3313 SUN 3314 3315 3316*/ 3317 3318 function setSunNight() { 3319 3320 var dt = new Date(); 3321 var current = dt.getHours(); 3322 3323 if(current >= 18 && current < 21) { // Ñ 18:00 до 21:00 3324 $('.time-block').css('display', 'flex'); 3325 $('.time-text').addClass('luna-text'); 3326 $('.time-text > div').html('Ðа двоÑе веÑеÑ. Ð ÑÐ¾Ð¶Ð°Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐºÐ¾ÑоÑÑе компании ÑейÑÐ°Ñ Ð½Ðµ ÑабоÑаÑÑ.<br>ÐÑ Ð¼Ð¾Ð¶ÐµÑе ÑоздаÑÑ Ð·Ð°ÑвкÑ, но обÑабоÑаÑÑ ÐµÐµ в ÑабоÑие ÑаÑÑ. СпаÑибо!'); 3327 $('.time-image').html('<img src="img/evening.png">'); 3328 return true; 3329 }else 3330 3331 if( ( current >= 0 && current < 4 ) || current >= 21 ) { // Ñ 21:00 до 04:00 3332 $('.time-block').css('display', 'flex'); 3333 $('.time-text').addClass('luna-text'); 3334 $('.time-text > div').html('Ðа двоÑе ноÑÑ. Ð ÑÐ¾Ð¶Ð°Ð»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ð¸ ÑейÑÐ°Ñ Ð½Ðµ ÑабоÑаÑÑ.<br>ÐÑ Ð¼Ð¾Ð¶ÐµÑе ÑоздаÑÑ Ð·Ð°ÑвкÑ, но обÑабоÑаÑÑ ÐµÐµ в ÑабоÑие ÑаÑÑ. СпаÑибо!'); 3335 $('.time-image').html('<img src="img/luna.png">'); 3336 return true; 3337 }else 3338 3339 if(current >= 4 && current <= 9) { // Ñ 04:00 до 09:00 3340 $('.time-block').css('display', 'flex'); 3341 $('.time-text').addClass('sun-text'); 3342 $('.time-text > div').html('Ðа двоÑе Ñанее ÑÑÑо. Ð ÑÐ¾Ð¶Ð°Ð»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ð¸ ÑейÑÐ°Ñ Ð½Ðµ ÑабоÑаÑÑ.<br>ÐÑ Ð¼Ð¾Ð¶ÐµÑе ÑоздаÑÑ Ð·Ð°ÑвкÑ, но обÑабоÑаÑÑ ÐµÐµ в ÑабоÑие ÑаÑÑ. СпаÑибо!'); 3343 $('.time-image').html('<img src="img/sun.png">'); 3344 return true; 3345 } 3346 3347 3348 } 3349 setSunNight();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.