JAVASCRIPT   79
jquery qqsuggest
Guest on 8th March 2023 12:28:51 AM


  1. /*
  2.  *      jquery.suggest 1.1b
  3.  * Patched by Mark Jaquith with Alexander Dick's "multiple items" patch to allow for auto-suggesting of more than one tag before submitting
  4.  * See: http://www.vulgarisoip.com/2007/06/29/jquerysuggest-an-alternative-jquery-based-autocomplete-library/#comment-7228
  5.  *
  6.  *      Uses code and techniques from following libraries:
  7.  *      1. http://www.dyve.net/jquery/?autocomplete
  8.  *      2. http://dev.jquery.com/browser/trunk/plugins/interface/iautocompleter.js
  9.  *
  10.  *      All the new stuff written by Peter Vulgaris (www.vulgarisoip.com)
  11.  *      Feel free to do whatever you want with this file
  12.  *
  13.  */
  14.  
  15. (function($) {
  16.  
  17.         $.suggest = function(input, options) {
  18.                 var $input, $results, timeout, prevLength, cache, cacheSize;
  19.  
  20.                 $input = $(input).attr("autocomplete", "off");
  21.                 $results = $("<ul/>");
  22.  
  23.                 timeout = false;                // hold timeout ID for suggestion results to appear
  24.                 prevLength = 0;                 // last recorded length of $input.val()
  25.                 cache = [];                             // cache MRU list
  26.                 cacheSize = 0;                  // size of cache in chars (bytes?)
  27.  
  28.                 $results.addClass(options.resultsClass).appendTo('body');
  29.  
  30.  
  31.                 resetPosition();
  32.                 $(window)
  33.                         .on( 'load', resetPosition ) // just in case user is changing size of page while loading
  34.                         .on( 'resize', resetPosition );
  35.  
  36.                 $input.blur(function() {
  37.                         setTimeout(function() { $results.hide() }, 200);
  38.                 });
  39.  
  40.                 $input.keydown(processKey);
  41.  
  42.                 function resetPosition() {
  43.                         // requires jquery.dimension plugin
  44.                         var offset = $input.offset();
  45.                         $results.css({
  46.                                 top: (offset.top + input.offsetHeight) + 'px',
  47.                                 left: offset.left + 'px'
  48.                         });
  49.                 }
  50.  
  51.  
  52.                 function processKey(e) {
  53.  
  54.                         // handling up/down/escape requires results to be visible
  55.                         // handling enter/tab requires that AND a result to be selected
  56.                         if ((/27$|38$|40$/.test(e.keyCode) && $results.is(':visible')) ||
  57.                                 (/^13$|^9$/.test(e.keyCode) && getCurrentResult())) {
  58.  
  59.                                 if (e.preventDefault)
  60.                                         e.preventDefault();
  61.                                 if (e.stopPropagation)
  62.                                         e.stopPropagation();
  63.  
  64.                                 e.cancelBubble = true;
  65.                                 e.returnValue = false;
  66.  
  67.                                 switch(e.keyCode) {
  68.  
  69.                                         case 38: // up
  70.                                                 prevResult();
  71.                                                 break;
  72.  
  73.                                         case 40: // down
  74.                                                 nextResult();
  75.                                                 break;
  76.  
  77.                                         case 9:  // tab
  78.                                         case 13: // return
  79.                                                 selectCurrentResult();
  80.                                                 break;
  81.  
  82.                                         case 27: //     escape
  83.                                                 $results.hide();
  84.                                                 break;
  85.  
  86.                                 }
  87.  
  88.                         } else if ($input.val().length != prevLength) {
  89.  
  90.                                 if (timeout)
  91.                                         clearTimeout(timeout);
  92.                                 timeout = setTimeout(suggest, options.delay);
  93.                                 prevLength = $input.val().length;
  94.  
  95.                         }
  96.  
  97.  
  98.                 }
  99.  
  100.  
  101.                 function suggest() {
  102.  
  103.                         var q = $.trim($input.val()), multipleSepPos, items;
  104.  
  105.                         if ( options.multiple ) {
  106.                                 multipleSepPos = q.lastIndexOf(options.multipleSep);
  107.                                 if ( multipleSepPos != -1 ) {
  108.                                         q = $.trim(q.substr(multipleSepPos + options.multipleSep.length));
  109.                                 }
  110.                         }
  111.                         if (q.length >= options.minchars) {
  112.  
  113.                                 cached = checkCache(q);
  114.  
  115.                                 if (cached) {
  116.  
  117.                                         displayItems(cached['items']);
  118.  
  119.                                 } else {
  120.  
  121.                                         $.get(options.source, {q: q}, function(txt) {
  122.  
  123.                                                 $results.hide();
  124.  
  125.                                                 items = parseTxt(txt, q);
  126.  
  127.                                                 displayItems(items);
  128.                                                 addToCache(q, items, txt.length);
  129.  
  130.                                         });
  131.  
  132.                                 }
  133.  
  134.                         } else {
  135.  
  136.                                 $results.hide();
  137.  
  138.                         }
  139.  
  140.                 }
  141.  
  142.  
  143.                 function checkCache(q) {
  144.                         var i;
  145.                         for (i = 0; i < cache.length; i++)
  146.                                 if (cache[i]['q'] == q) {
  147.                                         cache.unshift(cache.splice(i, 1)[0]);
  148.                                         return cache[0];
  149.                                 }
  150.  
  151.                         return false;
  152.  
  153.                 }
  154.  
  155.                 function addToCache(q, items, size) {
  156.                         var cached;
  157.                         while (cache.length && (cacheSize + size > options.maxCacheSize)) {
  158.                                 cached = cache.pop();
  159.                                 cacheSize -= cached['size'];
  160.                         }
  161.  
  162.                         cache.push({
  163.                                 q: q,
  164.                                 size: size,
  165.                                 items: items
  166.                                 });
  167.  
  168.                         cacheSize += size;
  169.  
  170.                 }
  171.  
  172.                 function displayItems(items) {
  173.                         var html = '', i;
  174.                         if (!items)
  175.                                 return;
  176.  
  177.                         if (!items.length) {
  178.                                 $results.hide();
  179.                                 return;
  180.                         }
  181.  
  182.                         resetPosition(); // when the form moves after the page has loaded
  183.  
  184.                         for (i = 0; i < items.length; i++)
  185.                                 html += '<li>' + items[i] + '</li>';
  186.  
  187.                         $results.html(html).show();
  188.  
  189.                         $results
  190.                                 .children('li')
  191.                                 .mouseover(function() {
  192.                                         $results.children('li').removeClass(options.selectClass);
  193.                                         $(this).addClass(options.selectClass);
  194.                                 })
  195.                                 .click(function(e) {
  196.                                         e.preventDefault();
  197.                                         e.stopPropagation();
  198.                                         selectCurrentResult();
  199.                                 });
  200.  
  201.                 }
  202.  
  203.                 function parseTxt(txt, q) {
  204.  
  205.                         var items = [], tokens = txt.split(options.delimiter), i, token;
  206.  
  207.                         // parse returned data for non-empty items
  208.                         for (i = 0; i < tokens.length; i++) {
  209.                                 token = $.trim(tokens[i]);
  210.                                 if (token) {
  211.                                         token = token.replace(
  212.                                                 new RegExp(q, 'ig'),
  213.                                                 function(q) { return '<span class="' + options.matchClass + '">' + q + '</span>' }
  214.                                                 );
  215.                                         items[items.length] = token;
  216.                                 }
  217.                         }
  218.  
  219.                         return items;
  220.                 }
  221.  
  222.                 function getCurrentResult() {
  223.                         var $currentResult;
  224.                         if (!$results.is(':visible'))
  225.                                 return false;
  226.  
  227.                         $currentResult = $results.children('li.' + options.selectClass);
  228.  
  229.                         if (!$currentResult.length)
  230.                                 $currentResult = false;
  231.  
  232.                         return $currentResult;
  233.  
  234.                 }
  235.  
  236.                 function selectCurrentResult() {
  237.  
  238.                         $currentResult = getCurrentResult();
  239.  
  240.                         if ($currentResult) {
  241.                                 if ( options.multiple ) {
  242.                                         if ( $input.val().indexOf(options.multipleSep) != -1 ) {
  243.                                                 $currentVal = $input.val().substr( 0, ( $input.val().lastIndexOf(options.multipleSep) + options.multipleSep.length ) ) + ' ';
  244.                                         } else {
  245.                                                 $currentVal = "";
  246.                                         }
  247.                                         $input.val( $currentVal + $currentResult.text() + options.multipleSep + ' ' );
  248.                                         $input.focus();
  249.                                 } else {
  250.                                         $input.val($currentResult.text());
  251.                                 }
  252.                                 $results.hide();
  253.                                 $input.trigger('change');
  254.  
  255.                                 if (options.onSelect)
  256.                                         options.onSelect.apply($input[0]);
  257.  
  258.                         }
  259.  
  260.                 }
  261.  
  262.                 function nextResult() {
  263.  
  264.                         $currentResult = getCurrentResult();
  265.  
  266.                         if ($currentResult)
  267.                                 $currentResult
  268.                                         .removeClass(options.selectClass)
  269.                                         .next()
  270.                                                 .addClass(options.selectClass);
  271.                         else
  272.                                 $results.children('li:first-child').addClass(options.selectClass);
  273.  
  274.                 }
  275.  
  276.                 function prevResult() {
  277.                         var $currentResult = getCurrentResult();
  278.  
  279.                         if ($currentResult)
  280.                                 $currentResult
  281.                                         .removeClass(options.selectClass)
  282.                                         .prev()
  283.                                                 .addClass(options.selectClass);
  284.                         else
  285.                                 $results.children('li:last-child').addClass(options.selectClass);
  286.  
  287.                 }
  288.         }
  289.  
  290.         $.fn.suggest = function(source, options) {
  291.  
  292.                 if (!source)
  293.                         return;
  294.  
  295.                 options = options || {};
  296.                 options.multiple = options.multiple || false;
  297.                 options.multipleSep = options.multipleSep || ",";
  298.                 options.source = source;
  299.                 options.delay = options.delay || 100;
  300.                 options.resultsClass = options.resultsClass || 'ac_results';
  301.                 options.selectClass = options.selectClass || 'ac_over';
  302.                 options.matchClass = options.matchClass || 'ac_match';
  303.                 options.minchars = options.minchars || 2;
  304.                 options.delimiter = options.delimiter || '\n';
  305.                 options.onSelect = options.onSelect || false;
  306.                 options.maxCacheSize = options.maxCacheSize || 65536;
  307.  
  308.                 this.each(function() {
  309.                         new $.suggest(this, options);
  310.                 });
  311.  
  312.                 return this;
  313.  
  314.         };
  315.  
  316. })(jQuery);

Raw Paste

Login or Register to edit or fork this paste. It's free.