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