1/*** 2@title: 3Live Search 4 5@version: 62.0 7 8@author: 9Andreas Lagerkvist 10 11@date: 122008-08-31 13 14@url: 15http://andreaslagerkvist.com/jquery/live-search/ 16 17@license: 18http://creativecommons.org/licenses/by/3.0/ 19 20@copyright: 212008 Andreas Lagerkvist (andreaslagerkvist.com) 22 23@requires: 24jquery, jquery.liveSearch.css 25 26@does: 27Use this plug-in to turn a normal form-input in to a live ajax search widget. The plug-in displays any HTML you like in the results and the search-results are updated live as the user types. 28 29@howto: 30jQuery('#q').liveSearch({url: '/ajax/search.php?q='}); would add the live-search container next to the input#q element and fill it with the contents of /ajax/search.php?q=THE-INPUTS-VALUE onkeyup of the input. 31 32@exampleHTML: 33<form method="post" action="/search/"> 34 35 <p> 36 <label> 37 Enter search terms<br /> 38 <input type="text" name="q" /> 39 </label> <input type="submit" value="Go" /> 40 </p> 41 42</form> 43 44@exampleJS: 45jQuery('#jquery-live-search-example input[name="q"]').liveSearch({url: Router.urlForModule('SearchResults') + '&q='}); 46***/ 47jQuery.fn.liveSearch = function (conf) { 48 var config = jQuery.extend({ 49 url: '/search-results.php?q=', 50 id: 'jquery-live-search', 51 duration: 400, 52 typeDelay: 200, 53 loadingClass: 'live-search-loading', 54 onSlideUp: function () {}, 55 uptadePosition: false 56 }, conf); 57 58 var liveSearch = jQuery('#' + config.id); 59 60 // Create live-search if it doesn't exist 61 if (!liveSearch.length) { 62 liveSearch = jQuery('<div id="' + config.id + '"></div>') 63 .appendTo(document.body) 64 .hide() 65 .slideUp(0); 66 67 // Close live-search when clicking outside it 68 jQuery(document.body).click(function(event) { 69 var clicked = jQuery(event.target); 70 71 if (!(clicked.is('#' + config.id) || clicked.parents('#' + config.id).length || clicked.is('input'))) { 72 liveSearch.slideUp(config.duration, function () { 73 config.onSlideUp(); 74 }); 75 } 76 }); 77 } 78 79 return this.each(function () { 80 var input = jQuery(this).attr('autocomplete', 'off'); 81 var liveSearchPaddingBorderHoriz = parseInt(liveSearch.css('paddingLeft'), 10) + parseInt(liveSearch.css('paddingRight'), 10) + parseInt(liveSearch.css('borderLeftWidth'), 10) + parseInt(liveSearch.css('borderRightWidth'), 10); 82 83 // Re calculates live search's position 84 var repositionLiveSearch = function () { 85 var tmpOffset = input.offset(); 86 var inputDim = { 87 left: tmpOffset.left, 88 top: tmpOffset.top, 89 width: input.outerWidth(), 90 height: input.outerHeight() 91 }; 92 93 inputDim.topPos = inputDim.top + inputDim.height; 94 inputDim.totalWidth = inputDim.width - liveSearchPaddingBorderHoriz; 95 96 liveSearch.css({ 97 position: 'absolute', 98 left: inputDim.left + 'px', 99 top: inputDim.topPos + 'px', 100 width: inputDim.totalWidth + 'px' 101 }); 102 }; 103 104 // Shows live-search for this input 105 var showLiveSearch = function () { 106 // Always reposition the live-search every time it is shown 107 // in case user has resized browser-window or zoomed in or whatever 108 repositionLiveSearch(); 109 110 // We need to bind a resize-event every time live search is shown 111 // so it resizes based on the correct input element 112 jQuery(window).unbind('resize', repositionLiveSearch); 113 jQuery(window).bind('resize', repositionLiveSearch); 114 115 liveSearch.slideDown(config.duration); 116 }; 117 118 // Hides live-search for this input 119 var hideLiveSearch = function () { 120 liveSearch.slideUp(config.duration, function () { 121 config.onSlideUp(); 122 }); 123 }; 124 125 input 126 // On focus, if the live-search is empty, perform an new search 127 // If not, just slide it down. Only do this if there's something in the input 128 .focus(function () { 129 if (this.value !== '') { 130 // Perform a new search if there are no search results 131 if (liveSearch.html() == '') { 132 this.lastValue = '';
133 input.keyup(); 134 } 135 // If there are search results show live search 136 else { 137 // HACK: In case search field changes width onfocus 138 setTimeout(showLiveSearch, 1); 139 } 140 } 141 }) 142 // Auto update live-search onkeyup 143 .keyup(function () { 144 // Don't update live-search if it's got the same value as last time 145 if (this.value != this.lastValue) { 146 input.addClass(config.loadingClass); 147 148 var q = this.value; 149 150 // Stop previous ajax-request 151 if (this.timer) { 152 clearTimeout(this.timer); 153 } 154 155 // Start a new ajax-request in X ms 156 this.timer = setTimeout(function () { 157 jQuery.get(config.url + q, function (data) { 158 input.removeClass(config.loadingClass); 159 160 // Show live-search if results and search-term aren't empty 161 if (data.length && q.length) { 162 liveSearch.html(data); 163 showLiveSearch(); 164 } 165 else { 166 hideLiveSearch(); 167 } 168 }); 169 }, config.typeDelay); 170 171 this.lastValue = this.value; 172 } 173 }); 174 }); 175};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.