Login   Register  
PHP Classes
elePHPant
Icontem

File: appz/autosuggest/autosuggestcontroller.js

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Guilherme Blanco  >  pAjax  >  appz/autosuggest/autosuggestcontroller.js  >  Download  
File: appz/autosuggest/autosuggestcontroller.js
Role: Auxiliary data
Content type: text/plain
Description: Auto Suggestion Controller Script
Class: pAjax
Do RPC calls from the browser without page reloads
Author: By
Last change:
Date: 2005-09-13 19:30
Size: 5,731 bytes
 

Contents

Class file image Download
/*
 * AutoSuggestController based on Nicholas C.Zackas code
 */
function AutoSuggestController(oTextBox, oProvider) {
    this.provider = oProvider;
    this.textbox = oTextBox;
    this.layer = null;

    this.textboxInfo = this.getElementInfo(this.textbox);

    this.init();
}


var _p = AutoSuggestController.prototype;


_p.init = function () {
    var oThis = this;

    this.textbox.onkeyup = function (e) { oThis.handleKeyUp(e); }
    this.textbox.onkeydown = function (e) { oThis.handleKeyDown(e); }
    this.textbox.onblur = function (e) { oThis.hideSuggestions(); }

    this.createDropDown();
}


_p.selectRange = function (iStart, iLength) {
    if (this.textbox.createTextRange) {
        var oRange = this.textbox.createTextRange();
        oRange.moveStart("character", iStart);
        oRange.moveEnd("character", iLength - this.textbox.value.length);
        oRange.select();
    } else if (this.textbox.setSelectionRange)
        this.textbox.setSelectionRange(iStart, iLength);

    this.textbox.focus();
}


_p.typeAhead = function (sSuggestion) {
    if (this.textbox.createTextRange || this.textbox.setSelectionRange) {
        var iLength = this.textbox.value.length;
        this.textbox.value = sSuggestion;
        this.selectRange(iLength, sSuggestion.length);
    }
}


_p.autoSuggest = function (aSuggestions, bTypeAhead) {
    if (aSuggestions.length > 0) {
        if (bTypeAhead)
            this.typeAhead(aSuggestions[0]);
        
        this.showSuggestions(aSuggestions);
    } else this.hideSuggestions();
}


_p.hideSuggestions = function () { this.layer.style.visibility = "hidden"; }


_p.highlightSuggestion = function (oSuggestionNode) {
    for (var i = 0; i < this.layer.childNodes.length; i++) {
        var oNode = this.layer.childNodes[i];

        if (oNode == oSuggestionNode)
            oNode.className = "current";
        else if (oNode.className = "current")
            oNode.className = "";
    }
}


_p.createDropDown = function () {
    this.layer = document.createElement("DIV");
    this.layer.className = "suggestions";
    this.layer.style.visibility = "hidden";
    this.layer.style.width = this.textboxInfo.width - ((/msie/i.test(navigator.userAgent)) ? 2 : 0) + "px";

    document.body.appendChild(this.layer);
    
    var oThis = this;
    
    this.layer.onmousedown = this.layer.onmouseup =
    this.layer.onmouseover = function (e) {
        var oEvent = e || window.event;
        var oTarget = oEvent.target || oEvent.srcElement;
        
        if (oEvent.type == "mousedown") {
            oThis.textbox.value = oTarget.firstChild.nodeValue;
            oThis.hideSuggestions();
        } else if (oEvent.type == "mouseover")
            oThis.highlightSuggestion(oTarget);
        else
            oThis.textbox.focus();
    }
}


_p.showSuggestions = function (aSuggestions) {
    var oDiv = null;
    this.layer.innerHTML = "";
    
    for (var i = 0; i < aSuggestions.length; i++) {
        oDiv = document.createElement("DIV");
        oDiv.appendChild(document.createTextNode(aSuggestions[i]));
        this.layer.appendChild(oDiv);
    }
    
    this.layer.style.left = (this.textboxInfo.left - 2) + "px";
    this.layer.style.top = (this.textboxInfo.top + this.textboxInfo.height - 1) + "px";
    this.layer.style.visibility = "visible";
}


_p.nextSuggestion = function () {
    var cSuggestionNodes = this.layer.childNodes;
    var currentNode = this.getCurrentFocused();

    if (cSuggestionNodes.length > 0 && currentNode < cSuggestionNodes.length - 1) {
        var oNode = cSuggestionNodes[currentNode + 1];
        this.highlightSuggestion(oNode);
        this.textbox.value = oNode.firstChild.nodeValue;
    }
}


_p.previousSuggestion = function () {
    var cSuggestionNodes = this.layer.childNodes;
    var currentNode = this.getCurrentFocused();

    if (cSuggestionNodes.length > 0 && currentNode > 0) {
        var oNode = cSuggestionNodes[currentNode - 1];
        this.highlightSuggestion(oNode);
        this.textbox.value = oNode.firstChild.nodeValue;
    }
}


_p.getCurrentFocused = function () {
    var cSuggestionNodes = this.layer.childNodes;

    if (cSuggestionNodes.length > 0) {
        for (var i = 0; i < cSuggestionNodes.length; i++) {
            if (cSuggestionNodes[i].className == "current")
                return i;
        }
    }
    
    return -1;
}


_p.getElementInfo = function (el) {
    if (el.getBoundingClientRect) {
        var o = el.getBoundingClientRect();

        this.top = o.top;
        this.left = o.left;
        this.width = (o.right - o.left);
        this.height = (o.bottom - o.top);
    } else if (document.getBoxObjectFor) {
        var o = document.getBoxObjectFor(el);

        this.top = o.y;
        this.left = o.x;
        this.width = o.width;
        this.height = o.height;
    }
    
    return this;
}


_p.handleKeyUp = function (e) {
    var oEvent = e || window.event;
    var code = oEvent.keyCode;

    if (!(code < 32 || (code >= 33 && code <= 46) || (code >= 112 && code <= 123)))
        this.provider.requestSuggestions(this, ((code == 8 || code == 46) ? false : true));
}


_p.handleKeyDown = function (e) {
    var oEvent = e || window.event;

    switch (oEvent.keyCode) {
        case 38: // UP Arrow
            this.previousSuggestion();
            break;
        
        case 40: // DOWN Arrow
            this.nextSuggestion();
            break;
        
        case 13: // ENTER
            this.hideSuggestions();
            break;
    }
}