UNPKG

@progress/kendo-ui

Version:

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

953 lines (768 loc) 30.9 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); require('./kendo.list.js'); require('./kendo.mobile.scroller.js'); require('./kendo.virtuallist.js'); var prefixSuffixContainers = require('./prefix-suffix-containers-BmDm564f.js'); require('./kendo.data.js'); require('./kendo.core.js'); require('./kendo.data.odata.js'); require('./kendo.data.xml.js'); require('./kendo.popup.js'); require('./kendo.label.js'); require('./kendo.floatinglabel.js'); require('./kendo.icons.js'); require('./kendo.html.icon.js'); require('./kendo.html.base.js'); require('@progress/kendo-svg-icons'); require('./kendo.actionsheet.js'); require('./kendo.html.button.js'); require('./dropdowns-loader-CMg_pnLB.js'); require('./kendo.fx.js'); require('./kendo.draganddrop.js'); require('./kendo.userevents.js'); require('./valueMapper-CU-4EASG.js'); const __meta__ = { id: "autocomplete", name: "AutoComplete", category: "web", description: "The AutoComplete widget provides suggestions depending on the typed text.It also allows multiple value entries.", depends: [ "list" ], features: [ { id: "mobile-scroller", name: "Mobile scroller", description: "Support for kinetic scrolling in mobile device", depends: [ "mobile.scroller" ] }, { id: "virtualization", name: "VirtualList", description: "Support for virtualization", depends: [ "virtuallist" ] } ] }; (function($, undefined$1) { var kendo = window.kendo, encode = kendo.htmlEncode, support = kendo.support, caret = kendo.caret, activeElement = kendo._activeElement, placeholderSupported = support.placeholder, ui = kendo.ui, List = ui.List, keys = kendo.keys, DataSource = kendo.data.DataSource, ARIA_DISABLED = "aria-disabled", ARIA_READONLY = "aria-readonly", CHANGE = "change", DISABLED = "disabled", READONLY = "readonly", FOCUSED = "k-focus", SELECTED = "k-selected", STATEDISABLED = "k-disabled", AUTOCOMPLETEVALUE = "off", HOVER = "k-hover", ns = ".kendoAutoComplete", HOVEREVENTS = "mouseenter" + ns + " mouseleave" + ns; function indexOfWordAtCaret(caretIdx, text, separator) { return separator ? text.substring(0, caretIdx).split(separator).length - 1 : 0; } function wordAtCaret(caretIdx, text, separator) { return text.split(separator)[indexOfWordAtCaret(caretIdx, text, separator)]; } function replaceWordAtCaret(caretIdx, text, word, separator, defaultSeparator) { var words = text.split(separator); words.splice(indexOfWordAtCaret(caretIdx, text, separator), 1, word); if (separator && words[words.length - 1] !== "") { words.push(""); } return words.join(defaultSeparator); } var AutoComplete = List.extend({ init: function(element, options) { var that = this, wrapper, disabled; that.ns = ns; options = Array.isArray(options) ? { dataSource: options } : options; List.fn.init.call(that, element, options); element = that.element; options = that.options; options.placeholder = options.placeholder || element.attr("placeholder"); if (placeholderSupported) { element.attr("placeholder", options.placeholder); } that._wrapper(); that._clearButton(); that._dataSource(); that._ignoreCase(); element[0].type = "text"; wrapper = that.wrapper; that._popup(); element .addClass("k-input-inner") .on("keydown" + ns, that._keydown.bind(that)) .on("keypress" + ns, that._keypress.bind(that)) .on("input" + ns, that._search.bind(that)) .on("paste" + ns, that._search.bind(that)) .on("focus" + ns, function() { that._prev = that._accessor(); that._oldText = that._prev; that._placeholder(false); wrapper.addClass(FOCUSED); }) .on("focusout" + ns, function(ev) { if (that.filterInput && ev.relatedTarget === that.filterInput[0]) { return; } that._change(); that._placeholder(); that.close(); wrapper.removeClass(FOCUSED); }) .attr({ autocomplete: AUTOCOMPLETEVALUE, role: "combobox", "aria-expanded": false }); that._clear.on("click" + ns + " touchend" + ns, that._clearValue.bind(that)); that._clear.on("mousedown" + ns, that._clearValueMouseDownHandler.bind(that)); that._enable(); that._old = that._accessor(); that._placeholder(); that._initList(); disabled = $(that.element).parents("fieldset").is(':disabled'); if (disabled) { that.enable(false); } that.listView.bind("click", function(e) { e.preventDefault(); }); that._resetFocusItemHandler = that._resetFocusItem.bind(that); prefixSuffixContainers.addInputPrefixSuffixContainers({ widget: that, wrapper: that.wrapper, options: that.options, prefixInsertBefore: that._inputValuesContainer, suffixInsertAfter: options.clearButton ? that._clear : that.element }); kendo.notify(that); that._toggleCloseVisibility(); that._applyCssClasses(); if (options.label) { that._label(); } that._aria(); }, options: { name: "AutoComplete", enabled: true, suggest: false, template: "", groupTemplate: (data) => encode(data), fixedGroupTemplate: (data) => encode(data), prefixOptions: { separator: true }, suffixOptions: { separator: true }, dataTextField: "", minLength: 1, enforceMinLength: false, delay: 200, height: 200, filter: "startswith", ignoreCase: true, highlightFirst: false, separator: null, placeholder: "", animation: {}, virtual: false, value: null, clearButton: true, autoWidth: false, popup: null, size: "medium", fillMode: "solid", rounded: "medium", label: null, }, _clearValueMouseDownHandler: function(ev) { var that = this; if (ev && ev.currentTarget && ev.currentTarget.classList.contains('k-clear-value')) { that._clearValueTrigger = true; } else { that._clearValueTrigger = false; } }, _onActionSheetCreate: function() { var that = this; if (that.filterInput) { that.filterInput .on("keydown" + ns, that._keydown.bind(that)) .on("keypress" + ns, that._keypress.bind(that)) .on("input" + ns, that._search.bind(that)) .on("paste" + ns, that._search.bind(that)) .attr({ autocomplete: AUTOCOMPLETEVALUE, role: "combobox", "aria-expanded": false }); that.popup.bind("activate", () => { that.filterInput.val(that.element.val()); that.filterInput.trigger("focus"); }); that.popup.bind("deactivate", () => { that.element.trigger("focus"); }); } }, _onCloseButtonPressed: function() { var that = this; if (that.filterInput && activeElement() === that.filterInput[0]) { that.element.val(that.filterInput.val()); } }, _popup: function() { List.fn._popup.call(this); this.popup.element.addClass("k-autocomplete-popup"); }, _dataSource: function() { var that = this; if (that.dataSource && that._refreshHandler) { that._unbindDataSource(); } else { that._progressHandler = that._showBusy; that._errorHandler = that._hideBusy; } that.dataSource = DataSource.create(that.options.dataSource) .bind("progress", that._progressHandler) .bind("error", that._errorHandler); }, setDataSource: function(dataSource) { this.options.dataSource = dataSource; this._dataSource(); this.listView.setDataSource(this.dataSource); }, events: [ "open", "close", CHANGE, "select", "filtering", "dataBinding", "dataBound" ], setOptions: function(options) { var listOptions = this._listOptions(options); List.fn.setOptions.call(this, options); this.listView.setOptions(listOptions); this._accessors(); this._aria(); this._clearButton(); }, _listOptions: function(options) { var listOptions = List.fn._listOptions.call(this, $.extend(options, { skipUpdateOnBind: true })); listOptions.dataValueField = listOptions.dataTextField; listOptions.selectedItemChange = null; return listOptions; }, _editable: function(options) { var that = this, element = that.element, wrapper = that.wrapper.off(ns), readonly = options.readonly, disable = options.disable; if (!readonly && !disable) { wrapper .removeClass(STATEDISABLED) .on(HOVEREVENTS, that._toggleHover); element.prop(DISABLED, false) .prop(READONLY, false) .attr(ARIA_DISABLED, false) .attr(ARIA_READONLY, false); } else { wrapper .addClass(disable ? STATEDISABLED : "") .removeClass(disable ? "" : STATEDISABLED); element.attr(DISABLED, disable) .attr(READONLY, readonly) .attr(ARIA_DISABLED, disable) .attr(ARIA_READONLY, readonly); } that._toggleCloseVisibility(); }, close: function() { var that = this; var current = that.listView.focus(); if (current) { current.removeClass(SELECTED); } that.popup.close(); that._deactivateItem(); }, destroy: function() { var that = this; that.element.off(ns); that._clear.off(ns); that.wrapper.off(ns); if (that.filterInput) { that.filterInput.off(ns); } List.fn.destroy.call(that); }, refresh: function() { this.listView.refresh(); }, select: function(li) { this._select(li); }, search: function(word) { let that = this, options = that.options, ignoreCase = options.ignoreCase, separator = that._separator(), length, lowerCaseValue, accentFoldingFiltering = that.dataSource.options.accentFoldingFiltering, element = that.filterInput && activeElement() === that.filterInput[0] ? that.filterInput : that.element; word = word || that._accessor(); clearTimeout(that._typingTimeout); if (separator) { word = wordAtCaret(caret(element)[0], word, separator); } length = word.length; if ((!options.enforceMinLength && !length) || length >= options.minLength) { that._open = true; that._mute(function() { this.listView.value([]); }); lowerCaseValue = accentFoldingFiltering ? word.toLocaleLowerCase(accentFoldingFiltering) : word.toLowerCase(); that._filterSource({ value: ignoreCase ? lowerCaseValue : word, operator: options.filter, field: options.dataTextField, ignoreCase: ignoreCase }); that.one("close", that._unifySeparators.bind(that)); } that._toggleCloseVisibility(); }, suggest: function(word) { var that = this, key = that._last, value = that._accessor(), currentValue = that.value(), element = that.element[0], caretIdx = caret(element)[0], separator = that._separator(), words = value.split(separator), wordIndex = indexOfWordAtCaret(caretIdx, value, separator), selectionEnd = caretIdx, idx, accentFoldingFiltering = that.dataSource.options.accentFoldingFiltering; if (key == keys.BACKSPACE || key == keys.DELETE) { that._last = undefined$1; return; } word = word || ""; if (typeof word !== "string") { if (word[0]) { word = that.dataSource.view()[List.inArray(word[0], that.ul[0])]; } word = word ? that._text(word) : ""; } if (caretIdx <= 0) { caretIdx = (accentFoldingFiltering ? value.toLocaleLowerCase(accentFoldingFiltering) : value.toLowerCase()).indexOf(accentFoldingFiltering ? word.toLocaleLowerCase(accentFoldingFiltering) : word.toLowerCase()) + 1; } idx = value.substring(0, caretIdx).lastIndexOf(that._defaultSeparator()); idx = idx > -1 ? caretIdx - (idx + that._defaultSeparator().length) : caretIdx; value = words[wordIndex].substring(0, idx); if (word) { word = word.toString(); idx = (accentFoldingFiltering ? word.toLocaleLowerCase(accentFoldingFiltering) : word.toLowerCase()).indexOf(accentFoldingFiltering ? value.toLocaleLowerCase(accentFoldingFiltering) : value.toLowerCase()); if (idx > -1) { word = word.substring(idx + value.length); selectionEnd = caretIdx + word.length; value += word; } if (separator && words[words.length - 1] !== "") { words.push(""); } } words[wordIndex] = value; if (typeof that.options.separator == 'object' && that.options.separator != null) { if (currentValue.length > 1) { let lastSeparator = [...currentValue.matchAll(separator.source)].pop(); if (lastSeparator) { that._accessor(words.slice(0, -1).join(that._defaultSeparator() || "") + lastSeparator + words[words.length - 1]); } else { that._accessor(words.slice(0, -1).join(that._defaultSeparator() || "")); } } else { that._accessor(words.join(this._defaultSeparator() || "")); } } else { that._accessor(words.join(separator || "")); } if (element === activeElement()) { caret(element, caretIdx, selectionEnd); } }, value: function(value) { if (value !== undefined$1) { this.listView.value(value); this._accessor(value); this._old = this._accessor(); this._oldText = this._accessor(); } else { return this._accessor(); } this._toggleCloseVisibility(); this._refreshFloatingLabel(); }, _click: function(e) { var item = e.item; var that = this; var element = that.element; var dataItem = that.listView.dataItemByIndex(that.listView.getElementIndex(item)); e.preventDefault(); that._active = true; if (that.trigger("select", { dataItem: dataItem, item: item })) { that.close(); return; } that._oldText = element.val(); that._select(item).done(function() { that._blur(); caret(element, element.val().length); }); }, _clearText: $.noop, _highlightFirst: function() { var index = this.options.highlightFirst ? 0 : -1; this.listView.focus(index); }, _resetFocusItem: function() { if (this.options.virtual) { this.listView.scrollTo(0); } this._highlightFirst(); }, _listBound: function() { var that = this; var popup = that.popup; var options = that.options; var data = that.dataSource.flatView(); var length = data.length; var groupsLength = that.dataSource._group ? that.dataSource._group.length : 0; var isActive = that.element[0] === activeElement() || that.filterInput && that.filterInput[0] === activeElement(); var action; that._renderFooter(); that._renderNoData(); that._toggleNoData(!length); that._toggleHeader(!!groupsLength && !!length); that._resizePopup(); popup.position(); if (length) { if (options.suggest && isActive && that._inputValue()) { that.suggest(data[0]); } that._highlightFirst(); } if (that._open) { that._open = false; action = that._allowOpening() ? "open" : "close"; if (that._typingTimeout && !isActive) { action = "close"; } if (length) { that._resetFocusItem(); if (options.virtual) { that.popup .unbind("activate", that._resetFocusItemHandler) .one("activate", that._resetFocusItemHandler); } } popup[action](); that._typingTimeout = undefined$1; } if (that._touchScroller) { that._touchScroller.reset(); } that._hideBusy(); that.trigger("dataBound"); }, _mute: function(callback) { this._muted = true; callback.call(this); this._muted = false; }, _listChange: function() { var isActive = this._active || this.element[0] === activeElement(); if (isActive && !this._muted) { this._selectValue(this.listView.selectedDataItems()[0]); } }, _selectValue: function(dataItem) { var separator = this._separator(); var text = ""; if (dataItem) { text = this._text(dataItem); } if (text === null) { text = ""; } if (separator) { text = replaceWordAtCaret(caret(this.element)[0], this._accessor(), text, separator, this._defaultSeparator()); } this._prev = text; this._accessor(text); this._placeholder(); }, _unifySeparators: function() { this._accessor(this.value().split(this._separator()).join(this._defaultSeparator())); return this; }, _preselect: function(value, text) { this._inputValue(text); this._accessor(value); this._old = this.oldText = this._accessor(); this.listView.setValue(value); this._placeholder(); }, _change: function() { var that = this; var value = that._unifySeparators().value(); var trigger = value !== List.unifyType(that._old, typeof value); var valueUpdated = trigger && !that._typing; var itemSelected = that._oldText !== value; var clearValueTrigger = that._clearValueTrigger; that._old = value; that._oldText = value; if (that.filterInput && activeElement() === that.filterInput[0]) { that.element.val(that.filterInput.val()); } if ((valueUpdated || itemSelected) && !clearValueTrigger) { // trigger the DOM change event so any subscriber gets notified that.element.trigger(CHANGE); } if (trigger && !clearValueTrigger) { that.trigger(CHANGE); } that.typing = false; that._toggleCloseVisibility(); }, _accessor: function(value) { var that = this, element = that.filterInput && activeElement() === that.filterInput[0] ? that.filterInput[0] : that.element[0]; if (value !== undefined$1) { element.value = value === null ? "" : value; that._placeholder(); } else { value = element.value; if (element.className.indexOf("k-readonly") > -1) { if (value === that.options.placeholder) { return ""; } else { return value; } } return value; } }, _keydown: function(e) { var that = this; var key = e.keyCode; var listView = that.listView; var visible = that.popup.visible(); var current = listView.focus(); that._last = key; if (key === keys.DOWN) { if (visible) { this._move(current ? "focusNext" : "focusFirst"); } else if (that.value()) { that._filterSource({ value: that.ignoreCase ? that.value().toLowerCase() : that.value(), operator: that.options.filter, field: that.options.dataTextField, ignoreCase: that.ignoreCase }).done(function() { if (that._allowOpening()) { that._resetFocusItem(); that.popup.open(); } }); } e.preventDefault(); } else if (key === keys.ESC ) { if (visible) { e.preventDefault(); that.close(); } else { that._clearValue(); } } else if (e.altKey && key === keys.UP && visible) { e.preventDefault(); that.close(); } else if (key === keys.UP) { if (visible) { this._move(current ? "focusPrev" : "focusLast"); } e.preventDefault(); } else if (key === keys.HOME) { this._move("focusFirst"); } else if (key === keys.END) { this._move("focusLast"); } else if (key === keys.ENTER || key === keys.TAB) { if (key === keys.ENTER && visible) { e.preventDefault(); } if (visible && current) { var dataItem = listView.dataItemByIndex(listView.getElementIndex(current)); if (that.trigger("select", { dataItem: dataItem, item: current })) { return; } this._select(current); } this._blur(); } else if (that.popup.visible() && (key === keys.PAGEDOWN || key === keys.PAGEUP)) { e.preventDefault(); var direction = key === keys.PAGEDOWN ? 1 : -1; listView.scrollWith(direction * listView.screenHeight()); } else { // In some cases when the popup is opened resize is triggered which will cause it to close // Setting the below flag will prevent this from happening that.popup._hovered = true; that._search(); } }, _keypress: function() { this._oldText = this.element.val(); this._typing = true; }, _move: function(action) { this.listView[action](); if (this.options.suggest && this.listView.focus() == null && action == "focusNext") { this.listView.focus(0); this.suggest(this.listView._view[0].item); } else if (this.options.suggest && this.listView.focus() == null && action == "focusPrev") { let index = this.listView._view.length - 1; this.listView.focus(index); this.suggest(this.listView._view[index].item); } else if (this.options.suggest && (action == "focusFirst" || action == "focusLast")) { caret(this.element); } else if (this.options.suggest && this.listView.focus() != null) { this.suggest(this.listView.focus()); } }, _placeholder: function(show) { if (placeholderSupported) { return; } var that = this, element = that.element, placeholder = that.options.placeholder, value; if (placeholder) { value = element.val(); if (show === undefined$1) { show = !value; } if (!show) { if (value !== placeholder) { placeholder = value; } else { placeholder = ""; } } if (value === that._old && !show) { return; } element.toggleClass("k-readonly", show) .val(placeholder); if (!placeholder && element[0] === document.activeElement) { caret(element[0], 0, 0); } } }, _separator: function() { var separator = this.options.separator; if (separator instanceof Array) { return new RegExp(separator.join("|"), 'gi'); } return separator; }, _defaultSeparator: function() { var separator = this.options.separator; if (separator instanceof Array) { return separator[0]; } return separator; }, _inputValue: function() { return this.element.val(); }, _search: function() { var that = this; clearTimeout(that._typingTimeout); that._typingTimeout = setTimeout(function() { if (that._prev !== that._accessor()) { that._prev = that._accessor(); that.search(); } }, that.options.delay); }, _select: function(candidate) { var that = this; that._active = true; return that.listView.select(candidate).done(function() { that._active = false; }); }, _clearButton: function() { List.fn._clearButton.call(this); if (this.options.clearButton) { this._clear.insertAfter(this.element); } }, _toggleHover: function(e) { $(e.currentTarget).toggleClass(HOVER, e.type === "mouseenter"); }, _toggleCloseVisibility: function() { var preventShow = this.element.is(":disabled") || this.element.is("[readonly]"); if (this.value() && !preventShow) { this._showClear(); } else { this._hideClear(); } }, _wrapper: function() { var that = this, element = that.element, DOMelement = element[0], wrapper; wrapper = element.parent(); if (!wrapper.is("span.k-autocomplete")) { wrapper = element.wrap("<span />").parent(); } wrapper.attr("tabindex", -1); wrapper[0].style.cssText = DOMelement.style.cssText; element.css({ width: "", height: DOMelement.style.height }); that._focused = that.element; that.wrapper = wrapper .addClass("k-autocomplete k-input") .addClass(DOMelement.className) .removeClass('input-validation-error'); }, _clearValue: function() { this._clearValueTrigger = false; List.fn._clearValue.call(this); this.element.trigger("focus"); } }); ui.plugin(AutoComplete); kendo.cssProperties.registerPrefix("AutoComplete", "k-input-"); kendo.cssProperties.registerValues("AutoComplete", [{ prop: "rounded", values: kendo.cssProperties.roundedValues.concat([['full', 'full']]) }]); })(window.kendo.jQuery); var kendo$1 = kendo; exports.__meta__ = __meta__; exports.default = kendo$1;