UNPKG

@progress/kendo-ui

Version:

This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.

1,399 lines (1,398 loc) 54.4 kB
//#region ../src/kendo.timepicker.js const __meta__ = { id: "timepicker", name: "TimePicker", category: "web", description: "The TimePicker widget allows the end user to select a value from a list of predefined values or to type a new value.", depends: [ "calendar", "popup", "html.button", "label", "actionsheet" ] }; (function($, undefined) { var kendo = window.kendo, keys = kendo.keys, html = kendo.html, parse = kendo.parseDate, encode = kendo.htmlEncode, activeElement = kendo._activeElement, extractFormat = kendo._extractFormat, support = kendo.support, browser = support.browser, mediaQuery = kendo.mediaQuery, ui = kendo.ui, Widget = ui.Widget, OPEN = "open", CLOSE = "close", CHANGE = "change", ns = ".kendoTimePicker", CLICK = "click" + ns, DISABLED = "disabled", READONLY = "readonly", LI = "li", SPAN = "<span></span>", FOCUSED = "k-focus", HOVER = "k-hover", HOVEREVENTS = "mouseenter" + ns + " mouseleave" + ns, MOUSEDOWN = "mousedown" + ns, DEFAULT_HEIGHT = 200, MS_PER_MINUTE = 6e4, MS_PER_DAY = 864e5, SELECTED = "k-selected", STATEDISABLED = "k-disabled", ARIA_SELECTED = "aria-selected", ARIA_EXPANDED = "aria-expanded", ARIA_HIDDEN = "aria-hidden", ARIA_DISABLED = "aria-disabled", ARIA_READONLY = "aria-readonly", ARIA_ACTIVEDESCENDANT = "aria-activedescendant", ID = "id", isArray = Array.isArray, extend = $.extend, DATE = Date, TODAY = new DATE(), MODERN_RENDERING_TEMPLATE = ({ mainSize, messages, buttonSize, isAdaptive }) => "<div>" + `<div tabindex="0" class="k-timeselector ${mainSize}">` + "<div class=\"k-time-header\">" + "<span class=\"k-title\"></span>" + kendo.html.renderButton(`<button class="k-time-now" title="Select now" aria-label="Select now">${encode(messages.now)}</button>`, { fillMode: "flat", size: buttonSize }) + "</div>" + "<div class=\"k-time-list-container\">" + "<span class=\"k-time-highlight\"></span>" + "</div>" + "</div>" + (isAdaptive ? "" : NEW_RENDERING_FOOTER(buttonSize, messages)) + "</div>", NEW_RENDERING_FOOTER = (buttonSize, messages, isAdaptive) => isAdaptive ? kendo.html.renderButton(`<button class="k-time-cancel" title="Cancel changes" aria-label="Cancel changes">${encode(messages.cancel)}</button>`, { size: buttonSize }) + kendo.html.renderButton(`<button class="k-time-accept" title="Set time" aria-label="Set time">${encode(messages.set)}</button>`, { size: buttonSize, themeColor: "primary" }) : "<div class=\"k-time-footer k-actions k-actions-stretched k-actions-horizontal\">" + kendo.html.renderButton(`<button class="k-time-accept" title="Set time" aria-label="Set time">${encode(messages.set)}</button>`, { size: buttonSize, themeColor: "primary" }) + kendo.html.renderButton(`<button class="k-time-cancel" title="Cancel changes" aria-label="Cancel changes">${encode(messages.cancel)}</button>`, { size: buttonSize }) + "</div>", HIGHLIGHTCONTAINER = "<span class=\"k-time-highlight\"></span>"; TODAY = new Date(TODAY.getFullYear(), TODAY.getMonth(), TODAY.getDate(), 0, 0, 0); var TimeView = function(options) { var that = this, focusTime = options.focusTime, id = options.id; that.options = options; that._dates = []; that.bigScreenMQL = mediaQuery("large"); that.smallScreenMQL = mediaQuery("small"); if (that.options.adaptiveMode == "auto") { that.smallScreenMQL.onChange(function() { if (that.popup && kendo.isFunction(that.popup.fullscreen)) { that.popup.fullscreen(that.smallScreenMQL.mediaQueryList.matches); if (that.options.timeView && that.options.timeView.list === "scroll") { that.addTranslate(); that._updateRanges(); } } }); } that._createList(options.timeView && options.timeView.list === "scroll"); if (focusTime) { that._focusTime = new DATE(TODAY.getFullYear(), TODAY.getMonth(), TODAY.getDate(), focusTime.getHours(), focusTime.getMinutes(), focusTime.getSeconds()); } if (id) { that._timeViewID = id + "_timeview"; that._optionID = id + "_option_selected"; that.ul.attr(ID, that._timeViewID); } that._heightHandler = that._height.bind(that); that._popup(); }; TimeView.prototype = { _createList: function(scroll) { if (scroll) { this._createScrollList(); } else { this._createClassicRenderingList(); } }, _createScrollList: function() { var size = this.options.adaptiveMode != "auto" || this.bigScreenMQL.mediaQueryList.matches ? this.options.size : "large"; const isAdaptive = this.options.adaptiveMode === "auto" && !this.bigScreenMQL.mediaQueryList.matches; var templateOptions = $.extend({}, this.options, { mainSize: kendo.getValidCssClass("k-timeselector-", "size", size), buttonSize: size, isAdaptive }); this.popupContent = $(kendo.template(MODERN_RENDERING_TEMPLATE)(templateOptions)).on(MOUSEDOWN, preventDefault); this.list = this.popupContent.find(".k-timeselector"); const footerCancelSelector = isAdaptive ? ".k-actionsheet-footer button.k-time-cancel" : ".k-time-footer button.k-time-cancel"; const footerAcceptSelector = isAdaptive ? ".k-actionsheet-footer button.k-time-accept" : ".k-time-footer button.k-time-accept"; this.ul = this.list.find(".k-time-list-container"); this.list.on("click" + ns, ".k-time-header button.k-time-now", this._nowClickHandler.bind(this)); this.popupContent.on("click" + ns, footerCancelSelector, this._cancelClickHandler.bind(this)); this.popupContent.on("click" + ns, footerAcceptSelector, this._setClickHandler.bind(this)); this.list.on("mouseover" + ns, ".k-time-list-wrapper", this._mouseOverHandler.bind(this)); this.list.on("keydown" + ns, this._scrollerKeyDownHandler.bind(this)); }, _scrollerKeyDownHandler: function(e) { var that = this, key = e.keyCode, list = $(e.currentTarget).find(".k-time-list-wrapper.k-focus"), lists = that.list.find(".k-time-list-wrapper"), length = lists.length, index = lists.index(list), isRtl = kendo.support.isRtl(that.wrapper), itemHeight = getItemHeight(list.find(".k-item:visible").eq(0)), container = list.find(".k-time-container.k-content.k-scrollable"); if (!list.length) { return; } if (key == keys.RIGHT && !isRtl || key == keys.LEFT && isRtl) { if (index + 1 < length) { that._focusList(lists.eq(index + 1)); } } else if (key == keys.LEFT && !isRtl || key == keys.RIGHT && isRtl) { if (index - 1 >= 0) { that._focusList(lists.eq(index - 1)); } } else if (key == keys.UP) { container.scrollTop(container.scrollTop() - itemHeight); e.preventDefault(); } else if (key == keys.DOWN) { container.scrollTop(container.scrollTop() + itemHeight); e.preventDefault(); } else if (key === keys.ENTER) { that._setClickHandler(e); } else if (key === keys.ESC) { that._cancelClickHandler(e); } }, _mouseOverHandler: function(e) { this._focusList($(e.currentTarget)); }, _focusList: function(list) { this.list.find(".k-time-list-wrapper").removeClass(FOCUSED); list.addClass(FOCUSED); this.list.trigger("focus"); this._scrollTop = list.find(".k-scrollable").scrollTop(); }, _createClassicRenderingList: function() { var that = this; var listParent = $("<div class=\"k-list " + kendo.getValidCssClass("k-list-", "size", that.options.size) + "\"><div class=\"k-list-content\"><ul tabindex=\"-1\" role=\"listbox\" aria-hidden=\"true\" unselectable=\"on\" class=\"k-list-ul\"/></div></div>"); that.ul = listParent.find("ul").css({ overflow: support.kineticScrollNeeded ? "" : "auto" }).on(CLICK, LI, that._click.bind(that)).on("mouseenter" + ns, LI, function() { $(this).addClass(HOVER); }).on("mouseleave" + ns, LI, function() { $(this).removeClass(HOVER); }); that.list = $("<div class='k-list-container k-list-scroller' unselectable='on'/>").append(listParent).on(MOUSEDOWN, preventDefault); that.template = (data) => `<li tabindex="-1" role="option" class="k-list-item" unselectable="on"><span class="k-list-item-text">${data}</span></li>`; }, current: function(candidate) { var that = this, active = that.options.active; if (candidate !== undefined) { if (that._current) { that._current.removeClass(SELECTED); if (that._current && that._current.length) { that._current[0].removeAttribute(ID); that._current[0].removeAttribute(ARIA_SELECTED); } } if (candidate) { candidate = $(candidate).addClass(SELECTED).attr(ID, that._optionID).attr(ARIA_SELECTED, true); that.scroll(candidate[0]); } that._current = candidate; if (active) { active(candidate); } } else { return that._current; } }, _updateTitle: function() { this.list.find(".k-time-header > .k-title").html(kendo.toString(this._value, this.options.format, this.options.culture)); }, applyValue: function(value) { if (!value) { return; } var is12hourFormat = includes(this.options.format.toLowerCase(), "t"); var hours = value.getHours(); var minutes = value.getMinutes(); var seconds = value.getSeconds(); var designator; var indexAttr = kendo.attr("index"); var hoursList = this.ul.find("[" + indexAttr + "=\"1\"]"); var minutessList = this.ul.find("[" + indexAttr + "=\"2\"]"); var secondsList = this.ul.find("[" + indexAttr + "=\"3\"]"); var designatorList = this.ul.find("[" + indexAttr + "=\"4\"]"); if (is12hourFormat) { if (hours >= 12) { designator = "PM"; if (hours > 12) { hours -= 12; } } else { designator = "AM"; if (hours === 0) { hours = 12; } } } this._internalScroll = true; if (hoursList.length) { this._scrollListToPosition(hoursList, hours); } if (minutessList.length) { this._scrollListToPosition(minutessList, minutes); } if (secondsList.length) { this._scrollListToPosition(secondsList, seconds); } if (designatorList.length) { this._scrollListToPosition(designatorList, designator); } this._internalScroll = false; }, _scrollListToPosition: function(list, value) { var item = list.find(".k-item[data-value=\"" + pad(value) + "\"]"); var itemHeight = getItemHeight(item); list.scrollTop(list.find(".k-item:visible").index(item) * itemHeight); }, close: function() { if (this.popup) { this.popup.close(); } }, destroy: function() { var that = this; that.ul.off(ns); that.list.off(ns); if (that.popupContent) { that.popupContent.off(ns); } if (that.popup) { that.popup.destroy(); } if (that.bigScreenMQL) { that.bigScreenMQL.destroy(); } if (that.smallScreenMQL) { that.smallScreenMQL.destroy(); } }, open: function() { var that = this; var popupHovered; if (!that.ul[0].firstChild || that.ul.find("li").length < 1) { that.bind(); } if (that._focusTime) { that.value(that._focusTime); } popupHovered = that.popup._hovered; that.popup._hovered = true; that.popup.open(); setTimeout(function() { that.popup._hovered = popupHovered; }, 1); if (that._current) { that.scroll(that._current[0]); } }, dataBind: function(dates) { var that = this, options = that.options, format = options.format, toString = kendo.toString, template = that.template, length = dates.length, idx = 0, date, html = ""; for (; idx < length; idx++) { date = dates[idx]; if (isInRange(date, options.min, options.max)) { html += template(toString(date, format, options.culture)); } } that._html(html); }, refresh: function() { var that = this, options = that.options, format = options.format, offset = dst(), ignoreDST = offset < 0, value = kendo.parseDate(that._value), parsedValue = value ? mergeDateAndTime(value, options.min) : mergeDateAndTime(new Date(), options.min), min = options.min, max = options.max, msMin = getMilliseconds(min), msMax = getMilliseconds(max), msLastTime = getMilliseconds(lastTimeOption(options.interval)), msInterval = options.interval * MS_PER_MINUTE, toString = kendo.toString, template = that.template, start = options.useValueToRender ? parsedValue : new Date(+options.min), startDate = new DATE(start), msStart, length, html = ""; if (ignoreDST) { length = (MS_PER_DAY + offset * MS_PER_MINUTE) / msInterval; } else { length = MS_PER_DAY / msInterval; } if (msMin != msMax || msLastTime === msMax) { if (msMin > msMax) { msMax += MS_PER_DAY; } length = (msMax - msMin) / msInterval + 1; } if (options.timeView && options.timeView.list === "scroll") { html = that._createListContent(kendo.date.splitDateFormat(format), options.interval); } else { that.getDatesInRange(msStart, msMax, startDate, max, msInterval, start).forEach(function(date) { html += template(toString(date, format, options.culture)); }); } that._html(html); }, _showAllHiddenItems: function() { var items = this.list.find(".k-time-container"); var length = items.length; var item; for (var i = 0; i < length; i++) { item = $(items[i]); item.find(".k-item:hidden").show(); this._updateListBottomOffset(item); } }, _updateListBottomOffset: function(list) { var itemHeight = getItemHeight(list.find(".k-item:visible").eq(0)); var listHeight = list.outerHeight(); var bottomOffset = listHeight - itemHeight; list.find(".k-scrollable-placeholder").css({ height: list.find("ul").height() + bottomOffset }); }, _updateHoursRange: function() { var that = this; var indexAttr = kendo.attr("index"); var hoursList = this.ul.find("[" + indexAttr + "=\"1\"]"); var minHours = this._minHours; var maxHours = this._maxHours; var is12hourFormat = includes(this.options.format.toLowerCase(), "t"); var useMax; var useMin; var selectedDesignator = this._findSelectedValue(this.ul.find("[" + indexAttr + "=\"4\"]")); if (!hoursList.length) { return; } if (is12hourFormat && selectedDesignator) { if (selectedDesignator === "AM") { if (minHours < 12) { useMin = true; } if (maxHours < 12) { useMax = true; } } else if (selectedDesignator === "PM") { if (minHours > 12) { useMin = true; minHours -= 12; } if (maxHours > 12) { useMax = true; maxHours -= 12; } } hoursList.find(".k-item").each(function(_, item) { item = $(item); var value = +item.attr("data-value"); if (that._validateMin && useMin && value < minHours || that._validateMax && useMax && value > maxHours) { item.hide(); } else { item.show(); } }); } else { hoursList.find(".k-item").each(function(_, item) { item = $(item); var value = +item.attr("data-value"); if (that._validateMin && value < minHours || that._validateMax && value > maxHours) { item.hide(); } else { item.show(); } }); } this._updateListBottomOffset(hoursList); }, _updateMinutesRange: function() { var that = this; var indexAttr = kendo.attr("index"); var minutesList = this.ul.find("[" + indexAttr + "=\"2\"]"); var minHours = this._minHours; var maxHours = this._maxHours; var minMinutes = this._minMinutes; var maxMinutes = this._maxMinutes; var selectedHour = +this._findSelectedValue(this.ul.find("[" + indexAttr + "=\"1\"]")); var is12hourFormat = includes(this.options.format.toLowerCase(), "t"); var selectedDesignator = this._findSelectedValue(this.ul.find("[" + indexAttr + "=\"4\"]")); if (is12hourFormat && selectedDesignator === "PM") { selectedHour += 12; } if (!minutesList.length) { return; } minutesList.find(".k-item").each(function(_, item) { item = $(item); var value = +item.attr("data-value"); if (that._validateMin && value < minMinutes && (minHours && selectedHour) === minHours || that._validateMax && value > maxMinutes && (maxHours && selectedHour) === maxHours) { item.hide(); } else { item.show(); } }); this._updateListBottomOffset(minutesList); }, _updateSecondsRange: function() { var that = this; var indexAttr = kendo.attr("index"); var secondsList = this.ul.find("[" + indexAttr + "=\"3\"]"); var minSeconds = this._minSeconds; var maxSeconds = this._minSeconds; var minMinutes = this._minMinutes; var maxMinutes = this._maxMinutes; var selectedMinutes = +this._findSelectedValue(this.ul.find("[" + indexAttr + "=\"2\"]")); if (!secondsList.length) { return; } secondsList.find(".k-item").each(function(_, item) { item = $(item); var value = +item.attr("data-value"); if (that._validateMin && value < minSeconds && minMinutes && selectedMinutes === minMinutes || that._validateMax && value > maxSeconds && maxMinutes && selectedMinutes === maxMinutes) { item.hide(); } else { item.show(); } }); this._updateListBottomOffset(secondsList); }, _updateDesignatorRange: function() { var minHours = this._minHours; var maxHours = this._maxHours; var indexAttr = kendo.attr("index"); var designatorList = this.ul.find("[" + indexAttr + "=\"4\"]"); if (!designatorList.length) { return; } if (this._validateMin && minHours >= 12) { designatorList.find(".k-item[data-value=\"AM\"]").hide(); } else { designatorList.find(".k-item[data-value=\"AM\"]").show(); } if (this._validateMax && maxHours < 12) { designatorList.find(".k-item[data-value=\"PM\"]").hide(); } else { designatorList.find(".k-item[data-value=\"PM\"]").show(); } }, _updateRanges: function() { if (!this.options.specifiedRange) { return; } if (!this._currentlySelected) { this._currentlySelected = new Date(); } var max = this.options.endTime ? this.options.endTime : this.options.max; var min = this.options.startTime ? this.options.startTime : this.options.min; if (this.options.validateDate) { if (max.getFullYear() === this._currentlySelected.getFullYear() && max.getMonth() === this._currentlySelected.getMonth() && max.getDate() === this._currentlySelected.getDate()) { this._validateMax = true; } else { this._validateMax = false; } if (min.getFullYear() === this._currentlySelected.getFullYear() && min.getMonth() === this._currentlySelected.getMonth() && min.getDate() === this._currentlySelected.getDate()) { this._validateMin = true; } else { this._validateMin = false; } if (!this._validateMax && !this._validateMin) { this._showAllHiddenItems(); return; } } else { this._validateMax = true; this._validateMin = true; } this._minMinutes = min.getMinutes(); this._maxMinutes = max.getMinutes(); this._minHours = min.getHours(); this._maxHours = max.getHours(); this._minSeconds = min.getSeconds(); this._maxSeconds = max.getSeconds(); this._updateDesignatorRange(); this._updateHoursRange(); this._updateMinutesRange(); this._updateSecondsRange(); }, addTranslate: function() { var lists = this.ul.find(".k-time-container.k-content.k-scrollable"); var length = lists.length; var list; var itemHeight; var listHeight; var topOffset; var translate; var bottomOffset; for (var i = 0; i < length; i++) { list = lists.eq(i); itemHeight = getItemHeight(list.find(".k-item:visible").eq(0)); listHeight = list.outerHeight(); topOffset = (listHeight - itemHeight) / 2; translate = "translateY(" + topOffset + "px)"; bottomOffset = listHeight - itemHeight; list.find("ul").css({ transform: translate, "-ms-transform": translate }); list.find(".k-scrollable-placeholder").css({ height: list.find("ul").height() + bottomOffset }); list.off(ns).on("click" + ns, ".k-item", this._itemClickHandler.bind(this)).on("scroll" + ns, this._listScrollHandler.bind(this)); } }, _nowClickHandler: function(e) { e.preventDefault(); var now = new Date(); this.value(now); this.options.change(kendo.toString(now, this.options.format, this.options.culture), true); }, _cancelClickHandler: function(e) { e.preventDefault(); this.value(this._value); if (this.popup) { this.popup.close(); } }, _setClickHandler: function(e) { e.preventDefault(); this._value = new Date(this._currentlySelected); this.options.change(kendo.toString(this._currentlySelected, this.options.format, this.options.culture), true); if (this.popup) { this.popup.close(); } }, _listScrollHandler: function(e) { var that = this; var itemHeight = getItemHeight($(e.currentTarget).find(".k-item:visible").eq(0)); if (that._internalScroll) { return; } if (that._scrollingTimeout) { clearTimeout(that._scrollingTimeout); } that._scrollingTimeout = setTimeout(function() { if (e.currentTarget.scrollTop % itemHeight > 1) { e.currentTarget.scrollTop += itemHeight - e.currentTarget.scrollTop % itemHeight; } that._scrollTop = e.currentTarget.scrollTop; that._updateRanges(); that._updateCurrentlySelected(); }, 100); }, _updateCurrentlySelected: function() { var is12hourFormat = includes(this.options.format.toLowerCase(), "t"); var indexAttr = kendo.attr("index"); var hoursList = this.ul.find("[" + indexAttr + "=\"1\"]"); var minutesList = this.ul.find("[" + indexAttr + "=\"2\"]"); var secondsList = this.ul.find("[" + indexAttr + "=\"3\"]"); var designatorList = this.ul.find("[" + indexAttr + "=\"4\"]"); var selectedHour; var selectedMinutes; var selectedSeconds; var selectedDesignator; if (!this.ul.is(":visible")) { return; } if (!this._currentlySelected) { this._currentlySelected = this._value ? new Date(this._value) : new Date(); } if (hoursList.length) { selectedHour = +this._findSelectedValue(hoursList); } if (minutesList.length) { selectedMinutes = +this._findSelectedValue(minutesList); } if (secondsList.length) { selectedSeconds = +this._findSelectedValue(secondsList); } if (designatorList.length) { selectedDesignator = this._findSelectedValue(designatorList); } if (is12hourFormat) { if (selectedDesignator == "PM") { selectedHour += 12; if (selectedHour == 24) { selectedHour = 12; } } if (selectedDesignator === "AM" && selectedHour === 12) { selectedHour = 0; } } if (selectedHour !== undefined) { this._currentlySelected.setHours(selectedHour); } if (selectedMinutes !== undefined) { this._currentlySelected.setMinutes(selectedMinutes); } if (selectedSeconds !== undefined) { this._currentlySelected.setSeconds(selectedSeconds); } }, _findSelectedValue: function(list) { var firstOccurence = firstItemIndex(list.scrollTop(), getItemHeight(list.find(".k-item:visible").eq(0))); return list.find(".k-item:visible").eq(firstOccurence).attr("data-value"); }, _itemClickHandler: function(e) { var list = $(e.originalEvent.currentTarget); var index = list.find(".k-item:visible").index($(e.currentTarget)); var itemHeight = getItemHeight(list.find(".k-item:visible").eq(0)); list.scrollTop(index * itemHeight); }, getDatesInRange: function(msStart, msMax, startDate, max, msInterval, start) { var result = []; while (true) { if (msMax && (getMilliseconds(start) >= msMax || startDate.getDate() != start.getDate())) { msStart = getMilliseconds(start); if (startDate < start) { msStart += MS_PER_DAY; } if (msStart > msMax) { start = new DATE(+max); } if (getMilliseconds(start) > 0) { result.push(new Date(start)); } break; } if (startDate.getDate() != start.getDate()) { break; } result.push(new Date(start)); start.setTime(start.getTime() + msInterval); if (!msMax && this.options.maxSet && !this._ignoreMaxSet) { break; } } return result; }, _createListContent: function(parts, interval) { var length = parts.length; var result = ""; var part; var values; for (var i = 0; i < length; i++) { part = parts[i]; if (part.type === "literal" || part.type == "dayperiod") { result += this._literalTemplate(part); } else { values = this._getValues(part, true, interval); result += this._itemTemplate(values.values, part, this.options.messages[part.type], values.index); } } return result; }, _itemTemplate: function(values, part, title, index) { var result = ""; var length = values.length; var indexAttr = kendo.attr("index"); result += "<div class=\"k-time-list-wrapper\" role=\"presentation\">" + "<span class=\"k-title\">" + (title || part.type) + "</span>" + "<div class=\"k-time-list\">" + "<div class=\"k-time-container k-content k-scrollable\" role=\"presentation\" " + indexAttr + "=\"" + index + "\">" + "<ul class=\"k-reset\">"; for (var i = 0; i < length; i++) { result += "<li class=\"k-item\" data-value=\"" + values[i] + "\">" + "<span>" + values[i] + "</span>" + "</li>"; } result += "</ul>" + "<div class=\"k-scrollable-placeholder\"></div>" + "</div>" + "</div>" + "</div>"; return result; }, _getValues: function(part, shouldPad, interval) { var result = []; var index; var start = 0; var end; var step = 0; var currentStep = 0; if ($.isPlainObject(interval)) { step = interval[part.type] || 0; } if (part.type === "hour") { start = part.hour12 ? 1 : 0; index = 1; end = part.hour12 ? 12 : 23; } else if (part.type === "minute") { index = 2; end = 59; } else if (part.type === "second") { index = 3; end = 59; } for (; start <= end; start++) { if (step > 0) { if (start === 0 || start === 1 && step > 1 && part.type === "hour") { result.push(shouldPad ? pad(currentStep) : currentStep); } if (start % step === 0 && currentStep + step <= end) { currentStep += step; result.push(shouldPad ? pad(currentStep) : currentStep); } } else { result.push(shouldPad ? pad(start) : start); } } return { values: result, index }; }, _literalTemplate: function(part) { var isDayTimePattern = part.pattern === " tt" || part.pattern === "aa"; var result = "<div class=\"k-time-separator\">" + (isDayTimePattern ? ":" : part.pattern) + "</div>"; if (isDayTimePattern) { result += this._itemTemplate(["AM", "PM"], part, "AM/PM", 4); } return result; }, bind: function() { var that = this, options = that.options, dates = options.dates; if (dates && dates[0] && !(options.timeView && options.timeView.list === "scroll")) { that.dataBind(dates); } else { that.refresh(); that.addTranslate(); if (that._value) { that.applyValue(that._value); } } }, _html: function(html) { var that = this; if (that.options.timeView && that.options.timeView.list === "scroll") { html = HIGHLIGHTCONTAINER + html; that.ul.html(html); } else { that.ul[0].innerHTML = html; that.popup.unbind(OPEN, that._heightHandler); that.popup.one(OPEN, that._heightHandler); that.current(null); that.select(that._value); } }, scroll: function(item) { if (!item) { return; } if (item.scrollIntoViewIfNeeded) { item.scrollIntoViewIfNeeded(); } else { scrollIntoViewIfNeeded(item); } }, select: function(li) { var that = this, options = that.options, current = that._current, selection; if (li instanceof Date) { li = kendo.toString(li, options.format, options.culture); } if (typeof li === "string") { if (!current || current.text() !== li) { li = $.grep(that.ul[0].childNodes, function(node) { return (node.textContent || node.innerText) == li; }); li = li[0] ? li : null; } else { li = current; } } selection = that._distinctSelection(li); that.current(selection); }, _distinctSelection: function(selection) { var that = this, currentValue, selectionIndex; if (selection && selection.length > 1) { currentValue = getMilliseconds(that._value); selectionIndex = $.inArray(currentValue, that._dates); selection = that.ul.children()[selectionIndex]; } return selection; }, setOptions: function(options) { var old = this.options; options.min = parse(options.min); options.max = parse(options.max); this.options = extend(old, options, { active: old.active, change: old.change, close: old.close, open: old.open }); this.bind(); }, toggle: function() { var that = this; if (that.popup.visible()) { that.close(); } else { that.open(); } }, value: function(value) { var that = this; that._value = value; if (that.ul[0].firstChild) { if (that.options.timeView && that.options.timeView.list === "scroll") { that.applyValue(value); } else { that.select(value); } } }, _click: function(e) { let that = this, li = $(e.currentTarget), date = li.text(), dates = that.options.dates, min = that.options.min, max = that.options.max; if (dates && dates.length > 0) { if (min.getTime() !== max.getTime()) { dates = dates.filter((d) => that._inRange(d)); } date = dates[li.index()]; } if (!e.isDefaultPrevented()) { that.select(li); that.options.change(date, true); that.close(); } }, _inRange(date) { const that = this, min = that.options.min, max = that.options.max; const dateSeconds = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds(), minSeconds = min.getHours() * 3600 + min.getMinutes() * 60 + min.getSeconds(), maxSeconds = max.getHours() * 3600 + max.getMinutes() * 60 + max.getSeconds(); return dateSeconds >= minSeconds && dateSeconds <= maxSeconds; }, _height: function() { var that = this; var list = that.list; var parent = list.parent(".k-child-animation-container"); var container = parent.closest(".k-animation-container"); var height = that.options.height; var elements = list.add(container); var ul = that.ul[0]; if (ul.children.length) { elements.add(parent).show(); list.add(parent).height(ul.scrollHeight > height && (that.options.adaptiveMode != "auto" || that.bigScreenMQL.mediaQueryList.matches) ? height : "auto"); elements.hide(); } }, _parse: function(value) { var that = this, options = that.options, min = getMilliseconds(options.min) != getMilliseconds(TODAY) ? options.min : null, max = getMilliseconds(options.max) != getMilliseconds(TODAY) ? options.max : null, current = that._value || min || max || TODAY; if (value instanceof DATE) { return value; } value = parse(value, options.parseFormats, options.culture); if (value) { value = new DATE(current.getFullYear(), current.getMonth(), current.getDate(), value.getHours(), value.getMinutes(), value.getSeconds(), value.getMilliseconds()); } return value; }, _adjustListWidth: function() { var that = this, list = this.list, width = list[0].style.width, wrapper = this.options.anchor, computedStyle, computedWidth, outerWidth = kendo._outerWidth; if (!list.data("width") && width) { return; } computedStyle = window.getComputedStyle ? window.getComputedStyle(wrapper[0], null) : 0; computedWidth = computedStyle ? parseFloat(computedStyle.width) : outerWidth(wrapper); if (computedStyle && (browser.mozilla || browser.msie)) { computedWidth += parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight) + parseFloat(computedStyle.borderLeftWidth) + parseFloat(computedStyle.borderRightWidth); } width = computedWidth - (outerWidth(list) - list.width()); list.css({ fontFamily: wrapper.css("font-family"), width: that.options.adaptiveMode != "auto" || that.bigScreenMQL.mediaQueryList.matches ? width : "100%" }).data("width", width); }, _popup: function() { var that = this, list = that.list, options = that.options, anchor = options.anchor; if (!this.options.omitPopup) { if (options.adaptiveMode == "auto" && !that.bigScreenMQL.mediaQueryList.matches) { var popupContent = that.popupContent || list; popupContent.appendTo(document.body); that.popup = new ui.ActionSheet(popupContent, { adaptive: true, focusOnActivate: false, title: options.adaptiveTitle || "Set time", subtitle: options.adaptiveSubtitle, closeButton: { icon: "check", themeColor: "primary" }, footerTemplate: that.options.componentType === "modern" ? () => NEW_RENDERING_FOOTER(that.options.adaptiveMode != "auto" || that.bigScreenMQL.mediaQueryList.matches ? that.options.size : "large", that.options.messages, true) : null, fullscreen: that.smallScreenMQL.mediaQueryList.matches, popup: extend(options.popup, { anchor, close: options.close, animation: options.animation, isRtl: support.isRtl(options.anchor) }), open: function() { if (that.popup._footer) { that.popup._footer.addClass("k-actions k-actions-stretched k-actions-horizontal"); } if (options.open) { options.open(); } }, activate: function() { if (that.options.timeView && that.options.timeView.list === "scroll") { that.addTranslate(); that._updateRanges(); if (that._value) { that.applyValue(that._value); } else { that._updateCurrentlySelected(); } that._focusList(that.list.find(".k-time-list-wrapper").eq(0)); } } }); that._updateRanges(); that._updateCurrentlySelected(); } else { that.popup = new ui.Popup(that.popupContent || list, extend(options.popup, { anchor, open: options.open, close: options.close, animation: options.animation, isRtl: support.isRtl(options.anchor), activate: function() { if (that.options.timeView && that.options.timeView.list === "scroll") { that.addTranslate(); that._updateRanges(); if (that._value) { that.applyValue(that._value); } else { that._updateCurrentlySelected(); } that._focusList(that.list.find(".k-time-list-wrapper").eq(0)); } } })); } } else { list.appendTo(options.timeDiv); } }, move: function(e) { const that = this, key = e.keyCode, ul = that.ul[0], down = key === keys.DOWN, isInput = $(e.target).is(".k-input-inner"), isModernType = that.options.componentType === "modern", isPopupOpened = that.popup.visible(); let current = that._current; const preventInputValueChange = isInput && isModernType && isPopupOpened; if (key === keys.UP || down) { if (e.altKey) { that.toggle(down); return; } else if (preventInputValueChange) { return; } else if (down) { current = current ? current[0].nextSibling : ul.firstChild; } else { current = current ? current[0].previousSibling : ul.lastChild; } if (current) { that.select(current); } that.options.change(that._current.text()); e.preventDefault(); } else if (key === keys.ENTER || key === keys.TAB || key === keys.ESC) { e.preventDefault(); if (current) { that.options.change(current.text(), true); } that.close(); } } }; function dst() { var today = new DATE(), midnight = new DATE(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0), noon = new DATE(today.getFullYear(), today.getMonth(), today.getDate(), 12, 0, 0); return -1 * (midnight.getTimezoneOffset() - noon.getTimezoneOffset()); } function getMilliseconds(date) { return date.getHours() * 60 * MS_PER_MINUTE + date.getMinutes() * MS_PER_MINUTE + date.getSeconds() * 1e3 + date.getMilliseconds(); } function lastTimeOption(interval) { var date = new Date(2100, 0, 1); date.setMinutes(-interval); return date; } function isInRange(value, min, max) { var msMin = getMilliseconds(min), msMax = getMilliseconds(max), msValue; if (!value || msMin == msMax) { return true; } msValue = getMilliseconds(value); if (msMin > msValue) { msValue += MS_PER_DAY; } if (msMax < msMin) { msMax += MS_PER_DAY; } return msValue >= msMin && msValue <= msMax; } TimeView.getMilliseconds = getMilliseconds; kendo.TimeView = TimeView; var TimePicker = Widget.extend({ init: function(element, options) { var that = this, disabled; options = options || {}; options.componentType = options.componentType || "classic"; if ($.isPlainObject(options.interval) && options.componentType !== "modern") { options.interval = 30; } Widget.fn.init.call(that, element, options); element = that.element; options = that.options; options.min = parse(element.attr("min")) || parse(options.min); options.max = parse(element.attr("max")) || parse(options.max); options.inputMode = options.inputMode || element.attr("inputmode") || "text"; element.attr("inputmode", options.inputMode); if (+options.max != +TODAY || +options.min != +TODAY) { this._specifiedRange = true; } normalize(options); that._initialOptions = extend({}, options); that._wrapper(); if (that.options.timeView && that.options.timeView.list === "scroll") { that.options.height = null; } that.bigScreenMQL = mediaQuery("large"); if (that.options.adaptiveMode == "auto") { that.bigScreenMQL.onChange(() => { that._createTimeViewProxy(); that._update(that.element.val()); }); } that._createTimeView(); that._createTimeViewProxy = that._createTimeView.bind(that); that._icon(); that._reset(); try { element[0].setAttribute("type", "text"); } catch (e) { element[0].type = "text"; } element.addClass("k-input-inner").attr({ "role": "combobox", "aria-expanded": false, "aria-controls": that.timeView._timeViewID, "autocomplete": "off" }); disabled = element.is("[disabled]") || $(that.element).parents("fieldset").is(":disabled"); if (disabled) { that.enable(false); } else { that.readonly(element.is("[readonly]")); } that._createDateInput(); that._old = that._update(options.value || that.element.val()); that._oldText = element.val(); that._applyCssClasses(); if (options.label) { that._label(); } that.element.removeAttr("style"); kendo.notify(that); }, options: { name: "TimePicker", autoAdjust: true, min: TODAY, max: TODAY, format: "", dates: [], parseFormats: [], focusTime: null, value: null, interval: 30, height: DEFAULT_HEIGHT, animation: {}, dateInput: false, messages: { set: "Set", cancel: "Cancel", hour: "hour", minute: "minute", second: "second", millisecond: "millisecond", now: "Now" }, adaptiveMode: "none", adaptiveTitle: null, adaptiveSubtitle: null, componentType: "classic", size: undefined, fillMode: undefined, rounded: undefined, label: null, autoCorrectParts: true }, events: [ OPEN, CLOSE, CHANGE ], componentTypes: { "classic": { timeView: { list: "list" } }, "modern": { timeView: { list: "scroll" } } }, setOptions: function(options) { let that = this, value = options.value || that.options.value || that._value, isComponentTypeChanged = false; if (options.componentType) { isComponentTypeChanged = options.componentType !== that.options.componentType; } Widget.fn.setOptions.call(that, options); options = that.options; if ($.isPlainObject(options.interval) && options.componentType !== "modern") { options.interval = 30; } if (+options.max != +TODAY || +options.min != +TODAY) { this._specifiedRange = true; } that._arrow.off(ns); that._arrow.remove(); normalize(options); if (options.componentType && isComponentTypeChanged) { options.timeView.list = options.componentType == "classic" ? "list" : "scroll"; that.options.height = options.componentType == "classic" ? DEFAULT_HEIGHT : null; that._createTimeView(); } that.timeView.setOptions(options); that._icon(); that._editable(options); that._createDateInput(); if (!that._dateInput && value) { that.element.val(kendo.toString(value, options.format, options.culture)); } if (value) { if (that?.timeView?.list === "scroll") { that.timeView.applyValue(value); } else { that.timeView.select(value); } that._value = value; } if (options.label && that._inputLabel) { that.label.setOptions(options.label); } else if (options.label === false) { that.label._unwrapFloating(); that._inputLabel.remove(); delete that._inputLabel; } else if (options.label) { that._label(); } }, dataBind: function(dates) { if (isArray(dates)) { this.timeView.dataBind(dates); } }, _createDateInput: function() { const that = this, options = that.options, element = that.element; if (that._dateInput) { that._dateInput.destroy(); that._dateInput = null; } if (options.dateInput) { var min = options.min; var max = options.max; var today = new DATE(); if (getMilliseconds(min) == getMilliseconds(max)) { min = new DATE(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0); max = new DATE(today.getFullYear(), today.getMonth(), today.getDate(), 24, 0, 0); } that._dateInput = new ui.DateInput(element, { autoAdjust: options.autoAdjust, culture: options.culture, format: options.format, min, max, value: options.value, interval: options.interval, size: options.size, fillMode: options.fillMode, rounded: options.rounded, messages: options.messages.dateInput, autoCorrectParts: options.autoCorrectParts, toggleDayPeriod: true, inputMode: options.inputMode }); } }, _editable: function(options) { var that = this, disable = options.disable, readonly = options.readonly, arrow = that._arrow.off(ns), element = that.element.off(ns), wrapper = that.wrapper.off(ns); if (that._dateInput) { that._dateInput._unbindInput(); } if (!readonly && !disable) { wrapper.removeClass(STATEDISABLED).on(HOVEREVENTS, that._toggleHover); if (element && element.length) { element[0].removeAttribute(DISABLED); element[0].removeAttribute(READONLY); } element.attr(ARIA_DISABLED, false).attr(ARIA_READONLY, false).on("keydown" + ns, that._keydown.bind(that)).on("focusout" + ns, that._blur.bind(that)).on("focus" + ns, function() { that.wrapper.addClass(FOCUSED); }); if (that._dateInput) { that._dateInput._bindInput(); } arrow.on(CLICK, that._click.bind(that)).on(MOUSEDOWN, preventDefault); } else { wrapper.addClass(disable ? STATEDISABLED : "").removeClass(disable ? "" : STATEDISABLED); element.attr(DISABLED, disable).attr(READONLY, readonly).attr(ARIA_DISABLED, disable).attr(ARIA_READONLY, readonly); } }, _label: function() { var that = this; var options = that.options; var labelOptions = $.isPlainObject(options.label) ? options.label : { content: options.label }; if (that._dateInput) { labelOptions.floatCheck = () => { if (!that.value() && (!that._dateInput._hasDateInput() || that.element.val() === "") && document.activeElement !== that.element[0]) { that.element.val(""); return true; } return false; }; } that.label = new kendo.ui.Label(null, $.extend({}, labelOptions, { widget: that })); that._inputLabel = that.label.element; }, readonly: function(readonly) { this._editable({ readonly: readonly === undefined ? true : readonly, disable: false }); if (this.label && this.label.floatingLabel) { this.label.floatingLabel.readonly(readonly === undefined ? true : readonly); } }, enable: function(enable) { this._editable({ readonly: false, disable: !(enable = enable === undefined ? true : enable) }); if (this.label && this.label.floatingLabel) { this.label.floatingLabel.enable(enable = enable === undefined ? true : enable); } }, destroy: function() { var that = this; Widget.fn.destroy.call(that); that.timeView.destroy(); that.element.off(ns); that._arrow.off(ns); that.wrapper.off(ns); if (that._form) { that._form.off("reset", that._resetHandler); } if (that.label) { that.label.destroy(); } if (that.bigScreenMQL) { that.bigScreenMQL.destroy(); } that._createTimeViewProxy = null; }, close: function() { this.timeView.close(); }, open: function() { this.timeView.open(); }, min: function(value) { if (value) { this._specifiedRange = true; } return this._option("min", value); }, max: function(value) { if (value && this.timeView) { this._specifiedRange = true; this.timeView.options.maxSet = true; } else if (this.timeView) { this.timeView.options.maxSet = false; } return this._option("max", value); }, value: function(value) { var that = this; if (value === undefined) { return that._value; } that._old = that._update(value); if (that._old === null) { that.element.val(""); } that._oldText = that.element.val(); if (that.label && that.label.floatingLabel) { that.label.floatingLabel.refresh(); } }, _blur: function() { var that = this, value = that.element.val(); that._typing = false; if (!(that.options.timeView && that.options.timeView.list === "scroll")) { that.close(); } if (value !== that._oldText) { that._change(value); } that.wrapper.removeClass(FOCUSED); }, _click: function() { var that = this, element = that.element; that.timeView.toggle(); if (!support.touch && element[0] !== activeElement() && !(that.options.timeView && that.options.timeView.list === "scroll")) { element.trigger("focus"); } }, _change: function(value) { var that = this, oldValue = that.element.val(), dateChanged; value = that._update(value); dateChanged = !kendo.calendar.isEqualDate(that._old, value); var valueUpdated = dateChanged && !that._typing; var textFormatted = oldValue !== that.element.val(); if (valueUpdated || textFormatted) { that.element.trigger(CHANGE); } if (dateChanged) { that._old = value; that._oldText = that.element.val(); that.trigger(CHANGE); } that._typing = false; }, _createTimeView: function() { var that = this; var options = that.options; var element = that.element; var timeView, ul; if (that.timeView) { if (that.timeView.popup && that.timeView.popup.wrapper) { that.timeView.popup.wrapper.remove(); } that.timeView.destroy(); that.timeView = null; } that.timeView = timeView = new TimeView(extend({}, options, { id: element.attr(ID), size: options.adaptiveMode != "auto" || that.bigScreenMQL.mediaQueryList.matches ? options.size : "large", anchor: that.wrapper, format: options.format, change: function(value, trigger) { if (trigger) { that._change(value); } else { element.val(value); } that.timeView._focusTime = null; }, open: function(e) { if (that.options.timeView && that.options.timeView.list !== "scroll") { that.timeView._adjustListWidth(); } else { that.timeView._updateTitle(); } if (that.trigger(OPEN)) { e.preventDefault(); } else { element.attr(ARIA_EXPANDED, true); ul.attr(ARIA_HIDDEN, false); if (timeView.current()) { element.attr(ARIA_ACTIVEDESCENDANT, timeView._optionID); } } }, close: function(e) { if (that.trigger(CLOSE)) { e.preventDefault(); } else { element.attr(ARIA_EXPANDED, false); ul.attr(ARIA_HIDDEN, true); element[0].removeAttribute(ARIA_ACTIVEDESCENDANT); } }, active: function(current) { if (element && element.length) { element[0].removeAttribute(ARIA_ACTIVEDESCENDANT); } if (current) { element.attr(ARIA_ACTIVEDESCENDANT, timeView._optionID); } }, specifiedRange: that._specifiedRange, maxSet: +options.max != +TODAY })); ul = timeView.ul; that._ariaLabel(ul); }, _icon: function() { var that = this, element = that.element, options = that.options, arrow; arrow = element.next("button.k-input-button"); if (!arrow[0]) { arrow = $(html.renderButton("<button unselectable=\"on\" tabindex=\"-1\" class=\"k-input-button\" aria-label=\"select\"></button>", { icon: "clock", size: options.size, fillMode: options.fillMode, shape: "none" })).insertAfter(element); } that._arrow = arrow.attr({ "role": "button" }); }, _keydown: function(e) { const that = this, key = e.keyCode, timeView = that.timeView, value = that.element.val(); if (timeView.popup.visible() || e.altKey) { timeView.move(e); if (that._dateInput && e.stopImmediatePropagation && that.options.componentType !== "modern") { e.stopImmediatePropagation(); } } else if (key === keys.ENTER && value !== that._oldText) { that._change(value); } else { that._typing = true; } }, _option: function(option, value) { var that = this, options = that.options; if (value === undefined) { return options[option]; } value = that.timeView._parse(value); if (!value) { return; } value = new DATE(+value); options[option] = value; that.timeView.options[option] = value; if (that._dateInput) { that._dateInput[option](value); } that.timeView.bind(); }, _toggleHover: function(e) { $(e.currentTarget).toggleClass(HOVER, e.type === "mouseenter"); }, _update: function(value) { var that = this, options = that.options, timeVie