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