/* * jQuery Plugin: Tokenizing Autocomplete Text Entry * Version 1.6.1 * * Copyright (c) 2009 James Smith (http://loopj.com) * Licensed jointly under the GPL and MIT licenses, * choose which one suits your project best! * * https://github.com/mistic100/jquery-tokeninput */ (function ($) { // Default settings var DEFAULT_SETTINGS = { // Search settings method: "GET", queryParam: "q", searchDelay: 300, minChars: 1, propertyToSearch: "name", jsonContainer: null, contentType: "json", // Prepopulation settings prePopulate: null, processPrePopulate: false, // Display settings hintText: "Type in a search term", noResultsText: "No results", searchingText: "Searching...", deleteText: "×", newText: " (new)", animateDropdown: true, placeholder: null, theme: null, zindex: 999, resultsLimit: null, enableHTML: false, resultsFormatter: function(item) { var string = item[this.propertyToSearch]; return "
" + (this.enableHTML ? string : _escapeHTML(string)) + "
" + escapeHTML($(input).data("settings").searchingText) + "
"); show_dropdown(); } } function show_dropdown_hint () { if($(input).data("settings").hintText) { dropdown.html("" + escapeHTML($(input).data("settings").hintText) + "
"); show_dropdown(); } } var regexp_special_chars = new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\-]', 'g'); function regexp_escape(term) { return term.replace(regexp_special_chars, '\\$&'); } // Highlight the query part of the search term function highlight_term(value, term) { return value.replace( new RegExp( "(?![^&;]+;)(?!<[^<>]*)(" + regexp_escape(term) + ")(?![^<>]*>)(?![^&;]+;)", "gi" ), function(match, p1) { return "" + escapeHTML(p1) + ""; } ); } function find_value_and_highlight_term(template, value, term) { return template.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + regexp_escape(value) + ")(?![^<>]*>)(?![^&;]+;)", "g"), highlight_term(value, term)); } // Populate the results dropdown with some results function populate_dropdown (query, results) { if(results && results.length) { dropdown.empty(); var dropdown_ul = $("" + escapeHTML($(input).data("settings").noResultsText) + "
"); show_dropdown(); } } } // Highlight an item in the results dropdown function select_dropdown_item (item) { if(item) { if(selected_dropdown_item) { deselect_dropdown_item($(selected_dropdown_item)); } item.addClass($(input).data("settings").classes.selectedDropdownItem); selected_dropdown_item = item.get(0); } } // Remove highlighting from an item in the results dropdown function deselect_dropdown_item (item) { item.removeClass($(input).data("settings").classes.selectedDropdownItem); selected_dropdown_item = null; } // Do a search and show the "searching" dropdown if the input is longer // than $(input).data("settings").minChars function do_search() { var query = input_box.val(); if(query && query.length) { if(selected_token) { deselect_token($(selected_token), POSITION.AFTER); } if(query.length >= $(input).data("settings").minChars) { show_dropdown_searching(); clearTimeout(timeout); timeout = setTimeout(function(){ run_search(query); }, $(input).data("settings").searchDelay); } else { hide_dropdown(); } } } // Do the actual search function run_search(query) { var cache_key = query + computeURL(); var cached_results = cache.get(cache_key); if(cached_results) { if ($.isFunction($(input).data("settings").onCachedResult)) { cached_results = $(input).data("settings").onCachedResult.call(hidden_input, cached_results); } populate_dropdown(query, cached_results); } else { // Are we doing an ajax search or local data search? if($(input).data("settings").url) { var url = computeURL(); // Extract exisiting get params var ajax_params = {}; ajax_params.data = {}; if(url.indexOf("?") > -1) { var parts = url.split("?"); ajax_params.url = parts[0]; var param_array = parts[1].split("&"); $.each(param_array, function (index, value) { var kv = value.split("="); ajax_params.data[kv[0]] = kv[1]; }); } else { ajax_params.url = url; } // Prepare the request ajax_params.data[$(input).data("settings").queryParam] = query; ajax_params.type = $(input).data("settings").method; ajax_params.dataType = $(input).data("settings").contentType; if($(input).data("settings").crossDomain) { ajax_params.dataType = "jsonp"; } // Attach the success callback ajax_params.success = function(results) { cache.add(cache_key, $(input).data("settings").jsonContainer ? results[$(input).data("settings").jsonContainer] : results); if($.isFunction($(input).data("settings").onResult)) { results = $(input).data("settings").onResult.call(hidden_input, results); } if($(input).data("settings").allowFreeTagging && $(input).data("settings").freeTaggingHint) { results.push({name: input_box.val() + $(input).data("settings").newText, id: input_box.val()}); } // only populate the dropdown if the results are associated with the active search query if(input_box.val() === query) { populate_dropdown(query, $(input).data("settings").jsonContainer ? results[$(input).data("settings").jsonContainer] : results); } }; // Make the request $.ajax(ajax_params); } else if($(input).data("settings").local_data) { // Do the search through local data var results = $.grep($(input).data("settings").local_data, function (row) { return row[$(input).data("settings").propertyToSearch].toLowerCase().indexOf(query.toLowerCase()) > -1; }); if($(input).data("settings").allowFreeTagging && $(input).data("settings").freeTaggingHint) { results.push({name: input_box.val() + $(input).data("settings").newText, id: input_box.val()}); } cache.add(cache_key, results); if($.isFunction($(input).data("settings").onResult)) { results = $(input).data("settings").onResult.call(hidden_input, results); } populate_dropdown(query, results); } } } // compute the dynamic URL function computeURL() { var url = $(input).data("settings").url; if(typeof $(input).data("settings").url == 'function') { url = $(input).data("settings").url.call($(input).data("settings")); } return url; } // Bring browser focus to the specified object. // Use of setTimeout is to get around an IE bug. // (See, e.g., http://stackoverflow.com/questions/2600186/focus-doesnt-work-in-ie) // // obj: a jQuery object to focus() function focus_with_timeout(obj) { setTimeout(function() { obj.focus(); }, 50); } }; // Really basic cache for the results $.TokenList.Cache = function (options) { var settings = $.extend({ max_size: 500 }, options); var data = {}; var size = 0; var flush = function () { data = {}; size = 0; }; this.add = function (query, results) { if(size > settings.max_size) { flush(); } if(!data[query]) { size += 1; } data[query] = results; }; this.get = function (query) { return data[query]; }; }; }(jQuery));