| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 // $Id: autocomplete.js,v 1.23 2008/01/04 11:53:21 goba Exp $ 2 3 /** 4 * Attaches the autocomplete behavior to all required fields 5 */ 6 Drupal.behaviors.autocomplete = function (context) { 7 var acdb = []; 8 $('input.autocomplete:not(.autocomplete-processed)', context).each(function () { 9 var uri = this.value; 10 if (!acdb[uri]) { 11 acdb[uri] = new Drupal.ACDB(uri); 12 } 13 var input = $('#' + this.id.substr(0, this.id.length - 13)) 14 .attr('autocomplete', 'OFF')[0]; 15 $(input.form).submit(Drupal.autocompleteSubmit); 16 new Drupal.jsAC(input, acdb[uri]); 17 $(this).addClass('autocomplete-processed'); 18 }); 19 }; 20 21 /** 22 * Prevents the form from submitting if the suggestions popup is open 23 * and closes the suggestions popup when doing so. 24 */ 25 Drupal.autocompleteSubmit = function () { 26 return $('#autocomplete').each(function () { 27 this.owner.hidePopup(); 28 }).size() == 0; 29 }; 30 31 /** 32 * An AutoComplete object 33 */ 34 Drupal.jsAC = function (input, db) { 35 var ac = this; 36 this.input = input; 37 this.db = db; 38 39 $(this.input) 40 .keydown(function (event) { return ac.onkeydown(this, event); }) 41 .keyup(function (event) { ac.onkeyup(this, event); }) 42 .blur(function () { ac.hidePopup(); ac.db.cancel(); }); 43 44 }; 45 46 /** 47 * Handler for the "keydown" event 48 */ 49 Drupal.jsAC.prototype.onkeydown = function (input, e) { 50 if (!e) { 51 e = window.event; 52 } 53 switch (e.keyCode) { 54 case 40: // down arrow 55 this.selectDown(); 56 return false; 57 case 38: // up arrow 58 this.selectUp(); 59 return false; 60 default: // all other keys 61 return true; 62 } 63 }; 64 65 /** 66 * Handler for the "keyup" event 67 */ 68 Drupal.jsAC.prototype.onkeyup = function (input, e) { 69 if (!e) { 70 e = window.event; 71 } 72 switch (e.keyCode) { 73 case 16: // shift 74 case 17: // ctrl 75 case 18: // alt 76 case 20: // caps lock 77 case 33: // page up 78 case 34: // page down 79 case 35: // end 80 case 36: // home 81 case 37: // left arrow 82 case 38: // up arrow 83 case 39: // right arrow 84 case 40: // down arrow 85 return true; 86 87 case 9: // tab 88 case 13: // enter 89 case 27: // esc 90 this.hidePopup(e.keyCode); 91 return true; 92 93 default: // all other keys 94 if (input.value.length > 0) 95 this.populatePopup(); 96 else 97 this.hidePopup(e.keyCode); 98 return true; 99 } 100 }; 101 102 /** 103 * Puts the currently highlighted suggestion into the autocomplete field 104 */ 105 Drupal.jsAC.prototype.select = function (node) { 106 this.input.value = node.autocompleteValue; 107 }; 108 109 /** 110 * Highlights the next suggestion 111 */ 112 Drupal.jsAC.prototype.selectDown = function () { 113 if (this.selected && this.selected.nextSibling) { 114 this.highlight(this.selected.nextSibling); 115 } 116 else { 117 var lis = $('li', this.popup); 118 if (lis.size() > 0) { 119 this.highlight(lis.get(0)); 120 } 121 } 122 }; 123 124 /** 125 * Highlights the previous suggestion 126 */ 127 Drupal.jsAC.prototype.selectUp = function () { 128 if (this.selected && this.selected.previousSibling) { 129 this.highlight(this.selected.previousSibling); 130 } 131 }; 132 133 /** 134 * Highlights a suggestion 135 */ 136 Drupal.jsAC.prototype.highlight = function (node) { 137 if (this.selected) { 138 $(this.selected).removeClass('selected'); 139 } 140 $(node).addClass('selected'); 141 this.selected = node; 142 }; 143 144 /** 145 * Unhighlights a suggestion 146 */ 147 Drupal.jsAC.prototype.unhighlight = function (node) { 148 $(node).removeClass('selected'); 149 this.selected = false; 150 }; 151 152 /** 153 * Hides the autocomplete suggestions 154 */ 155 Drupal.jsAC.prototype.hidePopup = function (keycode) { 156 // Select item if the right key or mousebutton was pressed 157 if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) { 158 this.input.value = this.selected.autocompleteValue; 159 } 160 // Hide popup 161 var popup = this.popup; 162 if (popup) { 163 this.popup = null; 164 $(popup).fadeOut('fast', function() { $(popup).remove(); }); 165 } 166 this.selected = false; 167 }; 168 169 /** 170 * Positions the suggestions popup and starts a search 171 */ 172 Drupal.jsAC.prototype.populatePopup = function () { 173 // Show popup 174 if (this.popup) { 175 $(this.popup).remove(); 176 } 177 this.selected = false; 178 this.popup = document.createElement('div'); 179 this.popup.id = 'autocomplete'; 180 this.popup.owner = this; 181 $(this.popup).css({ 182 marginTop: this.input.offsetHeight +'px', 183 width: (this.input.offsetWidth - 4) +'px', 184 display: 'none' 185 }); 186 $(this.input).before(this.popup); 187 188 // Do search 189 this.db.owner = this; 190 this.db.search(this.input.value); 191 }; 192 193 /** 194 * Fills the suggestion popup with any matches received 195 */ 196 Drupal.jsAC.prototype.found = function (matches) { 197 // If no value in the textfield, do not show the popup. 198 if (!this.input.value.length) { 199 return false; 200 } 201 202 // Prepare matches 203 var ul = document.createElement('ul'); 204 var ac = this; 205 for (key in matches) { 206 var li = document.createElement('li'); 207 $(li) 208 .html('<div>'+ matches[key] +'</div>') 209 .mousedown(function () { ac.select(this); }) 210 .mouseover(function () { ac.highlight(this); }) 211 .mouseout(function () { ac.unhighlight(this); }); 212 li.autocompleteValue = key; 213 $(ul).append(li); 214 } 215 216 // Show popup with matches, if any 217 if (this.popup) { 218 if (ul.childNodes.length > 0) { 219 $(this.popup).empty().append(ul).show(); 220 } 221 else { 222 $(this.popup).css({visibility: 'hidden'}); 223 this.hidePopup(); 224 } 225 } 226 }; 227 228 Drupal.jsAC.prototype.setStatus = function (status) { 229 switch (status) { 230 case 'begin': 231 $(this.input).addClass('throbbing'); 232 break; 233 case 'cancel': 234 case 'error': 235 case 'found': 236 $(this.input).removeClass('throbbing'); 237 break; 238 } 239 }; 240 241 /** 242 * An AutoComplete DataBase object 243 */ 244 Drupal.ACDB = function (uri) { 245 this.uri = uri; 246 this.delay = 300; 247 this.cache = {}; 248 }; 249 250 /** 251 * Performs a cached and delayed search 252 */ 253 Drupal.ACDB.prototype.search = function (searchString) { 254 var db = this; 255 this.searchString = searchString; 256 257 // See if this key has been searched for before 258 if (this.cache[searchString]) { 259 return this.owner.found(this.cache[searchString]); 260 } 261 262 // Initiate delayed search 263 if (this.timer) { 264 clearTimeout(this.timer); 265 } 266 this.timer = setTimeout(function() { 267 db.owner.setStatus('begin'); 268 269 // Ajax GET request for autocompletion 270 $.ajax({ 271 type: "GET", 272 url: db.uri +'/'+ Drupal.encodeURIComponent(searchString), 273 dataType: 'json', 274 success: function (matches) { 275 if (typeof matches['status'] == 'undefined' || matches['status'] != 0) { 276 db.cache[searchString] = matches; 277 // Verify if these are still the matches the user wants to see 278 if (db.searchString == searchString) { 279 db.owner.found(matches); 280 } 281 db.owner.setStatus('found'); 282 } 283 }, 284 error: function (xmlhttp) { 285 alert(Drupal.ahahError(xmlhttp, db.uri)); 286 } 287 }); 288 }, this.delay); 289 }; 290 291 /** 292 * Cancels the current autocomplete request 293 */ 294 Drupal.ACDB.prototype.cancel = function() { 295 if (this.owner) this.owner.setStatus('cancel'); 296 if (this.timer) clearTimeout(this.timer); 297 this.searchString = ''; 298 };
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |