webmaster@1: // $Id: autocomplete.js,v 1.23 2008/01/04 11:53:21 goba Exp $ webmaster@1: webmaster@1: /** webmaster@1: * Attaches the autocomplete behavior to all required fields webmaster@1: */ webmaster@1: Drupal.behaviors.autocomplete = function (context) { webmaster@1: var acdb = []; webmaster@1: $('input.autocomplete:not(.autocomplete-processed)', context).each(function () { webmaster@1: var uri = this.value; webmaster@1: if (!acdb[uri]) { webmaster@1: acdb[uri] = new Drupal.ACDB(uri); webmaster@1: } webmaster@1: var input = $('#' + this.id.substr(0, this.id.length - 13)) webmaster@1: .attr('autocomplete', 'OFF')[0]; webmaster@1: $(input.form).submit(Drupal.autocompleteSubmit); webmaster@1: new Drupal.jsAC(input, acdb[uri]); webmaster@1: $(this).addClass('autocomplete-processed'); webmaster@1: }); webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Prevents the form from submitting if the suggestions popup is open webmaster@1: * and closes the suggestions popup when doing so. webmaster@1: */ webmaster@1: Drupal.autocompleteSubmit = function () { webmaster@1: return $('#autocomplete').each(function () { webmaster@1: this.owner.hidePopup(); webmaster@1: }).size() == 0; webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * An AutoComplete object webmaster@1: */ webmaster@1: Drupal.jsAC = function (input, db) { webmaster@1: var ac = this; webmaster@1: this.input = input; webmaster@1: this.db = db; webmaster@1: webmaster@1: $(this.input) webmaster@1: .keydown(function (event) { return ac.onkeydown(this, event); }) webmaster@1: .keyup(function (event) { ac.onkeyup(this, event); }) webmaster@1: .blur(function () { ac.hidePopup(); ac.db.cancel(); }); webmaster@1: webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Handler for the "keydown" event webmaster@1: */ webmaster@1: Drupal.jsAC.prototype.onkeydown = function (input, e) { webmaster@1: if (!e) { webmaster@1: e = window.event; webmaster@1: } webmaster@1: switch (e.keyCode) { webmaster@1: case 40: // down arrow webmaster@1: this.selectDown(); webmaster@1: return false; webmaster@1: case 38: // up arrow webmaster@1: this.selectUp(); webmaster@1: return false; webmaster@1: default: // all other keys webmaster@1: return true; webmaster@1: } webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Handler for the "keyup" event webmaster@1: */ webmaster@1: Drupal.jsAC.prototype.onkeyup = function (input, e) { webmaster@1: if (!e) { webmaster@1: e = window.event; webmaster@1: } webmaster@1: switch (e.keyCode) { webmaster@1: case 16: // shift webmaster@1: case 17: // ctrl webmaster@1: case 18: // alt webmaster@1: case 20: // caps lock webmaster@1: case 33: // page up webmaster@1: case 34: // page down webmaster@1: case 35: // end webmaster@1: case 36: // home webmaster@1: case 37: // left arrow webmaster@1: case 38: // up arrow webmaster@1: case 39: // right arrow webmaster@1: case 40: // down arrow webmaster@1: return true; webmaster@1: webmaster@1: case 9: // tab webmaster@1: case 13: // enter webmaster@1: case 27: // esc webmaster@1: this.hidePopup(e.keyCode); webmaster@1: return true; webmaster@1: webmaster@1: default: // all other keys webmaster@1: if (input.value.length > 0) webmaster@1: this.populatePopup(); webmaster@1: else webmaster@1: this.hidePopup(e.keyCode); webmaster@1: return true; webmaster@1: } webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Puts the currently highlighted suggestion into the autocomplete field webmaster@1: */ webmaster@1: Drupal.jsAC.prototype.select = function (node) { webmaster@1: this.input.value = node.autocompleteValue; webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Highlights the next suggestion webmaster@1: */ webmaster@1: Drupal.jsAC.prototype.selectDown = function () { webmaster@1: if (this.selected && this.selected.nextSibling) { webmaster@1: this.highlight(this.selected.nextSibling); webmaster@1: } webmaster@1: else { webmaster@1: var lis = $('li', this.popup); webmaster@1: if (lis.size() > 0) { webmaster@1: this.highlight(lis.get(0)); webmaster@1: } webmaster@1: } webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Highlights the previous suggestion webmaster@1: */ webmaster@1: Drupal.jsAC.prototype.selectUp = function () { webmaster@1: if (this.selected && this.selected.previousSibling) { webmaster@1: this.highlight(this.selected.previousSibling); webmaster@1: } webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Highlights a suggestion webmaster@1: */ webmaster@1: Drupal.jsAC.prototype.highlight = function (node) { webmaster@1: if (this.selected) { webmaster@1: $(this.selected).removeClass('selected'); webmaster@1: } webmaster@1: $(node).addClass('selected'); webmaster@1: this.selected = node; webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Unhighlights a suggestion webmaster@1: */ webmaster@1: Drupal.jsAC.prototype.unhighlight = function (node) { webmaster@1: $(node).removeClass('selected'); webmaster@1: this.selected = false; webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Hides the autocomplete suggestions webmaster@1: */ webmaster@1: Drupal.jsAC.prototype.hidePopup = function (keycode) { webmaster@1: // Select item if the right key or mousebutton was pressed webmaster@1: if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) { webmaster@1: this.input.value = this.selected.autocompleteValue; webmaster@1: } webmaster@1: // Hide popup webmaster@1: var popup = this.popup; webmaster@1: if (popup) { webmaster@1: this.popup = null; webmaster@1: $(popup).fadeOut('fast', function() { $(popup).remove(); }); webmaster@1: } webmaster@1: this.selected = false; webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Positions the suggestions popup and starts a search webmaster@1: */ webmaster@1: Drupal.jsAC.prototype.populatePopup = function () { webmaster@1: // Show popup webmaster@1: if (this.popup) { webmaster@1: $(this.popup).remove(); webmaster@1: } webmaster@1: this.selected = false; webmaster@1: this.popup = document.createElement('div'); webmaster@1: this.popup.id = 'autocomplete'; webmaster@1: this.popup.owner = this; webmaster@1: $(this.popup).css({ webmaster@1: marginTop: this.input.offsetHeight +'px', webmaster@1: width: (this.input.offsetWidth - 4) +'px', webmaster@1: display: 'none' webmaster@1: }); webmaster@1: $(this.input).before(this.popup); webmaster@1: webmaster@1: // Do search webmaster@1: this.db.owner = this; webmaster@1: this.db.search(this.input.value); webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Fills the suggestion popup with any matches received webmaster@1: */ webmaster@1: Drupal.jsAC.prototype.found = function (matches) { webmaster@1: // If no value in the textfield, do not show the popup. webmaster@1: if (!this.input.value.length) { webmaster@1: return false; webmaster@1: } webmaster@1: webmaster@1: // Prepare matches webmaster@1: var ul = document.createElement('ul'); webmaster@1: var ac = this; webmaster@1: for (key in matches) { webmaster@1: var li = document.createElement('li'); webmaster@1: $(li) webmaster@1: .html('