UNPKG

@progress/kendo-ui

Version:

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

864 lines (741 loc) 30.2 kB
import './kendo.timeselector.js'; import './kendo.icons.js'; import './kendo.popup.js'; import './kendo.core.js'; import './kendo.licensing.js'; import '@progress/kendo-licensing'; import './kendo.html.button.js'; import './kendo.html.base.js'; import './kendo.html.icon.js'; import '@progress/kendo-svg-icons'; import './kendo.actionsheet.js'; const __meta__ = { id: "timedurationpicker", name: "TimeDurationPicker", category: "web", description: "The TimeDurationPicker widget allows the end user to select a time range stored in milliseconds.", docsCategory: "editors", depends: [ "timeselector" ] }; (function($, undefined$1) { var kendo = window.kendo, ui = kendo.ui, Widget = ui.Widget, html = kendo.html, map = $.map, extend = $.extend, mediaQuery = kendo.mediaQuery, OPEN = "open", FOCUS = "focus", CLOSE = "close", CHANGE = "change", CLICK = "click", SPAN = "<span></span>", KEYDOWN = "keydown", FOCUSOUT = "focusout", FOCUSED = "k-focus", MOUSEUP = "mouseup", MOUSEDOWN = "mousedown", PASTE = "paste", NS = ".kendoTimeDurationPicker", ARIA_EXPANDED = "aria-expanded", HOVEREVENTS = "mouseenter" + NS + " mouseleave" + NS, STRING = "string", INPUT = "input", HOVER = "k-hover", STATEDISABLED = "k-disabled", ARIA_HIDDEN = "aria-hidden", ARIA_DISABLED = "aria-disabled", ARIA_READONLY = "aria-readonly", ARIA_READONLY = "aria-readonly", DISABLED = "disabled", READONLY = "readonly", STATEINVALID = "k-invalid", MASKCHAR = "_", caret = kendo.caret, keys = kendo.keys, NS = ".kendoTimeDurationPicker"; html = kendo.html; var defaultColumns = { "hours": { name: "hours", format: "## hours", divider: 3600000, min: 0, max: 23, step: 1 }, "minutes": { name: "minutes", format: "## mins", divider: 60000, min: 0, max: 59, step: 1 }, "seconds": { name: "seconds", format: "## sec", divider: 1000, min: 0, max: 59, step: 1 }, "milliseconds": { name: "milliseconds", format: "### msec", min: 0, max: 999, step: 1 }, "days": { format: "### days", name: "days", divider: 86400000, min: 0, max: 365, step: 1 } }; function convertToMsec(value) { return ((value.days || 0) * 86400000) + ((value.hours || 0) * 3600000) + ((value.minutes || 0) * 60000) + ((value.seconds || 0) * 1000) + (value.milliseconds || 0); } function getTimeParts(value) { var rest; var days = Math.floor(value / 86400000); rest = value % 86400000; var hours = Math.floor(rest / 3600000); rest = value % 3600000; var minutes = Math.floor(rest / 60000); rest = value % 60000; var seconds = Math.floor(rest / 1000); rest = value % 1000; return { days: days, hours: hours, minutes: minutes, seconds: seconds, milliseconds: rest }; } function normalizeColumns(columns) { return map(columns, function(column) { column = typeof column === STRING ? { name: column } : column; var extended = extend(true, {}, defaultColumns[column.name], column); extended.selectorFormat = "{0:" + "0".repeat(extended.format.match(/#/g).length) + "}"; return extended; }); } var TimeDurationPicker = Widget.extend({ init: function(element, options) { var that = this; options = options || {}; Widget.fn.init.call(that, element, options); that._columns = normalizeColumns(options.columns); that.options.columns = that._columns; that.options.readonly = options.readonly !== undefined$1 ? options.readonly : Boolean(that.element.attr("readonly")); that.options.enable = options.enable !== undefined$1 ? options.enable : !(Boolean(that.element.is("[disabled]") || $(element).parents("fieldset").is(':disabled'))); that.options.inputMode = options.inputMode || that.element.attr("inputmode") || "text"; that.bigScreenMQL = mediaQuery("large"); if (that.options.adaptiveMode == "auto") { that.bigScreenMQL.onChange(()=> { if (that._timeSelector) { if (that._timeSelector.popup && that._timeSelector.popup.wrapper) { that._timeSelector.popup.wrapper.remove(); } that._timeSelector.destroy(); that._timeSelector = null; } that._popupView(); }); } that._wrapper(); that._button(); that._applyCssClasses(); that._input(); that._popupView(); that._buildMask(); that._validation(); that._editable({ readonly: that.options.readonly, disable: !that.options.enable }); that._ariaLabel(that._timeSelector._listsContainer); if (that.options.value) { that.value(options.value); that._old = that._maskedInput.val(); } that._canUpdateLast = true; kendo.notify(that); }, options: { name: "TimeDurationPicker", columns: [], separator: ",", shortcuts: [], value: null, adaptiveMode: "none", size: "medium", fillMode: "solid", rounded: "medium", messages: { set: "Set", cancel: "Cancel", days: "Days", hours: "Hours", minutes: "Minutes", milliseconds: "Milliseconds", seconds: "Seconds" } }, events: [ OPEN, CLOSE, CHANGE ], destroy: function() { var that = this; that.wrapper.off(NS); that._maskedInput.off(NS); if (that._timeSelector) { that._timeSelector.destroy(); that._timeSelector = null; } if (that.bigScreenMQL) { that.bigScreenMQL.destroy(); } }, value: function(value) { var that = this; if (value === undefined$1) { return that._value; } if (typeof value === "number") { value = parseInt(value); } else { value = null; } that._value = value; that.element.val(that._value); that._timeSelector._value = that._value; that._updateValueFromTimeSelector(); }, _toggleHover: function(e) { $(e.currentTarget).toggleClass(HOVER, e.type === "mouseenter"); }, _editable: function(options) { var that = this, disable = options.disable, readonly = options.readonly, element = that._maskedInput.add(that.element).off(NS), wrapper = that.wrapper.off(NS); if (!readonly && !disable) { wrapper .removeClass(STATEDISABLED) .on(HOVEREVENTS, that._toggleHover); if (element && element.length) { element.removeAttr(DISABLED); element.removeAttr(READONLY); } element.attr(ARIA_DISABLED, false) .attr(ARIA_READONLY, false); that._attachHandlers(); } else { wrapper .addClass(disable ? STATEDISABLED : "") .removeClass(disable ? "" : STATEDISABLED); element.attr(DISABLED, disable) .attr(READONLY, readonly) .attr(ARIA_DISABLED, disable) .attr(ARIA_READONLY, readonly); } }, readonly: function(readonly) { this._editable({ readonly: readonly === undefined$1 ? true : readonly, disable: false }); }, enable: function(enable) { this._editable({ readonly: false, disable: !(enable = enable === undefined$1 ? true : enable) }); }, _popupView: function() { var that = this; var options = that.options; if (!that._timeSelector) { that._timeSelector = new kendo.ui.TimeSelector(that._maskedInput, { id: that.element.attr("id") + "_timeSelector", anchor: that.wrapper, adaptiveMode: options.adaptiveMode, columns: options.columns, shortcuts: options.shortcuts, value: options.value, size: options.adaptiveMode != "auto" || that.bigScreenMQL.mediaQueryList.matches ? options.size : "large", fillMode: options.fillMode, rounded: options.rounded, messages: options.messages, focus: function() { that._maskedInput.trigger("focus"); that._selectNearestSection(that._lastCaret || 0); }, close: function(e) { if (that.trigger(CLOSE)) { e.preventDefault(); } else { that._maskedInput.attr(ARIA_EXPANDED, false); that._timeSelector._listsContainer.attr(ARIA_HIDDEN, true); } }, open: function(e) { if (that.trigger(OPEN)) { e.preventDefault(); } else { that._maskedInput.attr(ARIA_EXPANDED, true); that._timeSelector._listsContainer.attr(ARIA_HIDDEN, false); that._lastCaret = caret(that._maskedInput)[0]; if (that._lastCaret === that._maskedInput.val().length) { that._lastCaret = 0; } } }, change: function(value) { that._value = value; that._updateValueFromTimeSelector(); that._removeInvalidState(); that.trigger(CHANGE); } }); } }, _button: function() { var that = this, element = that.element, options = that.options, button; button = element.next("button.k-input-button"); if (!button[0]) { button = $(html.renderButton('<button unselectable="on" tabindex="-1" class="k-input-button" aria-label="select"></button>', { icon: "clock-arrow-rotate", size: options.size, fillMode: options.fillMode, shape: "none", rounded: "none" })).insertAfter(element); } that._button = button.attr({ "role": "button" }); }, _buildMask: function() { var columns = this.options.columns; var format; var toAdd = ""; var part; var currentPartLength = 0; this._emtpyMask = ""; this._maskParts = []; for (var i = 0; i < columns.length; i++) { part = {}; format = columns[i].format; if (i) { toAdd = this.options.separator; } toAdd += format.replace(/#/g, '_'); this._emtpyMask += toAdd; part.end = this._emtpyMask.length - 1; part.mask = format.replace(/#/g, '_'); part.symbolsLength = part.mask.match(/_/g).length; part.start = this._emtpyMask.indexOf(part.mask, currentPartLength); part.numberEnd = this._emtpyMask.lastIndexOf(MASKCHAR) + 1; part.numberStart = this._emtpyMask.indexOf(MASKCHAR, part.start); currentPartLength += part.mask.length; this._maskParts.push(part); } this._old = this._emtpyMask; this._maskedInput.val(this._emtpyMask); }, _input: function() { var that = this; that._maskedInput = $("<input />") .attr(kendo.attr("validate"), "false") .attr({ "role": "combobox", "aria-expanded": false, "aria-controls": that.element.attr("id") + "_timeSelector", "autocomplete": "off", "inputmode": that.options }) .addClass("k-input-inner") .insertBefore(that.element); let inputMode = that.options.inputMode; if (inputMode) { that._maskedInput.attr("inputmode", inputMode); } that.element.hide(); }, _wrapper: function() { var that = this, element = that.element, wrapper; wrapper = element.parents(".k-timedurationpicker"); if (!wrapper[0]) { wrapper = element.wrap(SPAN).parent(); } that.wrapper = wrapper.addClass("k-timedurationpicker k-input"); }, _attachHandlers: function() { var that = this; that._maskedInput .on(KEYDOWN + NS, that._keydown.bind(that)) .on(INPUT + NS, that._inputHandler.bind(that)) .on(FOCUS + NS, that._focus.bind(that)) .on(FOCUSOUT + NS, that._focusout.bind(that)) .on(PASTE + NS, that._paste.bind(that)) .on(MOUSEDOWN + NS, that._mouseDown.bind(that)) .on(MOUSEUP + NS, that._mouseUp.bind(that)); that.wrapper.on(CLICK + NS, ".k-input-button", that._click.bind(that)); }, _mouseDown: function() { this._mouseOnInput = true; }, _mouseUp: function() { var selection = caret(this._maskedInput[0]); var value = this._maskedInput[0].value; if (selection[0] === selection[1]) { this._selectNearestSection(selection[1] == value.length ? value.length - 1 : selection[1]); } }, _triggerChange: function() { if ((this._lastValue == undefined$1 && this._value) || this._lastValue != this._value) { this._lastValue = this._value; this.trigger(CHANGE); } }, _focusout: function() { this._updateValueFromInput(); this._triggerChange(); this._canUpdateLast = true; this.wrapper.removeClass(FOCUSED); }, _focus: function() { var that = this; if (!that._mouseOnInput) { setTimeout(function() { that._selectNearestSection(0); }, 10); } that._mouseOnInput = false; that.wrapper.addClass(FOCUSED); }, _selectNearestSection: function(index) { var part; for (var i = 0; i < this._maskParts.length; i++ ) { part = this._maskParts[i]; if (index >= part.start && index <= part.end) { caret(this._maskedInput[0], part.numberStart, part.numberEnd); } } }, _getPartValue: function(value, index) { var that = this; var separator = that.options.separator; var startSeparator = value.indexOf(separator,index); var lastSeparator = value.lastIndexOf(separator,index); return value.substring(lastSeparator < 0 ? 0 : lastSeparator + 1 , startSeparator < 0 ? value.length : startSeparator ); }, _getEmptyPart: function(index) { return this._getPartValue(this._emtpyMask, index); }, _fillParts: function(clipNumber) { var parts = this._emtpyMask.split(this.options.separator); var symbols; clipNumber = clipNumber + ""; for (var i = 0; i < parts.length; i++) { symbols = parts[i].match(/_/g).length; if (symbols > clipNumber.length) { parts[i] = parts[i].replace(MASKCHAR.repeat(symbols), "0".repeat(symbols - clipNumber.length) + clipNumber); } else { parts[i] = parts[i].replace(MASKCHAR.repeat(symbols), clipNumber.substring(0, symbols)); clipNumber = clipNumber.substring(symbols, symbols.length); } } return parts.join(this.options.separator); }, _clearParts: function(value, start, end) { var parts = value.split(this.options.separator); var index = 0; var endBoundary; for (var i = 0; i < parts.length; i++) { endBoundary = index + parts[i].length; if ((index <= start && endBoundary >= start) || (index <= end && endBoundary >= end)) { parts[i] = this._getEmptyPart(index); } index += (parts[i].length + 1); } return parts.join(this.options.separator); }, _updatePart: function(oldValue, entered) { var emrtyPart = this._getEmptyPart(this._old.indexOf(oldValue)); var current = oldValue.substring(emrtyPart.indexOf(MASKCHAR), emrtyPart.lastIndexOf(MASKCHAR) + 1); var format = "{0:" + "0".repeat(current.length) + "}"; if (current.indexOf(MASKCHAR) >= 0 || !(oldValue[oldValue.search(/[0-9]/)] === "0") || entered.length > 1) { return oldValue.replace(current, kendo.format(format, parseInt(entered))); } else { return oldValue.replace(current, kendo.format(format, parseInt(current + entered))); } }, _replacePart: function(oldValue, newPart, index) { return oldValue.replace(this._getPartValue(oldValue, index), newPart); }, _click: function() { var that = this; if (!that._timeSelector) { return; } that._timeSelector.toggle(); }, _switchPart: function(options) { var separator = this.options.separator; var selection = options.caret != undefined$1 ? options.caret : caret(this._maskedInput[0])[0]; var value = this._maskedInput.val(); var index; if (options.next) { index = value.indexOf(separator, selection); if (index < 0) { index = value.length - 1; } else { index++; } } else { index = value.lastIndexOf(separator, selection); if (index < 0 ) { index = 0; } else { index--; } } this._selectNearestSection(index); }, _keydown: function(e) { var key = e.keyCode; var separator = this.options.separator; var selection; var value; var index; var future; var past; this._backward = key === keys.BACKSPACE; if (key == keys.LEFT || key == keys.RIGHT) { e.preventDefault(); selection = caret(this._maskedInput[0])[0]; value = this._maskedInput.val(); future = value.indexOf(separator, selection); past = value.lastIndexOf(separator, selection); if ((future < 0 && key == keys.RIGHT) || (past < 0 && key == keys.LEFT)) { return; } index = (key == keys.LEFT) ? (past - 1) : (future + 1); this._selectNearestSection(index); if (key == keys.LEFT) { this._canUpdateLast = true; } } else if (this._timeSelector.popup.visible()) { this._timeSelector._scrollerKeyDownHandler(e); } else if (key == keys.UP || key == keys.DOWN) { e.preventDefault(); if (e.altKey) { this._timeSelector.toggle(); } } else if (key == keys.ENTER) { this._updateValueFromInput(); this._triggerChange(); } }, _updateValueFromTimeSelector: function() { var that = this; var valueParts = getTimeParts(that._value); var value = ""; var column = this._columns[i]; var part; var partValue; var masksToAdd; for (var i = 0; i < this._columns.length; i++) { column = this._columns[i]; partValue = valueParts[column.name] + ''; part = this._maskParts[i]; if (i) { value += that.options.separator; } if (!valueParts[column.name]) { value += part.mask; continue; } masksToAdd = part.symbolsLength - partValue.length; value += part.mask.replace(MASKCHAR.repeat(part.symbolsLength), "0".repeat(masksToAdd < 0 ? 0 : masksToAdd) + partValue); } that._maskedInput.val(value); that._old = value; }, _validation: function() { var that = this; var element = that.element; that._validationIcon = $(kendo.ui.icon({ icon: "exclamation-circle", iconClass: "k-input-validation-icon k-hidden" })).insertAfter(element); }, _addInvalidState: function() { this.wrapper.addClass(STATEINVALID); this._validationIcon.removeClass('k-hidden'); }, _removeInvalidState: function() { this.wrapper.removeClass(STATEINVALID); this._validationIcon.addClass('k-hidden'); }, _updateValueFromInput: function() { var val = this._maskedInput.val(); var values = {}; var valid = true; var column; var part; var colValue; for (var i = 0; i < this._columns.length; i++) { column = this._columns[i]; part = this._maskParts[i]; colValue = val.substring(part.numberStart, part.numberEnd).replace(/_/g, ""); colValue = kendo.parseInt(colValue || 0); if (colValue >= column.min && colValue <= column.max) { values[column.name] = colValue; } else { valid = false; break; } } if (valid) { this._value = convertToMsec(values); this.element.val(this._value || ""); this._timeSelector._value = this._value; this._removeInvalidState(); } else { this._addInvalidState(); } }, _paste: function(e) { this._isPasted = true; this._pasted = (e.clipboardData || e.originalEvent.clipboardData).getData('Text'); var emptyPart; var selection = caret(this._maskedInput); if (this._maskedInput.val().length == selection[1] && !selection[0]) { this._replaceEntire = true; } else { emptyPart = this._getEmptyPart(selection[0]); this._pasted = this._pasted.substring(0, emptyPart.match(/_/g).length); } }, _inputHandler: function() { if (kendo._activeElement() !== this._maskedInput[0]) { return; } var that = this; var old = that._old; var separator = that.options.separator; var value = that._maskedInput[0].value; var selection = caret(that._maskedInput)[0]; var lengthDiff = old.length - value.length; var entered; var validEntry; var updatedPart; var endSubstring; var startSubstring; var deletedPart; var emptyPart; var canUpdate; var restored; var oldpartValue; var nextSeparator; entered = that._isPasted ? that._pasted : value.substring(selection - 1, selection); validEntry = /\d/.test(entered); if (that._isPasted && that._replaceEntire && validEntry) { that._old = that._fillParts(parseInt(entered)); that._maskedInput.val(that._old); that._selectNearestSection(0); that._isPasted = that._replaceEntire = false; return; } if (that._isPasted) { lengthDiff = 0; } that._isPasted = false; if ((entered === separator && !that._backward)) { that._maskedInput.val(that._old); that._switchPart({ caret: selection, next: true }); return; } if (!value && that._backward) { that._old = that._emtpyMask; that._maskedInput.val(that._old); that._selectNearestSection(selection); return; } if ((!validEntry && !that._backward)) { that._maskedInput.val(that._old); that._selectNearestSection(selection); return; } if (!lengthDiff || lengthDiff > 0) { endSubstring = value.substring(selection, value.length); startSubstring = value.substring(0, selection); deletedPart = that._emtpyMask.substring(startSubstring.length, old.indexOf(endSubstring)); restored = startSubstring + deletedPart + endSubstring; oldpartValue = that._getPartValue(that._old, selection); nextSeparator = that._old.indexOf(separator, that._old.indexOf(oldpartValue) + 1); if (that._backward) { // if multiple parts if (deletedPart.split(separator).length > 1) { that._old = this._clearParts(restored, selection, selection + deletedPart.length); } else { emptyPart = this._getEmptyPart(selection); if (emptyPart == oldpartValue) { that._maskedInput.val(that._old); that._switchPart({ caret: selection }); return; } that._old = that._replacePart(restored, emptyPart, selection); } that._maskedInput.val(that._old); that._selectNearestSection(selection); return; } if (nextSeparator < 0 && oldpartValue.indexOf(MASKCHAR) === -1 && !that._canUpdateLast) { that._maskedInput.val(that._old); that._selectNearestSection(selection); return; } if (validEntry) { updatedPart = that._updatePart(oldpartValue, entered); canUpdate = updatedPart[updatedPart.search(/[0-9]/)] === "0"; restored = that._replacePart(restored, updatedPart, selection); that._maskedInput.val(restored); if (nextSeparator > 0 && !canUpdate) { that._selectNearestSection(nextSeparator + 1, true); } else { that._selectNearestSection(selection); } that._canUpdateLast = !(nextSeparator < 0 && !canUpdate); } that._old = restored; } else if (lengthDiff < 0) { that._maskedInput.val(that._old); that._selectNearestSection(that._old.length - 1); } }, }); kendo.cssProperties.registerPrefix("TimeDurationPicker", "k-input-"); kendo.cssProperties.registerValues("TimeDurationPicker", [{ prop: "rounded", values: kendo.cssProperties.roundedValues.concat([['full', 'full']]) }]); ui.plugin(TimeDurationPicker); })(window.kendo.jQuery); var kendo$1 = kendo; export { __meta__, kendo$1 as default };