Changeset 2114:7f63aa8eeebf
- Timestamp:
- 09/27/13 19:40:37 (11 years ago)
- Branch:
- default
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
admin/js/jquery/jquery.autocomplete.js
r1035 r2114 1 1 /* 2 * jQuery Autocomplete plugin 1. 12 * jQuery Autocomplete plugin 1.2.3 3 3 * 4 4 * Copyright (c) 2009 Jörn Zaefferer … … 8 8 * http://www.gnu.org/licenses/gpl.html 9 9 * 10 * Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $ 10 * With small modifications by Alfonso Gómez-Arzola. 11 * See changelog for details. 12 * 11 13 */ 12 14 13 15 ;(function($) { 14 16 15 17 $.fn.extend({ 16 18 autocomplete: function(urlOrData, options) { … … 20 22 data: isUrl ? null : urlOrData, 21 23 delay: isUrl ? $.Autocompleter.defaults.delay : 10, 22 max: options && !options.scroll ? 10 : 150 24 max: options && !options.scroll ? 10 : 150, 25 noRecord: "No Records." 23 26 }, options); 24 27 25 28 // if highlight is set to false, replace it with a do-nothing function 26 29 options.highlight = options.highlight || function(value) { return value; }; 27 30 28 31 // if the formatMatch option is not specified, then use formatItem for backwards compatibility 29 32 options.formatMatch = options.formatMatch || options.formatItem; 30 33 31 34 return this.each(function() { 32 35 new $.Autocompleter(this, options); … … 65 68 }; 66 69 70 var globalFailure = null; 71 if(options.failure != null && typeof options.failure == "function") { 72 globalFailure = options.failure; 73 } 74 67 75 // Create $ object for input element 68 76 var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass); … … 77 85 }; 78 86 var select = $.Autocompleter.Select(options, input, selectCurrent, config); 79 87 80 88 var blockSubmit; 81 89 82 90 // prevent form submit in opera when selecting with return key 83 $.browser.opera&& $(input.form).bind("submit.autocomplete", function() {91 navigator.userAgent.indexOf("Opera") != -1 && $(input.form).bind("submit.autocomplete", function() { 84 92 if (blockSubmit) { 85 93 blockSubmit = false; … … 87 95 } 88 96 }); 89 90 // o nly opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all91 $input.bind(( $.browser.opera? "keypress" : "keydown") + ".autocomplete", function(event) {97 98 // older versions of opera don't trigger keydown multiple times while pressed, others don't work with keypress at all 99 $input.bind((navigator.userAgent.indexOf("Opera") != -1 && !'KeyboardEvent' in window ? "keypress" : "keydown") + ".autocomplete", function(event) { 92 100 // a keypress means the input has focus 93 101 // avoids issue where input had focus before the autocomplete was applied … … 96 104 lastKeyPressCode = event.keyCode; 97 105 switch(event.keyCode) { 98 106 99 107 case KEY.UP: 100 event.preventDefault();101 108 if ( select.visible() ) { 109 event.preventDefault(); 102 110 select.prev(); 103 111 } else { … … 105 113 } 106 114 break; 107 115 108 116 case KEY.DOWN: 109 event.preventDefault();110 117 if ( select.visible() ) { 118 event.preventDefault(); 111 119 select.next(); 112 120 } else { … … 114 122 } 115 123 break; 116 124 117 125 case KEY.PAGEUP: 118 event.preventDefault();119 126 if ( select.visible() ) { 127 event.preventDefault(); 120 128 select.pageUp(); 121 129 } else { … … 123 131 } 124 132 break; 125 133 126 134 case KEY.PAGEDOWN: 127 event.preventDefault();128 135 if ( select.visible() ) { 136 event.preventDefault(); 129 137 select.pageDown(); 130 138 } else { … … 132 140 } 133 141 break; 134 142 135 143 // matches also semicolon 136 144 case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA: … … 144 152 } 145 153 break; 146 154 147 155 case KEY.ESC: 148 156 select.hide(); 149 157 break; 150 158 151 159 default: 152 160 clearTimeout(timeout); … … 159 167 hasFocus++; 160 168 }).blur(function() { 161 169 hasFocus = 0; 162 170 if (!config.mouseDownOnSelect) { 163 171 hideResults(); … … 165 173 }).click(function() { 166 174 // show select when clicking in a focused field 167 if ( hasFocus++ > 1 && !select.visible() ) { 168 onChange(0, true); 175 // but if clickFire is true, don't require field 176 // to be focused to begin with; just show select 177 if( options.clickFire ) { 178 if ( !select.visible() ) { 179 onChange(0, true); 180 } 181 } else { 182 if ( hasFocus++ > 1 && !select.visible() ) { 183 onChange(0, true); 184 } 169 185 } 170 186 }).bind("search", function() { … … 190 206 cache.flush(); 191 207 }).bind("setOptions", function() { 192 $.extend( options, arguments[1]);208 $.extend(true, options, arguments[1]); 193 209 // if we've updated the data, repopulate 194 210 if ( "data" in arguments[1] ) … … 199 215 $(input.form).unbind(".autocomplete"); 200 216 }); 201 202 217 218 203 219 function selectCurrent() { 204 220 var selected = select.selected(); 205 221 if( !selected ) 206 222 return false; 207 223 208 224 var v = selected.result; 209 225 previousValue = v; 210 226 211 227 if ( options.multiple ) { 212 228 var words = trimWords($input.val()); … … 230 246 v += options.multipleSeparator; 231 247 } 232 248 233 249 $input.val(v); 234 250 hideResultsNow(); … … 236 252 return true; 237 253 } 238 254 239 255 function onChange(crap, skipPrevCheck) { 240 256 if( lastKeyPressCode == KEY.DEL ) { … … 242 258 return; 243 259 } 244 260 245 261 var currentValue = $input.val(); 246 262 247 263 if ( !skipPrevCheck && currentValue == previousValue ) 248 264 return; 249 265 250 266 previousValue = currentValue; 251 267 252 268 currentValue = lastWord(currentValue); 253 269 if ( currentValue.length >= options.minChars) { … … 261 277 } 262 278 }; 263 279 264 280 function trimWords(value) { 265 281 if (!value) … … 271 287 }); 272 288 } 273 289 274 290 function lastWord(value) { 275 291 if ( !options.multiple ) 276 292 return value; 277 293 var words = trimWords(value); 278 if (words.length == 1) 294 if (words.length == 1) 279 295 return words[0]; 280 296 var cursorAt = $(input).selection().start; … … 286 302 return words[words.length - 1]; 287 303 } 288 304 289 305 // fills in the input box w/the first match (assumed to be the best match) 290 306 // q: the term entered … … 347 363 var data = cache.load(term); 348 364 // recieve the cached data 349 if (data && data.length) { 350 success(term, data); 365 if (data) { 366 if(data.length) { 367 success(term, data); 368 } 369 else{ 370 var parsed = options.parse && options.parse(options.noRecord) || parse(options.noRecord); 371 success(term,parsed); 372 } 351 373 // if an AJAX url has been supplied, try loading the data now 352 374 } else if( (typeof options.url == "string") && (options.url.length > 0) ){ 353 375 354 376 var extraParams = { 355 377 timestamp: +new Date() … … 358 380 extraParams[key] = typeof param == "function" ? param() : param; 359 381 }); 360 382 361 383 $.ajax({ 362 384 // try to leverage ajaxQueue plugin to abort previous requests … … 379 401 // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match 380 402 select.emptyList(); 381 failure(term); 382 } 383 }; 384 403 if(globalFailure != null) { 404 globalFailure(); 405 } 406 else { 407 failure(term); 408 } 409 } 410 }; 411 385 412 function parse(data) { 386 413 var parsed = []; … … 415 442 matchSubset: true, 416 443 matchContains: false, 417 cacheLength: 10 ,418 max: 100 ,444 cacheLength: 100, 445 max: 1000, 419 446 mustMatch: false, 420 447 extraParams: {}, … … 425 452 width: 0, 426 453 multiple: false, 427 multipleSeparator: ", ", 454 multipleSeparator: " ", 455 inputFocus: true, 456 clickFire: false, 428 457 highlight: function(value, term) { 429 458 return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>"); 430 459 }, 431 460 scroll: true, 432 scrollHeight: 180 461 scrollHeight: 180, 462 scrollJumpPosition: true 433 463 }; 434 464 … … 437 467 var data = {}; 438 468 var length = 0; 439 469 440 470 function matchSubset(s, sub) { 441 if (!options.matchCase) 471 if (!options.matchCase) 442 472 s = s.toLowerCase(); 443 473 var i = s.indexOf(sub); … … 448 478 return i == 0 || options.matchContains; 449 479 }; 450 480 451 481 function add(q, value) { 452 482 if (length > options.cacheLength){ 453 483 flush(); 454 484 } 455 if (!data[q]){ 485 if (!data[q]){ 456 486 length++; 457 487 } 458 488 data[q] = value; 459 489 } 460 490 461 491 function populate(){ 462 492 if( !options.data ) return false; … … 467 497 // no url was specified, we need to adjust the cache length to make sure it fits the local data store 468 498 if( !options.url ) options.cacheLength = 1; 469 499 470 500 // track all options for minChars = 0 471 501 stMatchSets[""] = []; 472 502 473 503 // loop through the array and create a lookup structure 474 504 for ( var i = 0, ol = options.data.length; i < ol; i++ ) { … … 476 506 // if rawValue is a string, make an array otherwise just reference the array 477 507 rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue; 478 508 479 509 var value = options.formatMatch(rawValue, i+1, options.data.length); 480 if ( value === false )510 if ( typeof(value) === 'undefined' || value === false ) 481 511 continue; 482 512 483 513 var firstChar = value.charAt(0).toLowerCase(); 484 514 // if no lookup array for this character exists, look it up now 485 if( !stMatchSets[firstChar] ) 515 if( !stMatchSets[firstChar] ) 486 516 stMatchSets[firstChar] = []; 487 517 … … 492 522 result: options.formatResult && options.formatResult(rawValue) || value 493 523 }; 494 524 495 525 // push the current match into the set list 496 526 stMatchSets[firstChar].push(row); … … 510 540 }); 511 541 } 512 542 513 543 // populate any existing data 514 544 setTimeout(populate, 25); 515 545 516 546 function flush(){ 517 547 data = {}; 518 548 length = 0; 519 549 } 520 550 521 551 return { 522 552 flush: flush, … … 526 556 if (!options.cacheLength || !length) 527 557 return null; 528 /* 558 /* 529 559 * if dealing w/local data and matchContains than we must make sure 530 560 * to loop through all the data collections looking for matches … … 546 576 }); 547 577 } 548 } 578 } 549 579 return csub; 550 } else 580 } else 551 581 // if the exact item exists, use it 552 582 if (data[q]){ … … 576 606 ACTIVE: "ac_over" 577 607 }; 578 608 579 609 var listItems, 580 610 active = -1, … … 584 614 element, 585 615 list; 586 616 587 617 // Create results 588 618 function init() { … … 593 623 .addClass(options.resultsClass) 594 624 .css("position", "absolute") 595 .appendTo(document.body); 596 625 .appendTo(document.body) 626 .hover(function(event) { 627 // Browsers except FF do not fire mouseup event on scrollbars, resulting in mouseDownOnSelect remaining true, and results list not always hiding. 628 if($(this).is(":visible")) { 629 input.focus(); 630 } 631 config.mouseDownOnSelect = false; 632 }); 633 597 634 list = $("<ul/>").appendTo(element).mouseover( function(event) { 598 635 if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') { 599 636 active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event)); 600 $(target(event)).addClass(CLASSES.ACTIVE); 637 $(target(event)).addClass(CLASSES.ACTIVE); 601 638 } 602 639 }).click(function(event) { 603 640 $(target(event)).addClass(CLASSES.ACTIVE); 604 641 select(); 605 // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus606 input.focus();642 if( options.inputFocus ) 643 input.focus(); 607 644 return false; 608 645 }).mousedown(function() { … … 611 648 config.mouseDownOnSelect = false; 612 649 }); 613 650 614 651 if( options.width > 0 ) 615 652 element.css("width", options.width); 616 653 617 654 needsInit = false; 618 } 619 655 } 656 620 657 function target(event) { 621 658 var element = event.target; … … 644 681 } 645 682 }; 646 683 647 684 function movePosition(step) { 648 active += step; 649 if (active < 0) { 650 active = listItems.size() - 1; 651 } else if (active >= listItems.size()) { 652 active = 0; 653 } 654 } 655 685 if (options.scrollJumpPosition || (!options.scrollJumpPosition && !((step < 0 && active == 0) || (step > 0 && active == listItems.size() - 1)) )) { 686 active += step; 687 if (active < 0) { 688 active = listItems.size() - 1; 689 } else if (active >= listItems.size()) { 690 active = 0; 691 } 692 } 693 } 694 695 656 696 function limitNumberOfItems(available) { 657 697 return options.max && options.max < available … … 659 699 : available; 660 700 } 661 701 662 702 function fillList() { 663 703 list.empty(); … … 681 721 list.bgiframe(); 682 722 } 683 723 684 724 return { 685 725 display: function(d, q) { … … 733 773 overflow: 'auto' 734 774 }); 735 736 if( $.browser.msie&& typeof document.body.style.maxHeight === "undefined") {775 776 if(navigator.userAgent.indexOf("MSIE") != -1 && typeof document.body.style.maxHeight === "undefined") { 737 777 var listHeight = 0; 738 778 listItems.each(function() { … … 746 786 } 747 787 } 748 788 749 789 } 750 790 }, -
plugins/tags/js/jquery.autocomplete.js
r738 r2114 1 1 /* 2 * jQuery Autocomplete plugin 1. 12 * jQuery Autocomplete plugin 1.2.3 3 3 * 4 4 * Copyright (c) 2009 Jörn Zaefferer … … 8 8 * http://www.gnu.org/licenses/gpl.html 9 9 * 10 * Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $ 10 * With small modifications by Alfonso Gómez-Arzola. 11 * See changelog for details. 12 * 11 13 */ 12 14 13 15 ;(function($) { 14 16 15 17 $.fn.extend({ 16 18 autocomplete: function(urlOrData, options) { … … 20 22 data: isUrl ? null : urlOrData, 21 23 delay: isUrl ? $.Autocompleter.defaults.delay : 10, 22 max: options && !options.scroll ? 10 : 150 24 max: options && !options.scroll ? 10 : 150, 25 noRecord: "No Records." 23 26 }, options); 24 27 25 28 // if highlight is set to false, replace it with a do-nothing function 26 29 options.highlight = options.highlight || function(value) { return value; }; 27 30 28 31 // if the formatMatch option is not specified, then use formatItem for backwards compatibility 29 32 options.formatMatch = options.formatMatch || options.formatItem; 30 33 31 34 return this.each(function() { 32 35 new $.Autocompleter(this, options); … … 65 68 }; 66 69 70 var globalFailure = null; 71 if(options.failure != null && typeof options.failure == "function") { 72 globalFailure = options.failure; 73 } 74 67 75 // Create $ object for input element 68 76 var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass); … … 77 85 }; 78 86 var select = $.Autocompleter.Select(options, input, selectCurrent, config); 79 87 80 88 var blockSubmit; 81 89 82 90 // prevent form submit in opera when selecting with return key 83 $.browser.opera&& $(input.form).bind("submit.autocomplete", function() {91 navigator.userAgent.indexOf("Opera") != -1 && $(input.form).bind("submit.autocomplete", function() { 84 92 if (blockSubmit) { 85 93 blockSubmit = false; … … 87 95 } 88 96 }); 89 90 // o nly opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all91 $input.bind(( $.browser.opera? "keypress" : "keydown") + ".autocomplete", function(event) {97 98 // older versions of opera don't trigger keydown multiple times while pressed, others don't work with keypress at all 99 $input.bind((navigator.userAgent.indexOf("Opera") != -1 && !'KeyboardEvent' in window ? "keypress" : "keydown") + ".autocomplete", function(event) { 92 100 // a keypress means the input has focus 93 101 // avoids issue where input had focus before the autocomplete was applied … … 96 104 lastKeyPressCode = event.keyCode; 97 105 switch(event.keyCode) { 98 106 99 107 case KEY.UP: 100 event.preventDefault();101 108 if ( select.visible() ) { 109 event.preventDefault(); 102 110 select.prev(); 103 111 } else { … … 105 113 } 106 114 break; 107 115 108 116 case KEY.DOWN: 109 event.preventDefault();110 117 if ( select.visible() ) { 118 event.preventDefault(); 111 119 select.next(); 112 120 } else { … … 114 122 } 115 123 break; 116 124 117 125 case KEY.PAGEUP: 118 event.preventDefault();119 126 if ( select.visible() ) { 127 event.preventDefault(); 120 128 select.pageUp(); 121 129 } else { … … 123 131 } 124 132 break; 125 133 126 134 case KEY.PAGEDOWN: 127 event.preventDefault();128 135 if ( select.visible() ) { 136 event.preventDefault(); 129 137 select.pageDown(); 130 138 } else { … … 132 140 } 133 141 break; 134 142 135 143 // matches also semicolon 136 144 case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA: … … 144 152 } 145 153 break; 146 154 147 155 case KEY.ESC: 148 156 select.hide(); 149 157 break; 150 158 151 159 default: 152 160 clearTimeout(timeout); … … 159 167 hasFocus++; 160 168 }).blur(function() { 161 169 hasFocus = 0; 162 170 if (!config.mouseDownOnSelect) { 163 171 hideResults(); … … 165 173 }).click(function() { 166 174 // show select when clicking in a focused field 167 if ( hasFocus++ > 1 && !select.visible() ) { 168 onChange(0, true); 175 // but if clickFire is true, don't require field 176 // to be focused to begin with; just show select 177 if( options.clickFire ) { 178 if ( !select.visible() ) { 179 onChange(0, true); 180 } 181 } else { 182 if ( hasFocus++ > 1 && !select.visible() ) { 183 onChange(0, true); 184 } 169 185 } 170 186 }).bind("search", function() { … … 190 206 cache.flush(); 191 207 }).bind("setOptions", function() { 192 $.extend( options, arguments[1]);208 $.extend(true, options, arguments[1]); 193 209 // if we've updated the data, repopulate 194 210 if ( "data" in arguments[1] ) … … 199 215 $(input.form).unbind(".autocomplete"); 200 216 }); 201 202 217 218 203 219 function selectCurrent() { 204 220 var selected = select.selected(); 205 221 if( !selected ) 206 222 return false; 207 223 208 224 var v = selected.result; 209 225 previousValue = v; 210 226 211 227 if ( options.multiple ) { 212 228 var words = trimWords($input.val()); … … 230 246 v += options.multipleSeparator; 231 247 } 232 248 233 249 $input.val(v); 234 250 hideResultsNow(); … … 236 252 return true; 237 253 } 238 254 239 255 function onChange(crap, skipPrevCheck) { 240 256 if( lastKeyPressCode == KEY.DEL ) { … … 242 258 return; 243 259 } 244 260 245 261 var currentValue = $input.val(); 246 262 247 263 if ( !skipPrevCheck && currentValue == previousValue ) 248 264 return; 249 265 250 266 previousValue = currentValue; 251 267 252 268 currentValue = lastWord(currentValue); 253 269 if ( currentValue.length >= options.minChars) { … … 261 277 } 262 278 }; 263 279 264 280 function trimWords(value) { 265 281 if (!value) … … 271 287 }); 272 288 } 273 289 274 290 function lastWord(value) { 275 291 if ( !options.multiple ) 276 292 return value; 277 293 var words = trimWords(value); 278 if (words.length == 1) 294 if (words.length == 1) 279 295 return words[0]; 280 296 var cursorAt = $(input).selection().start; … … 286 302 return words[words.length - 1]; 287 303 } 288 304 289 305 // fills in the input box w/the first match (assumed to be the best match) 290 306 // q: the term entered … … 347 363 var data = cache.load(term); 348 364 // recieve the cached data 349 if (data && data.length) { 350 success(term, data); 365 if (data) { 366 if(data.length) { 367 success(term, data); 368 } 369 else{ 370 var parsed = options.parse && options.parse(options.noRecord) || parse(options.noRecord); 371 success(term,parsed); 372 } 351 373 // if an AJAX url has been supplied, try loading the data now 352 374 } else if( (typeof options.url == "string") && (options.url.length > 0) ){ 353 375 354 376 var extraParams = { 355 377 timestamp: +new Date() … … 358 380 extraParams[key] = typeof param == "function" ? param() : param; 359 381 }); 360 382 361 383 $.ajax({ 362 384 // try to leverage ajaxQueue plugin to abort previous requests … … 379 401 // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match 380 402 select.emptyList(); 381 failure(term); 382 } 383 }; 384 403 if(globalFailure != null) { 404 globalFailure(); 405 } 406 else { 407 failure(term); 408 } 409 } 410 }; 411 385 412 function parse(data) { 386 413 var parsed = []; … … 415 442 matchSubset: true, 416 443 matchContains: false, 417 cacheLength: 10 ,418 max: 100 ,444 cacheLength: 100, 445 max: 1000, 419 446 mustMatch: false, 420 447 extraParams: {}, … … 425 452 width: 0, 426 453 multiple: false, 427 multipleSeparator: ", ", 454 multipleSeparator: " ", 455 inputFocus: true, 456 clickFire: false, 428 457 highlight: function(value, term) { 429 458 return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>"); 430 459 }, 431 460 scroll: true, 432 scrollHeight: 180 461 scrollHeight: 180, 462 scrollJumpPosition: true 433 463 }; 434 464 … … 437 467 var data = {}; 438 468 var length = 0; 439 469 440 470 function matchSubset(s, sub) { 441 if (!options.matchCase) 471 if (!options.matchCase) 442 472 s = s.toLowerCase(); 443 473 var i = s.indexOf(sub); … … 448 478 return i == 0 || options.matchContains; 449 479 }; 450 480 451 481 function add(q, value) { 452 482 if (length > options.cacheLength){ 453 483 flush(); 454 484 } 455 if (!data[q]){ 485 if (!data[q]){ 456 486 length++; 457 487 } 458 488 data[q] = value; 459 489 } 460 490 461 491 function populate(){ 462 492 if( !options.data ) return false; … … 467 497 // no url was specified, we need to adjust the cache length to make sure it fits the local data store 468 498 if( !options.url ) options.cacheLength = 1; 469 499 470 500 // track all options for minChars = 0 471 501 stMatchSets[""] = []; 472 502 473 503 // loop through the array and create a lookup structure 474 504 for ( var i = 0, ol = options.data.length; i < ol; i++ ) { … … 476 506 // if rawValue is a string, make an array otherwise just reference the array 477 507 rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue; 478 508 479 509 var value = options.formatMatch(rawValue, i+1, options.data.length); 480 if ( value === false )510 if ( typeof(value) === 'undefined' || value === false ) 481 511 continue; 482 512 483 513 var firstChar = value.charAt(0).toLowerCase(); 484 514 // if no lookup array for this character exists, look it up now 485 if( !stMatchSets[firstChar] ) 515 if( !stMatchSets[firstChar] ) 486 516 stMatchSets[firstChar] = []; 487 517 … … 492 522 result: options.formatResult && options.formatResult(rawValue) || value 493 523 }; 494 524 495 525 // push the current match into the set list 496 526 stMatchSets[firstChar].push(row); … … 510 540 }); 511 541 } 512 542 513 543 // populate any existing data 514 544 setTimeout(populate, 25); 515 545 516 546 function flush(){ 517 547 data = {}; 518 548 length = 0; 519 549 } 520 550 521 551 return { 522 552 flush: flush, … … 526 556 if (!options.cacheLength || !length) 527 557 return null; 528 /* 558 /* 529 559 * if dealing w/local data and matchContains than we must make sure 530 560 * to loop through all the data collections looking for matches … … 546 576 }); 547 577 } 548 } 578 } 549 579 return csub; 550 } else 580 } else 551 581 // if the exact item exists, use it 552 582 if (data[q]){ … … 576 606 ACTIVE: "ac_over" 577 607 }; 578 608 579 609 var listItems, 580 610 active = -1, … … 584 614 element, 585 615 list; 586 616 587 617 // Create results 588 618 function init() { … … 593 623 .addClass(options.resultsClass) 594 624 .css("position", "absolute") 595 .appendTo(document.body); 596 625 .appendTo(document.body) 626 .hover(function(event) { 627 // Browsers except FF do not fire mouseup event on scrollbars, resulting in mouseDownOnSelect remaining true, and results list not always hiding. 628 if($(this).is(":visible")) { 629 input.focus(); 630 } 631 config.mouseDownOnSelect = false; 632 }); 633 597 634 list = $("<ul/>").appendTo(element).mouseover( function(event) { 598 635 if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') { 599 636 active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event)); 600 $(target(event)).addClass(CLASSES.ACTIVE); 637 $(target(event)).addClass(CLASSES.ACTIVE); 601 638 } 602 639 }).click(function(event) { 603 640 $(target(event)).addClass(CLASSES.ACTIVE); 604 641 select(); 605 // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus606 input.focus();642 if( options.inputFocus ) 643 input.focus(); 607 644 return false; 608 645 }).mousedown(function() { … … 611 648 config.mouseDownOnSelect = false; 612 649 }); 613 650 614 651 if( options.width > 0 ) 615 652 element.css("width", options.width); 616 653 617 654 needsInit = false; 618 } 619 655 } 656 620 657 function target(event) { 621 658 var element = event.target; … … 644 681 } 645 682 }; 646 683 647 684 function movePosition(step) { 648 active += step; 649 if (active < 0) { 650 active = listItems.size() - 1; 651 } else if (active >= listItems.size()) { 652 active = 0; 653 } 654 } 655 685 if (options.scrollJumpPosition || (!options.scrollJumpPosition && !((step < 0 && active == 0) || (step > 0 && active == listItems.size() - 1)) )) { 686 active += step; 687 if (active < 0) { 688 active = listItems.size() - 1; 689 } else if (active >= listItems.size()) { 690 active = 0; 691 } 692 } 693 } 694 695 656 696 function limitNumberOfItems(available) { 657 697 return options.max && options.max < available … … 659 699 : available; 660 700 } 661 701 662 702 function fillList() { 663 703 list.empty(); … … 681 721 list.bgiframe(); 682 722 } 683 723 684 724 return { 685 725 display: function(d, q) { … … 733 773 overflow: 'auto' 734 774 }); 735 736 if( $.browser.msie&& typeof document.body.style.maxHeight === "undefined") {775 776 if(navigator.userAgent.indexOf("MSIE") != -1 && typeof document.body.style.maxHeight === "undefined") { 737 777 var listHeight = 0; 738 778 listItems.each(function() { … … 746 786 } 747 787 } 748 788 749 789 } 750 790 },
Note: See TracChangeset
for help on using the changeset viewer.