JAVASCRIPT 26
Suggest.js Guest on 20th April 2021 04:58:57 PM
  1. /*
  2.  *    jquery.suggest 1.1b - 2007-08-06
  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);

Paste-bin is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

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