home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Blogs / wordpress2.6.exe / wordpress2.6 / wp-includes / js / jquery / suggest.js < prev    next >
Encoding:
JavaScript  |  2008-06-30  |  7.2 KB  |  332 lines

  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.  
  19.         var $input = $(input).attr("autocomplete", "off");
  20.         var $results = $(document.createElement("ul"));
  21.  
  22.         var timeout = false;        // hold timeout ID for suggestion results to appear    
  23.         var prevLength = 0;            // last recorded length of $input.val()
  24.         var cache = [];                // cache MRU list
  25.         var cacheSize = 0;            // size of cache in chars (bytes?)
  26.         
  27.         $results.addClass(options.resultsClass).appendTo('body');
  28.             
  29.  
  30.         resetPosition();
  31.         $(window)
  32.             .load(resetPosition)        // just in case user is changing size of page while loading
  33.             .resize(resetPosition);
  34.  
  35.         $input.blur(function() {
  36.             setTimeout(function() { $results.hide() }, 200);
  37.         });
  38.         
  39.         
  40.         // help IE users if possible
  41.         try {
  42.             $results.bgiframe();
  43.         } catch(e) { }
  44.  
  45.  
  46.         // I really hate browser detection, but I don't see any other way
  47.         if ($.browser.mozilla)
  48.             $input.keypress(processKey);    // onkeypress repeats arrow keys in Mozilla/Opera
  49.         else
  50.             $input.keydown(processKey);        // onkeydown repeats arrow keys in IE/Safari
  51.         
  52.  
  53.  
  54.  
  55.         function resetPosition() {
  56.             // requires jquery.dimension plugin
  57.             var offset = $input.offset();
  58.             $results.css({
  59.                 top: (offset.top + input.offsetHeight) + 'px',
  60.                 left: offset.left + 'px'
  61.             });
  62.         }
  63.         
  64.         
  65.         function processKey(e) {
  66.             
  67.             // handling up/down/escape requires results to be visible
  68.             // handling enter/tab requires that AND a result to be selected
  69.             if ((/27$|38$|40$/.test(e.keyCode) && $results.is(':visible')) ||
  70.                 (/^13$|^9$/.test(e.keyCode) && getCurrentResult())) {
  71.                 
  72.                 if (e.preventDefault)
  73.                     e.preventDefault();
  74.                 if (e.stopPropagation)
  75.                     e.stopPropagation();
  76.  
  77.                 e.cancelBubble = true;
  78.                 e.returnValue = false;
  79.             
  80.                 switch(e.keyCode) {
  81.  
  82.                     case 38: // up
  83.                         prevResult();
  84.                         break;
  85.             
  86.                     case 40: // down
  87.                         nextResult();
  88.                         break;
  89.  
  90.                     case 9:  // tab
  91.                     case 13: // return
  92.                         selectCurrentResult();
  93.                         break;
  94.                         
  95.                     case 27: //    escape
  96.                         $results.hide();
  97.                         break;
  98.  
  99.                 }
  100.                 
  101.             } else if ($input.val().length != prevLength) {
  102.  
  103.                 if (timeout) 
  104.                     clearTimeout(timeout);
  105.                 timeout = setTimeout(suggest, options.delay);
  106.                 prevLength = $input.val().length;
  107.                 
  108.             }            
  109.                 
  110.             
  111.         }
  112.         
  113.         
  114.         function suggest() {
  115.         
  116.             var q = $.trim($input.val());
  117.  
  118.             if ( options.multiple ) {
  119.                 var multipleSepPos = q.lastIndexOf(options.multipleSep);
  120.                 if ( multipleSepPos != -1 ) {
  121.                     q = q.substr(multipleSepPos + options.multipleSep.length);
  122.                 }
  123.             }
  124.             if (q.length >= options.minchars) {
  125.                 
  126.                 cached = checkCache(q);
  127.                 
  128.                 if (cached) {
  129.                 
  130.                     displayItems(cached['items']);
  131.                     
  132.                 } else {
  133.                 
  134.                     $.get(options.source, {q: q}, function(txt) {
  135.  
  136.                         $results.hide();
  137.                         
  138.                         var items = parseTxt(txt, q);
  139.                         
  140.                         displayItems(items);
  141.                         addToCache(q, items, txt.length);
  142.                         
  143.                     });
  144.                     
  145.                 }
  146.                 
  147.             } else {
  148.             
  149.                 $results.hide();
  150.                 
  151.             }
  152.                 
  153.         }
  154.         
  155.         
  156.         function checkCache(q) {
  157.  
  158.             for (var i = 0; i < cache.length; i++)
  159.                 if (cache[i]['q'] == q) {
  160.                     cache.unshift(cache.splice(i, 1)[0]);
  161.                     return cache[0];
  162.                 }
  163.             
  164.             return false;
  165.         
  166.         }
  167.         
  168.         function addToCache(q, items, size) {
  169.  
  170.             while (cache.length && (cacheSize + size > options.maxCacheSize)) {
  171.                 var cached = cache.pop();
  172.                 cacheSize -= cached['size'];
  173.             }
  174.             
  175.             cache.push({
  176.                 q: q,
  177.                 size: size,
  178.                 items: items
  179.                 });
  180.                 
  181.             cacheSize += size;
  182.         
  183.         }
  184.         
  185.         function displayItems(items) {
  186.             
  187.             if (!items)
  188.                 return;
  189.                 
  190.             if (!items.length) {
  191.                 $results.hide();
  192.                 return;
  193.             }
  194.  
  195.             resetPosition(); // when the form moves after the page has loaded
  196.  
  197.             var html = '';
  198.             for (var i = 0; i < items.length; i++)
  199.                 html += '<li>' + items[i] + '</li>';
  200.  
  201.             $results.html(html).show();
  202.             
  203.             $results
  204.                 .children('li')
  205.                 .mouseover(function() {
  206.                     $results.children('li').removeClass(options.selectClass);
  207.                     $(this).addClass(options.selectClass);
  208.                 })
  209.                 .click(function(e) {
  210.                     e.preventDefault(); 
  211.                     e.stopPropagation();
  212.                     selectCurrentResult();
  213.                 });
  214.                         
  215.         }
  216.         
  217.         function parseTxt(txt, q) {
  218.             
  219.             var items = [];
  220.             var tokens = txt.split(options.delimiter);
  221.             
  222.             // parse returned data for non-empty items
  223.             for (var i = 0; i < tokens.length; i++) {
  224.                 var token = $.trim(tokens[i]);
  225.                 if (token) {
  226.                     token = token.replace(
  227.                         new RegExp(q, 'ig'), 
  228.                         function(q) { return '<span class="' + options.matchClass + '">' + q + '</span>' }
  229.                         );
  230.                     items[items.length] = token;
  231.                 }
  232.             }
  233.             
  234.             return items;
  235.         }
  236.         
  237.         function getCurrentResult() {
  238.         
  239.             if (!$results.is(':visible'))
  240.                 return false;
  241.         
  242.             var $currentResult = $results.children('li.' + options.selectClass);
  243.             
  244.             if (!$currentResult.length)
  245.                 $currentResult = false;
  246.                 
  247.             return $currentResult;
  248.  
  249.         }
  250.         
  251.         function selectCurrentResult() {
  252.         
  253.             $currentResult = getCurrentResult();
  254.         
  255.             if ($currentResult) {
  256.                 if ( options.multiple ) {
  257.                     if ( $input.val().indexOf(options.multipleSep) != -1 ) {
  258.                         $currentVal = $input.val().substr( 0, ( $input.val().lastIndexOf(options.multipleSep) + options.multipleSep.length ) );
  259.                     } else {
  260.                         $currentVal = "";
  261.                     }
  262.                     $input.val( $currentVal + $currentResult.text() + options.multipleSep);
  263.                     $input.focus();
  264.                 } else {
  265.                     $input.val($currentResult.text());
  266.                 }
  267.                 $results.hide();
  268.                 
  269.                 if (options.onSelect)
  270.                     options.onSelect.apply($input[0]);
  271.                     
  272.             }
  273.         
  274.         }
  275.         
  276.         function nextResult() {
  277.         
  278.             $currentResult = getCurrentResult();
  279.         
  280.             if ($currentResult)
  281.                 $currentResult
  282.                     .removeClass(options.selectClass)
  283.                     .next()
  284.                         .addClass(options.selectClass);
  285.             else
  286.                 $results.children('li:first-child').addClass(options.selectClass);
  287.         
  288.         }
  289.         
  290.         function prevResult() {
  291.         
  292.             $currentResult = getCurrentResult();
  293.         
  294.             if ($currentResult)
  295.                 $currentResult
  296.                     .removeClass(options.selectClass)
  297.                     .prev()
  298.                         .addClass(options.selectClass);
  299.             else
  300.                 $results.children('li:last-child').addClass(options.selectClass);
  301.         
  302.         }
  303.  
  304.     }
  305.     
  306.     $.fn.suggest = function(source, options) {
  307.     
  308.         if (!source)
  309.             return;
  310.     
  311.         options = options || {};
  312.         options.multiple = options.multiple || false;
  313.         options.multipleSep = options.multipleSep || ", ";
  314.         options.source = source;
  315.         options.delay = options.delay || 100;
  316.         options.resultsClass = options.resultsClass || 'ac_results';
  317.         options.selectClass = options.selectClass || 'ac_over';
  318.         options.matchClass = options.matchClass || 'ac_match';
  319.         options.minchars = options.minchars || 2;
  320.         options.delimiter = options.delimiter || '\n';
  321.         options.onSelect = options.onSelect || false;
  322.         options.maxCacheSize = options.maxCacheSize || 65536;
  323.  
  324.         this.each(function() {
  325.             new $.suggest(this, options);
  326.         });
  327.  
  328.         return this;
  329.         
  330.     };
  331.     
  332. })(jQuery);