/* * jQuery Plugin: Tokenizing Autocomplete Text Entry * Version 1.6.0 * * Copyright (c) 2009 James Smith (http://loopj.com) * Licensed jointly under the GPL and MIT licenses, * choose which one suits your project best! * */ (function ($) { // Default settings var DEFAULT_SETTINGS = { // Search settings method: "GET", contentType: "json", queryParam: "q", duplicatesParam: "d", searchDelay: 300, minChars: 1, propertyToSearch: "name", jsonContainer: null, searchAlgorithm: 'global', // Display settings hintText: "Type in a search term", noResultsText: "No results", searchingText: "Searching...", addNewIcon: "/images/backend/beta/icons/22x22/add.png", addNewText: "dodaj", createNew: false, deleteText: "×", animateDropdown: true, // Tokenization settings tokenLimit: null, tokenDelimiter: ",", propertyNew: "new", preventDuplicates: false, // Output settings tokenValue: "id", // Prepopulation settings prePopulate: null, processPrePopulate: false, additionalDataFields: [], // Manipulation settings idPrefix: "token-input-", // Formatters newResultsFormatter: function (item) { return "
" + item[this.propertyToSearch] + "
" + item[this.propertyToSearch] + "
" + settings.searchingText + "
"); show_dropdown(); } } function show_dropdown_hint() { if (settings.hintText) { dropdown.html("" + settings.hintText + "
"); show_dropdown(); } } // Highlight the query part of the search term function highlight_term(value, term) { if (term) { term = term.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); } if (settings.searchAlgorithm == 'global') { return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1"); } else if (settings.searchAlgorithm == 'first') { return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(^" + term + ")(?![^<>]*>)(?![^&;]+;)", "i"), "$1"); } } function find_value_and_highlight_term(template, value, term) { var regex_value = value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); return template.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + regex_value + ")(?![^<>]*>)(?![^&;]+;)", "g"), highlight_term(value, term)); } // Populate the results dropdown with some results function populate_dropdown(query, results) { var new_item = true; if (settings.createNew && query && !settings.savedTokens[query.toLowerCase()]) { $.each(results, function (index, value) { if (value[settings.propertyToSearch].toLowerCase() == query.toLowerCase()) { new_item = false; } }); if (new_item) { var item = {}; item[settings.propertyNew] = true; item[settings.propertyToSearch] = query; results = [item].concat(results); } } if (results && results.length) { dropdown.empty(); var dropdown_ul = $("" + 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(settings.classes.selectedDropdownItem); selected_dropdown_item = item.get(0); var token_data = item.data("tokeninput"); if (token_data && (token_data[settings.tokenValue] != undefined || token_data[settings.propertyNew] != undefined)) { input_box.val(token_data[settings.propertyToSearch]); } } } // Remove highlighting from an item in the results dropdown function deselect_dropdown_item(item) { item.removeClass(settings.classes.selectedDropdownItem); selected_dropdown_item = null; } // Do a search and show the "searching" dropdown if the input is longer // than settings.minChars function do_search() { var query = input_box.val().trim(); if (query && query.length) { if (selected_token) { deselect_token($(selected_token), POSITION.AFTER); } if (query.length >= settings.minChars) { if (settings.url) { show_dropdown_searching(); clearTimeout(timeout); timeout = setTimeout(function () { run_search(query); }, settings.searchDelay); } else { run_search(query); } } else { hide_dropdown(); } } } // Do the actual search function run_search(query) { var cache_key = query ? query.toLowerCase() + computeURL() : computeURL(); var cached_results = cache.get(cache_key); if (cached_results) { populate_dropdown(query, cached_results); } else { // Are we doing an ajax search or local data search? if (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[settings.queryParam] = query; if (settings.preventDuplicates && hidden_input.val()) { var tokens = $.parseJSON(hidden_input.val()); var duplicates = []; $.each(tokens, function () { duplicates.push(this[settings.tokenValue]); }); ajax_params.data[settings.duplicatesParam] = duplicates.join(); } ajax_params.type = settings.method; ajax_params.dataType = settings.contentType; if (settings.crossDomain) { ajax_params.dataType = "jsonp"; } // Attach the success callback ajax_params.success = function (results) { if (settings.jsonContainer) { results = results[settings.jsonContainer]; } if ($.isFunction(settings.onResult)) { results = settings.onResult.call(hidden_input, results); } cache.add(cache_key, results); // only populate the dropdown if the results are associated with the active search query if (input_box.val().toLowerCase() === query.toLowerCase()) { populate_dropdown(query, results); } }; // Make the request $.ajax(ajax_params); } else if (settings.local_data) { // Do the search through local data var results = $.grep(settings.local_data, function (row) { let tokenCacheIndex = typeof row[settings.tokenValue] === 'string' ? row[settings.tokenValue].toLowerCase() : row[settings.tokenValue]; if (settings.savedTokens[tokenCacheIndex]) { return false; } if (query === null) { return true; } var value = row[settings.propertyToSearch].toLowerCase(); if (settings.searchAlgorithm == 'global') { return value.indexOf(query.toLowerCase()) > -1; } else if (settings.searchAlgorithm == 'first') { return value.indexOf(query.toLowerCase()) == 0; } }); if ($.isFunction(settings.onResult)) { results = settings.onResult.call(hidden_input, results); } cache.add(cache_key, results); populate_dropdown(query, results); } } } // compute the dynamic URL function computeURL() { var url = settings.url; if (typeof settings.url == 'function') { url = settings.url.call(); } return url; } }; // Really basic cache for the results $.TokenList.Cache = function (options) { var settings = $.extend({ max_size: 500 }, options); var data = {}; var size = 0; this.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));