UNPKG

@progress/kendo-ui

Version:

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

1,513 lines (1,236 loc) 59.5 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); require('./kendo.list.js'); require('./kendo.mobile.scroller.js'); require('./kendo.virtuallist.js'); require('./kendo.html.chip.js'); require('./kendo.html.chiplist.js'); require('./kendo.html.button.js'); var prefixSuffixContainers = require('./prefix-suffix-containers-BmDm564f.js'); require('./kendo.data.js'); require('./kendo.core.js'); require('./kendo.licensing.js'); require('@progress/kendo-licensing'); 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('./dropdowns-loader-Bc4IELFi.js'); require('./kendo.fx.js'); require('./kendo.draganddrop.js'); require('./kendo.userevents.js'); require('./valueMapper-q_OtZ-Tj.js'); const __meta__ = { id: "multiselect", name: "MultiSelect", category: "web", description: "The MultiSelect widget allows the selection from pre-defined values.", depends: [ "list", "html.chip", "html.chiplist", "html.button" ], 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, ui = kendo.ui, List = ui.List, encode = kendo.htmlEncode, html = kendo.html, keys = $.extend({ A: 65 }, kendo.keys), activeElement = kendo._activeElement, ObservableArray = kendo.data.ObservableArray, ID = "id", CHIP = ".k-chip", ACCEPT = "accept", FILTER = "filter", REBIND = "rebind", OPEN = "open", CLOSE = "close", CHANGE = "change", PROGRESS = "progress", SELECT = "select", DESELECT = "deselect", ARIA_DISABLED = "aria-disabled", ARIA_READONLY = "aria-readonly", ARIA_EXPANDED = "aria-expanded", ARIA_HIDDEN = "aria-hidden", ARIA_ACTIVEDESCENDANT = "aria-activedescendant", FOCUSEDCLASS = "k-focus", SELECTEDCLASS = "k-selected", HOVERCLASS = "k-hover", STATEDISABLED = "k-disabled", NOCLICKCLASS = "k-no-click", DISABLED = "disabled", READONLY = "readonly", AUTOCOMPLETEVALUE = "off", ns = ".kendoMultiSelect", CLICK = "click" + ns, KEYDOWN = "keydown" + ns, MOUSEENTER = "mouseenter" + ns, MOUSELEAVE = "mouseleave" + ns, HOVEREVENTS = MOUSEENTER + " " + MOUSELEAVE, quotRegExp = /"/g, isArray = Array.isArray, styles = ["font-family", "font-size", "font-stretch", "font-style", "font-weight", "letter-spacing", "text-transform", "line-height"]; var MultiSelect = List.extend({ init: function(element, options) { var that = this, id, disabled; that.ns = ns; List.fn.init.call(that, element, options); that._optionsMap = {}; that._customOptions = {}; that.options.inputMode = that.options.inputMode || that.element.attr("inputmode") || "text"; that._wrapper(); that._inputValuesContainer(); that._tagList(); that._input(); that._textContainer(); that._clearButton(); that._arrowButton(); that._tabindex(that.input); element = that.element.attr("multiple", "multiple").hide(); options = that.options; if (!options.placeholder) { options.placeholder = element.data("placeholder"); } id = element.attr(ID); if (!id) { id = kendo.guid(); } if (id) { that._tagID = id + "_tag_active"; id = id + "_taglist"; that.tagList.attr(ID, id); } that._initialOpen = true; if (options.label) { this._label(); } that._aria(); that._dataSource(); that._ignoreCase(); that._popup(); that._tagTemplate(); that.requireValueMapper(that.options); that._initList(); that._reset(); that._enable(); that._placeholder(); if (options.autoBind) { that.dataSource.fetch(); } else if (options.value) { that._preselect(options.value); } disabled = $(that.element).parents("fieldset").is(':disabled'); if (disabled) { that.enable(false); } that._toggleCloseVisibility(); that._applyCssClasses(); prefixSuffixContainers.addInputPrefixSuffixContainers({ widget: that, wrapper: that.wrapper, options: that.options, prefixInsertBefore: that._inputValuesContainer, suffixInsertAfter: options.clearButton ? that._clear : that.element.find("k-input-values") }); if (that.floatingLabel) { that.floatingLabel.refresh(); } kendo.notify(that); }, options: { name: "MultiSelect", tagMode: "multiple", enabled: true, autoBind: true, autoClose: true, highlightFirst: true, dataTextField: "", dataValueField: "", filter: "startswith", ignoreCase: true, minLength: 1, messages: { "singleTag": "item(s) selected", "clear": "clear", "deleteTag": "delete", "noData": "No data found.", "downArrow": "select" }, enforceMinLength: false, delay: 100, value: null, maxSelectedItems: null, placeholder: "", height: 200, animation: {}, virtual: false, itemTemplate: "", tagTemplate: "", groupTemplate: (data) => encode(data), fixedGroupTemplate: (data) => encode(data), prefixOptions: { separator: true }, suffixOptions: { separator: true }, clearButton: true, autoWidth: false, popup: null, size: "medium", fillMode: "solid", rounded: "medium", label: null }, events: [ OPEN, CLOSE, CHANGE, SELECT, DESELECT, "filtering", "dataBinding", "dataBound" ], setDataSource: function(dataSource) { this.options.dataSource = dataSource; this._state = ""; this._dataSource(); this.persistTagList = false; this.listView.setDataSource(this.dataSource); if (this.options.autoBind) { this.dataSource.fetch(); } }, setOptions: function(options) { var listOptions = this._listOptions(options); List.fn.setOptions.call(this, options); this.listView.setOptions(listOptions); this._accessors(); this._aria(); this._tagTemplate(); this._placeholder(); this._clearButton(); this._arrowButton(); }, currentTag: function(candidate) { var that = this; if (candidate !== undefined$1) { if (that._currentTag) { that._currentTag .removeClass(FOCUSEDCLASS) .removeAttr(ID); that._currentTag.find(".k-chip-action").attr(ARIA_HIDDEN, true); that.input.removeAttr(ARIA_ACTIVEDESCENDANT); } if (candidate) { candidate.addClass(FOCUSEDCLASS).attr(ID, that._tagID); candidate.find(".k-chip-action").removeAttr(ARIA_HIDDEN); that.input.attr(ARIA_ACTIVEDESCENDANT, that._tagID); } that._currentTag = candidate; } else { return that._currentTag; } }, dataItems: function() { return this.listView.selectedDataItems(); }, destroy: function() { var that = this, ns = that.ns; clearTimeout(that._busy); clearTimeout(that._typingTimeout); if (that.filterInput) { that.filterInput.off(ns); } that.wrapper.off(ns); that.tagList.off(ns); that.input.off(ns); that._clear.off(ns); List.fn.destroy.call(that); }, _onActionSheetCreate: function() { var that = this; that.filterInput .on("keydown" + ns, that._keydown.bind(that)) .on("input" + ns, that._search.bind(that)) .on("paste" + ns, that._search.bind(that)) .attr({ "role": "combobox", "aria-expanded": false, "aria-controls": that.input.attr("aria-controls"), "aria-autocomplete": that.input.attr("aria-autocomplete"), "aria-describedby": that.input.attr("aria-describedby") }); that.popup.bind("activate", () => { that.filterInput.val(that.input.val()); that.filterInput.trigger("focus"); }); that.popup.bind("close", () => { that.input.trigger("focus"); }); }, _aria: function() { var that = this, id = that.ul[0].id, autocomplete = this.options.filter === "none" ? "none" : "list", tagListId = that.tagList.attr(ID); that.input.attr({ "role": "combobox", "aria-expanded": false, "aria-controls": id, "aria-autocomplete": autocomplete, "aria-describedby": tagListId }); that._ariaLabel(that._focused); }, _activateItem: function() { if (this.popup.visible()) { List.fn._activateItem.call(this); } this.currentTag(null); }, _listOptions: function(options) { var that = this; var listOptions = List.fn._listOptions.call(that, $.extend(options, { selectedItemChange: that._selectedItemChange.bind(that), selectable: "multiple" })); var itemTemplate = this.options.itemTemplate || this.options.template; var template = listOptions.itemTemplate || itemTemplate || listOptions.template; if (!template) { template = data => encode(kendo.getter(listOptions.dataTextField)(data)); } listOptions.template = template; return listOptions; }, _setListValue: function() { List.fn._setListValue.call(this, this._initialValues.slice(0)); }, _listChange: function(e) { var data = this.dataSource.flatView(); var optionsMap = this._optionsMap; var valueGetter = this._value; if (this._state === REBIND) { this._state = ""; } for (var i = 0; i < e.added.length; i++) { if (optionsMap[valueGetter(e.added[i].dataItem)] === undefined$1) { this._render(data); //render select element <option> tags if the item does not persist in the current data view break; } } this._selectValue(e.added, e.removed); }, _selectedItemChange: function(e) { var items = e.items; var context; var idx; for (idx = 0; idx < items.length; idx++) { context = items[idx]; this.tagList.children(CHIP).eq(context.index).children("span").first().html(this.tagTextTemplate(context.item)); } }, _wrapperMousedown: function(e) { var that = this; var notInput = e.target.nodeName.toLowerCase() !== "input"; var target = $(e.target); var closeButton = target.closest(".k-input-button, .k-chip").children("[class*='-i-caret-alt-down']")[0]; var removeButton = target.closest("[class*='-i-x']")[0]; if (notInput && !(removeButton && kendo.support.mobileOS) && e.cancelable) { e.preventDefault(); } if (!removeButton) { if (closeButton && that.popup.visible()) { that.toggle(false); } else { if (that.input[0] !== activeElement() && notInput) { that.input.trigger("focus"); } if (that.options.minLength === 1 && !that.popup.visible()) { that.open(); } } } }, _inputFocus: function() { this._placeholder(false, true); this.wrapper.addClass(FOCUSEDCLASS); }, _inputFocusout: function(e) { var that = this; if (that.filterInput && e.relatedTarget === that.filterInput[0]) { return; } clearTimeout(that._typingTimeout); that.wrapper.removeClass(FOCUSEDCLASS); that._placeholder(!that.listView.selectedDataItems()[0], true); that.close(); if (that._state === FILTER) { that._state = ACCEPT; that.listView.skipUpdate(true); } if (that.listView.bound() && that.listView.isFiltered()) { that.persistTagList = true; that._clearFilter(); } that.element.trigger("blur"); }, _removeTag: function(tag, shouldTrigger) { var that = this; var state = that._state; var position = tag.index(); var listView = that.listView; var value = listView.value()[position]; var dataItem = that.listView.selectedDataItems()[position]; var customIndex = that._customOptions[value]; var listViewChildren = listView.element[0].children; var option; var listViewChild; if (that.trigger(DESELECT, { dataItem: dataItem, item: tag })) { that._close(); return; } if (customIndex === undefined$1 && (state === ACCEPT || state === FILTER)) { customIndex = that._optionsMap[value]; } var done = function() { that.currentTag(null); if (shouldTrigger) { that._change(); } that._refreshTagListAria(); that._close(); }; if (customIndex === undefined$1 && listView.select().length) { that.persistTagList = false; listView.select(listView.select()[position]).done(done); } else { option = that.element[0].children[customIndex]; if (option) { option.selected = false; } listView.removeAt(position); if (listView._removedAddedIndexes) { listView._removedAddedIndexes.splice(position, 1); } listViewChild = listViewChildren[customIndex]; if (listViewChild) { listViewChildren[customIndex].classList.remove("k-selected"); } if (that.options.tagMode !== "single") { tag.remove(); } else { that._updateTagListHTML(); } done(); } }, _tagListClick: function(e) { e.preventDefault(); e.stopPropagation(); var target = $(e.currentTarget); if (target.is("[class*='-i-x-circle']")) { this._removeTag(target.closest(CHIP), true); } }, _clearValue: function() { var that = this; if (that.options.tagMode === "single") { that._clearSingleTagValue(); } else { that.tagList.children(CHIP).each(function(index, tag) { that._removeTag($(tag), false); }); } that.input.val(""); that._search(true); that._change(); that.focus(); that._hideClear(); if (that._state === FILTER) { that._state = ACCEPT; } }, _clearSingleTagValue: function() { var that = this; var items = that.dataItems(); var tags = that.tagList.children(CHIP); var persistTagList = that.persistTagList; for (var i = 0; i < items.length; i += 1) { if (that.trigger(DESELECT, { dataItem: items[i], item: tags.first() })) { that._close(); return; } } if (persistTagList) { that.persistTagList = false; } that.listView.value([]); that.persistTagList = persistTagList; }, _focusHandler: function() { var input = this.input; var active = activeElement(); var isActive = input[0] === active; if (!isActive) { this.input.trigger("focus"); } }, _editable: function(options) { var that = this, disable = options.disable, readonly = options.readonly, wrapper = that.wrapper.off(ns), tagList = that.tagList.off(ns), input = that.input.off(ns); if (!readonly && !disable) { wrapper .removeClass(STATEDISABLED) .removeClass(NOCLICKCLASS) .on(HOVEREVENTS, that._toggleHover) .on("mousedown" + ns + " touchend" + ns, that._wrapperMousedown.bind(that)) .on(CLICK, that._focusHandler.bind(that)); that.input.on(KEYDOWN, that._keydown.bind(that)) .on("paste" + ns, that._search.bind(that)) .on("input" + ns, that._search.bind(that)) .on("focus" + ns, that._inputFocus.bind(that)) .on("focusout" + ns, that._inputFocusout.bind(that)); that._clear.on(CLICK + " touchend" + ns, that._clearValue.bind(that)); input.prop(DISABLED, false) .prop(READONLY, false) .attr(ARIA_DISABLED, false) .attr(ARIA_READONLY, false); that.element.prop(DISABLED, false); tagList .on(MOUSEENTER, CHIP, function() { $(this).addClass(HOVERCLASS); }) .on(MOUSELEAVE, CHIP, function() { $(this).removeClass(HOVERCLASS); }) .on(CLICK + " touchend" + ns, ".k-chip .k-icon,.k-chip .k-svg-icon", that._tagListClick.bind(that)); } else { wrapper.toggleClass(STATEDISABLED, disable) .toggleClass(NOCLICKCLASS, readonly); input.attr(DISABLED, disable) .attr(READONLY, readonly) .attr(ARIA_DISABLED, disable) .attr(ARIA_READONLY, readonly); that.element.prop(DISABLED, disable); } }, _close: function() { var that = this; if (that.options.autoClose) { that.close(); } else { that.popup.position(); } }, _filterSource: function(filter, force) { if (!force) { force = this._retrieveData; } this._retrieveData = false; List.fn._filterSource.call(this, filter, force); }, close: function() { this._activeItem = null; this.input.removeAttr(ARIA_ACTIVEDESCENDANT); this.popup.close(); }, open: function() { var that = this, filterValue = that.input.val().toLowerCase(), listViewFilter = that.listView.dataSource.filter(), listViewFilterValue = ""; if (listViewFilter && listViewFilter.filters.length > 0) { listViewFilterValue = (listViewFilter.filters[0].value || "").toString().toLowerCase(); } if (that._request) { that._retrieveData = false; } if (that._retrieveData || !that.listView.bound() || (that._state === ACCEPT && filterValue !== listViewFilterValue)) { that._open = true; that._state = REBIND; that.listView.skipUpdate(true); that.persistTagList = that._initialOpen && !that.listView.bound() ? false : true; that._filterSource(); that._focusItem(); } else if (that._allowOpening()) { //selects values in autoBind false and non virtual scenario on initial load if (that._initialOpen && !that.options.autoBind && !that.options.virtual && that.options.value && !$.isPlainObject(that.options.value[0])) { that.value(that.value() || that._initialValues); } // 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._initialOpen = false; that.popup.open({ altTarget: that.wrapper.add(that.element).add(that.input) }); that._focusItem(); } }, toggle: function(toggle) { toggle = toggle !== undefined$1 ? toggle : !this.popup.visible(); this[toggle ? OPEN : CLOSE](); }, refresh: function() { this.listView.refresh(); }, _floatCheck: function() { if (this.listView) { var hasValue = (this.value() && this.value().length); return !hasValue && !this.popup.visible(); } return true; }, _listBound: function() { var that = this; var data = that.dataSource.flatView(); that._render(data); that._renderFooter(); that._renderNoData(); that._toggleNoData(!data.length); that._resizePopup(); if (that._open) { that._open = false; that.toggle(that._allowOpening()); } that.popup.position(); that._updateItemFocus(); if (that._touchScroller) { that._touchScroller.reset(); } that._hideBusy(); that.trigger("dataBound"); }, _updateItemFocus: function() { var that = this, data = that.dataSource.flatView(), skip = that.listView.skip(), isFirstPage = skip === undefined$1 || skip === 0; if (data.length && isFirstPage) { if (!that.options.highlightFirst) { that.listView.focus(-1); } else { that.listView.focusFirst(); } } }, _inputValue: function() { var that = this; var inputValue = that.filterInput && activeElement() === that.filterInput[0] ? that.filterInput.val() : that.input.val(); if (that.options.placeholder === inputValue) { inputValue = ""; } return inputValue; }, value: function(value) { var that = this; var listView = that.listView; var oldValue = listView.value().slice(); var maxSelectedItems = that.options.maxSelectedItems; var clearFilters = listView.bound() && listView.isFiltered(); if (value === undefined$1) { return oldValue; } that.persistTagList = false; that.requireValueMapper(that.options, value); value = that._normalizeValues(value); if (maxSelectedItems !== null && value.length > maxSelectedItems) { value = value.slice(0, maxSelectedItems); } if (clearFilters) { that._clearFilter(); } listView.value(value); that._old = that._valueBeforeCascade = value.slice(); //get a new array reference if (!clearFilters) { that._fetchData(); } that._toggleCloseVisibility(); }, _preselect: function(data, value) { var that = this; if (!isArray(data) && !(data instanceof kendo.data.ObservableArray)) { data = [data]; } if ($.isPlainObject(data[0]) || data[0] instanceof kendo.data.ObservableObject || !that.options.dataValueField) { that.dataSource.data(data); that.value(value || that._initialValues); that._retrieveData = true; } }, _setOption: function(value, selected) { var option = this.element[0].children[this._optionsMap[value]]; if (option) { option.selected = selected; } }, _fetchData: function() { var that = this; var hasItems = !!that.dataSource.view().length; var isEmptyArray = that.listView.value().length === 0; if (isEmptyArray || that._request) { return; } if (that._retrieveData || (!that._fetch && !hasItems)) { that._fetch = true; that._retrieveData = false; that.dataSource.read().done(function() { that._fetch = false; }); } }, _isBound: function() { return this.listView.bound() && !this._retrieveData; }, _dataSource: function() { var that = this, element = that.element, options = that.options, dataSource = options.dataSource || {}; dataSource = isArray(dataSource) ? { data: dataSource } : dataSource; dataSource.select = element; dataSource.fields = [{ field: options.dataTextField }, { field: options.dataValueField }]; if (that.dataSource && that._refreshHandler) { that._unbindDataSource(); } else { that._progressHandler = that._showBusy; that._endRequestHandler = that._hideBusy; that._errorHandler = function() { that._hideBusy(); }; } that.dataSource = kendo.data.DataSource.create(dataSource) .bind(PROGRESS, that._progressHandler) .bind("requestEnd", that._endRequestHandler) .bind("error", that._errorHandler); }, _reset: function() { var that = this, element = that.element, formId = element.attr("form"), form = formId ? $("#" + formId) : element.closest("form"); if (form[0]) { that._resetHandler = function() { setTimeout(function() { that.value(that._initialValues); that._placeholder(); }); }; that._form = form.on("reset", that._resetHandler); } }, _initValue: function() { var value = this.options.value || this.element.val(); this._old = this._initialValues = this._normalizeValues(value); }, _normalizeValues: function(value) { var that = this; if (value === null) { value = []; } else if (value && $.isPlainObject(value)) { value = [that._value(value)]; } else if (value && $.isPlainObject(value[0])) { value = $.map(value, function(dataItem) { return that._value(dataItem); }); } else if (!isArray(value) && !(value instanceof ObservableArray)) { value = [value]; } else if (isArray(value)) { value = value.slice(); } return value; }, _change: function() { var that = this, value = that.value(); if (!compare(value, that._old)) { that._old = value.slice(); that.trigger(CHANGE); // trigger the DOM change event so any subscriber gets notified that.element.trigger(CHANGE); } that.popup.position(); that._toggleCloseVisibility(); }, _click: function(e) { var that = this; var item = e.item; e.preventDefault(); that._select(item).done(function() { that._activeItem = item; that._change(); that._close(); }); }, _getActiveItem: function() { return this._activeItem || $(this.listView.items()[this._getSelectedIndices().length - 1]) || this.listView.focus(); }, _getSelectedIndices: function() { return this.listView._selectedIndices || this.listView._selectedIndexes; }, _keydown: function(e) { var that = this; var key = e.keyCode; var tag = that._currentTag; var listView = that.listView; var hasValue = that.input.val(); var isRtl = kendo.support.isRtl(that.wrapper); var visible = that.popup.visible(); var dir = 0; var activeItemIdx; var handled = false; if (key !== keys.ENTER) { this._multipleSelection = false; } if (key === keys.DOWN) { e.preventDefault(); if (!visible) { that.open(); if (!listView.focus()) { listView.focusFirst(); } e.stopPropagation(); return; } if (listView.focus()) { if (!that._activeItem && e.shiftKey) { that._activeItem = listView.focus(); dir = -1; } activeItemIdx = listView.getElementIndex(that._getActiveItem().first()); listView.focusNext(); if (!listView.focus()) { listView.focusLast(); } else { if (e.shiftKey && !that.options.virtual) { this._multipleSelection = true; that._selectRange(activeItemIdx, listView.getElementIndex(listView.focus().first()) + dir); } } } else { listView.focusFirst(); } handled = true; } else if (key === keys.UP) { if (visible) { if (!that._activeItem && e.shiftKey) { that._activeItem = listView.focus(); dir = 1; } activeItemIdx = listView.getElementIndex(that._getActiveItem().first()); listView.focusPrev(); if (!listView.focus()) { that.close(); } else { if (e.shiftKey && !that.options.virtual) { this._multipleSelection = true; that._selectRange(activeItemIdx, listView.getElementIndex(listView.focus().first()) + dir); } } } handled = true; e.preventDefault(); } else if ((key === keys.LEFT && !isRtl) || (key === keys.RIGHT && isRtl)) { if (!hasValue) { tag = tag ? tag.prev(CHIP) : that.tagList.children(CHIP).last(); if (tag[0]) { that.currentTag(tag); } } handled = true; } else if ((key === keys.RIGHT && !isRtl) || (key === keys.LEFT && isRtl)) { if (!hasValue && tag) { tag = tag.next(CHIP); that.currentTag(tag[0] ? tag : null); } handled = true; } else if (e.ctrlKey && !e.altKey && key === keys.A && visible && !that.options.virtual) { this._multipleSelection = true; if (this._getSelectedIndices().length === listView.items().length) { that._activeItem = null; } if (listView.items().length) { that._selectRange(0, listView.items().length - 1); } handled = true; } else if (key === keys.ENTER && visible) { if (!listView.focus()) { e.stopPropagation(); return; } e.preventDefault(); if (this._multipleSelection) { this._multipleSelection = false; if (listView.focus().hasClass(SELECTEDCLASS)) { that._close(); e.stopPropagation(); return; } } that._select(listView.focus()).done(function() { that._change(); that._close(); }); handled = true; } else if (key === keys.SPACEBAR && e.ctrlKey && visible) { if (that._activeItem && listView.focus() && listView.focus()[0] === that._activeItem[0]) { that._activeItem = null; } if (!$(listView.focus()).hasClass(SELECTEDCLASS)) { that._activeItem = listView.focus(); } that._select(listView.focus()).done(function() { that._change(); }); handled = true; e.preventDefault(); } else if (key === keys.SPACEBAR && e.shiftKey && visible && !that.options.virtual) { var activeIndex = listView.getElementIndex(that._getActiveItem()); var currentIndex = listView.getElementIndex(listView.focus()); if (activeIndex !== undefined$1 && currentIndex !== undefined$1) { that._selectRange(activeIndex, currentIndex); } handled = true; e.preventDefault(); } else if (key === keys.ESC) { if (visible) { e.preventDefault(); } else { that.tagList.children(CHIP).each(function(index, tag) { that._removeTag($(tag), false); }); that._change(); } that.close(); handled = true; } else if (key === keys.HOME) { if (visible) { if (!listView.focus()) { that.close(); } else { if (e.ctrlKey && e.shiftKey && !that.options.virtual) { that._selectRange(listView.getElementIndex(listView.focus()[0]), 0); } listView.focusFirst(); } } else if (!hasValue) { tag = that.tagList.children(CHIP).first()[0]; if (tag) { that.currentTag($(tag)); } } handled = true; } else if (key === keys.END) { if (visible) { if (!listView.focus()) { that.close(); } else { if (e.ctrlKey && e.shiftKey && !that.options.virtual) { that._selectRange( listView.getElementIndex(listView.focus()[0]), listView.element.children().length - 1 ); } listView.focusLast(); } } else if (!hasValue) { tag = that.tagList.children(CHIP).last()[0]; if (tag) { that.currentTag($(tag)); } } handled = true; } else if ((key === keys.DELETE || key === keys.BACKSPACE) && !hasValue) { that._state = ACCEPT; if (that.options.tagMode === "single") { that._clearSingleTagValue(); that._change(); that._close(); e.stopPropagation(); return; } if (key === keys.BACKSPACE && !tag) { tag = that.tagList.children(CHIP).last(); } if (tag && tag[0]) { that._removeTag(tag, true); } handled = true; } 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()); handled = true; } else { clearTimeout(that._typingTimeout); that._search(); handled = true; } if (handled) { e.stopPropagation(); } }, _placeholder: function(show, skipCaret) { var that = this; var input = that.input; var active = activeElement(); var placeholder = that.options.placeholder; var inputValue = input.val(); var isActive = input[0] === active; var caretPos = inputValue.length; if (!isActive || that.options.autoClose || inputValue === placeholder) { caretPos = 0; inputValue = ""; } if (show === undefined$1) { show = false; if (input[0] !== active) { show = !that.listView.selectedDataItems()[0]; } } that._prev = inputValue; input.toggleClass("k-readonly", show).val(show ? placeholder : inputValue); if (isActive && !skipCaret) { kendo.caret(input[0], caretPos, caretPos); } }, _option: function(dataValue, dataText, selected) { var option = "<option"; if (dataValue !== undefined$1) { dataValue += ""; if (dataValue.indexOf('"') !== -1) { dataValue = dataValue.replace(quotRegExp, "&quot;"); } option += ' value="' + dataValue + '"'; } if (selected) { option += ' selected'; } option += ">"; if (dataText !== undefined$1) { option += kendo.htmlEncode(dataText); } return option += "</option>"; }, _render: function(data) { var selectedItems = this.listView.selectedDataItems(); var values = this.listView.value(); var length = data.length; var selectedIndex; var options = ""; var dataItem; var value; var idx; if (values.length !== selectedItems.length) { selectedItems = this._buildSelectedItems(values); } var custom = {}; var optionsMap = {}; for (idx = 0; idx < length; idx++) { dataItem = data[idx]; value = this._value(dataItem); selectedIndex = this._selectedItemIndex(value, selectedItems); if (selectedIndex !== -1) { selectedItems.splice(selectedIndex, 1); } optionsMap[value] = idx; options += this._option(value, this._text(dataItem), selectedIndex !== -1); } if (selectedItems.length) { for (idx = 0; idx < selectedItems.length; idx++) { dataItem = selectedItems[idx]; value = this._value(dataItem); custom[value] = length; optionsMap[value] = length; length += 1; options += this._option(value, this._text(dataItem), true); } } this._customOptions = custom; this._optionsMap = optionsMap; this.element.html(options); }, _buildSelectedItems: function(values) { var valueField = this.options.dataValueField; var textField = this.options.dataTextField; var result = []; var item; for (var idx = 0; idx < values.length; idx++) { item = {}; item[valueField] = values[idx]; item[textField] = values[idx]; result.push(item); } return result; }, _selectedItemIndex: function(value, selectedItems) { var valueGetter = this._value; var idx = 0; for (; idx < selectedItems.length; idx++) { if (value === valueGetter(selectedItems[idx])) { return idx; } } return -1; }, _search: function(noDelay) { let that = this; // noDelay may come as an even object, that is why an explicit === true check is needed. if (noDelay === true) { that._performSearch(); return; } clearTimeout(that._typingTimeout); that._typingTimeout = setTimeout(function() { that._performSearch(); }, that.options.delay); }, _performSearch: function() { var that = this, value = that._inputValue(); if (that._prev !== value) { that._prev = value; that.search(value); that._toggleCloseVisibility(); } }, _toggleCloseVisibility: function() { if (this.value().length || (this.input.val() && this.input.val() !== this.options.placeholder)) { this._showClear(); } else { this._hideClear(); } }, _allowOpening: function() { return this._allowSelection() && List.fn._allowOpening.call(this); }, _allowSelection: function() { var max = this.options.maxSelectedItems; return max === null || max > this.listView.value().length; }, updatePersistTagList: function(added, removed) { if (this.persistTagList.added && this.persistTagList.added.length === removed.length && this.persistTagList.removed && this.persistTagList.removed.length === added.length) { this.persistTagList = false; } else { this.listView._removedAddedIndexes = this._old.slice(); this.persistTagList = { added: added, removed: removed }; } }, _selectValue: function(added, removed) { var that = this; var total = that.dataSource.total(); var tagList = that.tagList; var getter = that._value; var removedItem; var addedItem; var idx; if (this.persistTagList) { this.updatePersistTagList(added, removed); that._refreshTagListAria(); return; } if (that.options.tagMode === "multiple") { for (idx = removed.length - 1; idx > -1; idx--) { removedItem = removed[idx]; if (tagList.children(CHIP).length) { tagList[0].removeChild(tagList[0].children[removedItem.position]); that._setOption(getter(removedItem.dataItem), false); } } for (idx = 0; idx < added.length; idx++) { addedItem = added[idx]; that.tagList.append(that.tagTemplate(addedItem.dataItem)); that._setOption(getter(addedItem.dataItem), true); } kendo.applyStylesFromKendoAttributes(that.tagList, ["background-color"]); } else { if (!that._maxTotal || that._maxTotal < total) { that._maxTotal = total; } this._updateTagListHTML(); for (idx = removed.length - 1; idx > -1; idx--) { that._setOption(getter(removed[idx].dataItem), false); } for (idx = 0; idx < added.length; idx++) { that._setOption(getter(added[idx].dataItem), true); } } that._refreshTagListAria(); that._refreshFloatingLabel(); that._placeholder(); }, _refreshTagListAria: function() { var that = this; html.renderChipList(that.tagList, $.extend({ selectable: that.value().length === 0 ? "none" : "multiple" }, that.options)); }, _updateTagListHTML: function() { var that = this; var values = that.value(); var total = that.dataSource.total(); var tagList = that.tagList; tagList.children(CHIP).each(function(index, tag) { $(tag).remove(); }); if (values.length) { that.tagList.append(that.tagTemplate({ values: values, dataItems: that.dataItems(), maxTotal: that._maxTotal, currentTotal: total })); kendo.applyStylesFromKendoAttributes(that.tagList, ["background-color"]); } that._refreshTagListAria(); }, _select: function(candidate) { var resolved = $.Deferred().resolve(); if (!candidate) { return resolved; } var that = this; var listView = that.listView; var dataItem = listView.dataItemByIndex(listView.getElementIndex(candidate)); var isSelected = candidate.hasClass("k-selected"); if (that._state === REBIND) { that._state = ""; } if (!that._allowSelection() && !isSelected) { return resolved; } if (that.trigger(isSelected ? DESELECT : SELECT, { dataItem: dataItem, item: candidate })) { that._close(); return resolved; } that.persistTagList = false; return listView.select(candidate).done(function() { that._placeholder(); if (that._state === FILTER) { that._state = ACCEPT; listView.skipUpdate(true); } }); }, _selectIndices: function(indices) {