/** * Kendo UI v2016.1.112 (http://www.telerik.com/kendo-ui) * Copyright 2016 Telerik AD. All rights reserved. * * Kendo UI commercial licenses may be obtained at * http://www.telerik.com/purchase/license-agreement/kendo-ui-complete * If you do not own a commercial license, this file shall be governed by the trial license terms. */ (function (f, define) { define('kendo.autocomplete', [ 'kendo.list', 'kendo.mobile.scroller' ], f); }(function () { var __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) { var kendo = window.kendo, 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', DEFAULT = 'k-state-default', DISABLED = 'disabled', READONLY = 'readonly', FOCUSED = 'k-state-focused', SELECTED = 'k-state-selected', STATEDISABLED = 'k-state-disabled', HOVER = 'k-state-hover', ns = '.kendoAutoComplete', HOVEREVENTS = 'mouseenter' + ns + ' mouseleave' + ns, proxy = $.proxy; 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) { var words = text.split(separator); words.splice(indexOfWordAtCaret(caretIdx, text, separator), 1, word); if (separator && words[words.length - 1] !== '') { words.push(''); } return words.join(separator); } var AutoComplete = List.extend({ init: function (element, options) { var that = this, wrapper, disabled; that.ns = ns; options = $.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._loader(); that._dataSource(); that._ignoreCase(); element[0].type = 'text'; wrapper = that.wrapper; that._popup(); element.addClass('k-input').on('keydown' + ns, proxy(that._keydown, that)).on('keypress' + ns, proxy(that._keypress, that)).on('paste' + ns, proxy(that._search, that)).on('focus' + ns, function () { that._prev = that._accessor(); that._oldText = that._prev; that._placeholder(false); wrapper.addClass(FOCUSED); }).on('focusout' + ns, function () { that._change(); that._placeholder(); wrapper.removeClass(FOCUSED); }).attr({ autocomplete: 'off', role: 'textbox', 'aria-haspopup': true }); that._enable(); that._old = that._accessor(); if (element[0].id) { element.attr('aria-owns', that.ul[0].id); } that._aria(); 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 = $.proxy(that._resetFocusItem, that); kendo.notify(that); }, options: { name: 'AutoComplete', enabled: true, suggest: false, template: '', groupTemplate: '#:data#', fixedGroupTemplate: '#:data#', dataTextField: '', minLength: 1, delay: 200, height: 200, filter: 'startswith', ignoreCase: true, highlightFirst: false, separator: null, placeholder: '', animation: {}, virtual: false, value: null }, _dataSource: function () { var that = this; if (that.dataSource && that._refreshHandler) { that._unbindDataSource(); } else { that._progressHandler = proxy(that._showBusy, that); that._errorHandler = proxy(that._hideBusy, that); } 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(); }, _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.addClass(DEFAULT).removeClass(STATEDISABLED).on(HOVEREVENTS, that._toggleHover); element.removeAttr(DISABLED).removeAttr(READONLY).attr(ARIA_DISABLED, false).attr(ARIA_READONLY, false); } else { wrapper.addClass(disable ? STATEDISABLED : DEFAULT).removeClass(disable ? DEFAULT : STATEDISABLED); element.attr(DISABLED, disable).attr(READONLY, readonly).attr(ARIA_DISABLED, disable).attr(ARIA_READONLY, readonly); } }, close: function () { var that = this; var current = that.listView.focus(); if (current) { current.removeClass(SELECTED); } that.popup.close(); }, destroy: function () { var that = this; that.element.off(ns); that.wrapper.off(ns); List.fn.destroy.call(that); }, refresh: function () { this.listView.refresh(); }, select: function (li) { this._select(li); }, search: function (word) { var that = this, options = that.options, ignoreCase = options.ignoreCase, separator = options.separator, length; word = word || that._accessor(); clearTimeout(that._typingTimeout); if (separator) { word = wordAtCaret(caret(that.element)[0], word, separator); } length = word.length; if (!length || length >= options.minLength) { that._open = true; that._mute(function () { this.listView.value([]); }); that._filterSource({ value: ignoreCase ? word.toLowerCase() : word, operator: options.filter, field: options.dataTextField, ignoreCase: ignoreCase }); } }, suggest: function (word) { var that = this, key = that._last, value = that._accessor(), element = that.element[0], caretIdx = caret(element)[0], separator = that.options.separator, words = value.split(separator), wordIndex = indexOfWordAtCaret(caretIdx, value, separator), selectionEnd = caretIdx, idx; if (key == keys.BACKSPACE || key == keys.DELETE) { that._last = undefined; 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 = value.toLowerCase().indexOf(word.toLowerCase()) + 1; } idx = value.substring(0, caretIdx).lastIndexOf(separator); idx = idx > -1 ? caretIdx - (idx + separator.length) : caretIdx; value = words[wordIndex].substring(0, idx); if (word) { word = word.toString(); idx = word.toLowerCase().indexOf(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; that._accessor(words.join(separator || '')); if (element === activeElement()) { caret(element, caretIdx, selectionEnd); } }, value: function (value) { if (value !== undefined) { this.listView.value(value); this._accessor(value); this._old = this._accessor(); this._oldText = this._accessor(); } else { return this._accessor(); } }, _click: function (e) { var item = e.item; var element = this.element; e.preventDefault(); this._active = true; if (this.trigger('select', { item: item })) { this.close(); return; } this._oldText = element.val(); this._select(item); this._blur(); caret(element, element.val().length); }, _resetFocusItem: function () { var index = this.options.highlightFirst ? 0 : -1; if (this.options.virtual) { this.listView.scrollTo(0); } this.listView.focus(index); }, _listBound: function () { var that = this; var popup = that.popup; var options = that.options; var data = that.dataSource.flatView(); var length = data.length; var isActive = that.element[0] === activeElement(); var action; that._angularItems('compile'); that._resizePopup(); popup.position(); if (length) { if (options.suggest && isActive) { that.suggest(data[0]); } } if (that._open) { that._open = false; action = length ? '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; } if (that._touchScroller) { that._touchScroller.reset(); } that._hideBusy(); that._makeUnselectable(); 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.options.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._prev = text; this._accessor(text); this._placeholder(); }, _change: function () { var that = this; var value = that.value(); var trigger = value !== List.unifyType(that._old, typeof value); var valueUpdated = trigger && !that._typing; var itemSelected = that._oldText !== value; if (valueUpdated || itemSelected) { that.element.trigger(CHANGE); } if (trigger) { that._old = value; that.trigger(CHANGE); } that.typing = false; }, _accessor: function (value) { var that = this, element = that.element[0]; if (value !== undefined) { 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 visible = that.popup.visible(); var current = this.listView.focus(); that._last = key; if (key === keys.DOWN) { if (visible) { this._move(current ? 'focusNext' : 'focusFirst'); } e.preventDefault(); } else if (key === keys.UP) { if (visible) { this._move(current ? 'focusPrev' : 'focusLast'); } e.preventDefault(); } else if (key === keys.ENTER || key === keys.TAB) { if (key === keys.ENTER && visible) { e.preventDefault(); } if (visible && current) { if (that.trigger('select', { item: current })) { return; } this._select(current); } this._blur(); } else if (key === keys.ESC) { if (visible) { e.preventDefault(); } that.close(); } else { that._search(); } }, _keypress: function () { this._oldText = this.element.val(); this._typing = true; }, _move: function (action) { this.listView[action](); if (this.options.suggest) { this.suggest(this.listView.focus()); } }, _hideBusy: function () { var that = this; clearTimeout(that._busy); that._loading.hide(); that.element.attr('aria-busy', false); that._busy = null; }, _showBusy: function () { var that = this; if (that._busy) { return; } that._busy = setTimeout(function () { that.element.attr('aria-busy', true); that._loading.show(); }, 100); }, _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) { 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); } } }, _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) { this._active = true; this.listView.select(candidate); this._active = false; }, _loader: function () { this._loading = $('').insertAfter(this.element); }, _toggleHover: function (e) { $(e.currentTarget).toggleClass(HOVER, e.type === 'mouseenter'); }, _wrapper: function () { var that = this, element = that.element, DOMelement = element[0], wrapper; wrapper = element.parent(); if (!wrapper.is('span.k-widget')) { wrapper = element.wrap('').parent(); } wrapper.attr('tabindex', -1); wrapper.attr('role', 'presentation'); wrapper[0].style.cssText = DOMelement.style.cssText; element.css({ width: '100%', height: DOMelement.style.height }); that._focused = that.element; that.wrapper = wrapper.addClass('k-widget k-autocomplete k-header').addClass(DOMelement.className); } }); ui.plugin(AutoComplete); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); }));