/*globals define*/ /*jslint nomen:true*/ /** * @class jQuery.ui.uiSmartsearch * @author Copyright 2006-2013, epages GmbH, All Rights Reserved * * The ui smartsearch widget can be used to extend an input field's * functionality with suggestions retrieved from an internal or external * data source. * * ### Example * HTML: * * <input class="FullSize ep-ui-smartsearch ep-js" data-js=".uiInput()" value="" name="TagNamesString" /> * * JavaScript: * * $('.ep-ui-smartsearch').uiSmartsearch({ * 'source': ['Suggestion1', 'Suggestion2', 'Suggestion3', 'Suggestion4'], * 'multiple' : true * }); * * @uses jQuery * @uses ep * @uses jQuery.tmpl * @uses jQuery.ui.widget * @uses jQuery.ui.autocomplete * @uses ep.ajax * * @chainable * @return {Object} ep */ define("ep/ui/smartsearch", [ "jquery", "ep", "jquery/tmpl", "jquery/ui/widget", "jquery/ui/autocomplete", "ep/ajax" ], function ($, ep) { 'use strict'; var groupedSource = {}; $.widget('ui.uiSmartsearch', { /** * Options to be passed to the widgt on initialzation * * @cfg {Object} options * @cfg {Array | String} options.source Source to look for suggestions (when string we use * it as view action) * @cfg {Object} [options.additionalParameters={}] An hash map of additional * parameters appended to the request. The keys are taken as * parameter names while the values are used as parameter values. * @cfg {String} [options.group=undefined] Identifier for a group of widgets that use * the same data source * @cfg {Boolean} [options.multiple=false] Allow one or multiple entries * @cfg {Number} [options.minLength=1] The minimum number of characters a user must * type before a search is performed */ options: { 'source': [], 'group': undefined, 'multiple': false, 'minLength': 1 }, /** * Creates widget instance and sets grouped data source * * @since 6.17.0 * @private */ _create: function () { var self = this, o = self.options; if (o.group && groupedSource && !groupedSource[o.group]) { groupedSource[o.group] = o.source; } }, /** * Initializes widget and adds configured autocomple widget to the element on that it's * called. * * @since 6.17.0 * @private */ _init: function () { var self = this, o = self.options; self.element.autocomplete({ minLength: o.minLength, source: function (request, response) { var term = '', returnValue = []; if (o.multiple) { term = request.term.split(/,\s*/).pop(); } else { term = request.term; } if (o.source instanceof Array) { returnValue = $.ui.autocomplete.filter(o.source, term); response(returnValue); } else if (typeof o.source === 'string') { ep.ajax({ dataType: 'json', data: $.extend({ 'ObjectID': ep.config.siteId, 'ViewAction': o.source, 'SearchString': request.term }, o.searchOptions) }).done(function (data) { response($.map(data.Results, function (item) { return { label: item.alias, value: item.alias, desc: item.name }; })); }); } }, focus: function () { return false; }, select: function (event, ui) { if (o.multiple) { var terms = this.value.split(/,\s*/); terms.pop(); terms.push(ui.item.value); terms.push(""); this.value = terms.join(", "); } else { this.value = ui.item.value; } return false; } }).data("ui-autocomplete")._renderItem = function (ul, item) { var returnNode = $("<li>"); if (item.desc) { returnNode.append("<a>" + item.value + " - " + ep.scrunch(item.desc, 25) + "</a>"); } else { returnNode.append("<a>" + item.value + "</a>"); } returnNode.appendTo(ul); return returnNode; }; self.element.on("keydown", function (event) { if (event.keyCode === $.ui.keyCode.TAB && $(this).data("ui-autocomplete").menu.active) { event.preventDefault(); } }); //if a group is defined we need to provide all aditional added tags to all group members if (o.group) { self.element.on("change", function (event) { self._checkTags($(this).val().split(','), groupedSource[o.group]); }); } }, /** * Checks if tag is already present in data source * * @since 6.17.0 * @private * * @param {Array} newTags Tags to add to the data source * @param {Array} source Data source */ _checkTags: function (newTags, source) { $.each(newTags, function (i, elem) { if ($.inArray(elem, source) === -1) { source.push(elem); } }); }, /** * Destroys the autocomplete widget * * @since 6.17.0 */ destroy: function () { this.element.autocomplete('destroy'); this._superApply(arguments); } }); return ep; });