# Yahoo! UI Library

### Event Utility 2.6.0

Yahoo! UI Library > event > KeyListener.js (source view)

Show Private Show Protected Show Deprecated

    //@TODO optimize
    //@TODO use event utility, lang abstractions
    //@TODO replace

    /**
    * KeyListener is a utility that provides an easy interface for listening for
    * keydown/keyup events fired against DOM elements.
    * @namespace YAHOO.util
    * @class KeyListener
    * @constructor
    * @param {HTMLElement} attachTo The element or element ID to which the key
    *                               event should be attached
    * @param {String}      attachTo The element or element ID to which the key
    *                               event should be attached
    * @param {Object}      keyData  The object literal representing the key(s)
    *                               to detect. Possible attributes are
    *                               shift(boolean), alt(boolean), ctrl(boolean)
    *                               and keys(either an int or an array of ints
    *                               representing keycodes).
    * @param {Function}    handler  The CustomEvent handler to fire when the
    *                               key event is detected
    * @param {Object}      handler  An object literal representing the handler.
    * @param {String}      event    Optional. The event (keydown or keyup) to
    *                               listen for. Defaults automatically to keydown.
    *
    * @knownissue the "keypress" event is completely broken in Safari 2.x and below.
    *             the workaround is use "keydown" for key listening.  However, if
    *             it is desired to prevent the default behavior of the keystroke,
    *             that can only be done on the keypress event.  This makes key
    *             handling quite ugly.
    * @knownissue keydown is also broken in Safari 2.x and below for the ESC key.
    *             There currently is no workaround other than choosing another
    *             key to listen for.
    */
    YAHOO.util.KeyListener = function(attachTo, keyData, handler, event) {
        if (!attachTo) {
            YAHOO.log("No attachTo element specified", "error");
        } else if (!keyData) {
            YAHOO.log("No keyData specified", "error");
        } else if (!handler) {
            YAHOO.log("No handler specified", "error");
        }

        if (!event) {
            event = YAHOO.util.KeyListener.KEYDOWN;
        }

        /**
        * The CustomEvent fired internally when a key is pressed
        * @event keyEvent
        * @private
        * @param {Object} keyData The object literal representing the key(s) to
        *                         detect. Possible attributes are shift(boolean),
        *                         alt(boolean), ctrl(boolean) and keys(either an
        *                         int or an array of ints representing keycodes).
        */
        var keyEvent = new YAHOO.util.CustomEvent("keyPressed");

        /**
        * The CustomEvent fired when the KeyListener is enabled via the enable()
        * function
        * @event enabledEvent
        * @param {Object} keyData The object literal representing the key(s) to
        *                         detect. Possible attributes are shift(boolean),
        *                         alt(boolean), ctrl(boolean) and keys(either an
        *                         int or an array of ints representing keycodes).
        */
        this.enabledEvent = new YAHOO.util.CustomEvent("enabled");

        /**
        * The CustomEvent fired when the KeyListener is disabled via the
        * disable() function
        * @event disabledEvent
        * @param {Object} keyData The object literal representing the key(s) to
        *                         detect. Possible attributes are shift(boolean),
        *                         alt(boolean), ctrl(boolean) and keys(either an
        *                         int or an array of ints representing keycodes).
        */
        this.disabledEvent = new YAHOO.util.CustomEvent("disabled");

        if (typeof attachTo == 'string') {
            attachTo = document.getElementById(attachTo);
        }

        if (typeof handler == 'function') {
            keyEvent.subscribe(handler);
        } else {
            keyEvent.subscribe(handler.fn, handler.scope, handler.correctScope);
        }

        /**
        * Handles the key event when a key is pressed.
        * @method handleKeyPress
        * @param {DOMEvent} e   The keypress DOM event
        * @param {Object}   obj The DOM event scope object
        * @private
        */
        function handleKeyPress(e, obj) {
            if (! keyData.shift) {
                keyData.shift = false;
            }
            if (! keyData.alt) {
                keyData.alt = false;
            }
            if (! keyData.ctrl) {
                keyData.ctrl = false;
            }

            // check held down modifying keys first
            if (e.shiftKey == keyData.shift &&
                e.altKey   == keyData.alt &&
                e.ctrlKey  == keyData.ctrl) { // if we pass this, all modifiers match

                var dataItem;

                if (keyData.keys instanceof Array) {
                    for (var i=0;i<keyData.keys.length;i++) {
                        dataItem = keyData.keys[i];

                        if (dataItem == e.charCode ) {
                            keyEvent.fire(e.charCode, e);
                            break;
                        } else if (dataItem == e.keyCode) {
                            keyEvent.fire(e.keyCode, e);
                            break;
                        }
                    }
                } else {
                    dataItem = keyData.keys;
                    if (dataItem == e.charCode ) {
                        keyEvent.fire(e.charCode, e);
                    } else if (dataItem == e.keyCode) {
                        keyEvent.fire(e.keyCode, e);
                    }
                }
            }
        }

        /**
        * Enables the KeyListener by attaching the DOM event listeners to the
        * target DOM element
        * @method enable
        */
        this.enable = function() {
            if (! this.enabled) {
                YAHOO.util.Event.addListener(attachTo, event, handleKeyPress);
                this.enabledEvent.fire(keyData);
            }
            /**
            * Boolean indicating the enabled/disabled state of the Tooltip
            * @property enabled
            * @type Boolean
            */
            this.enabled = true;
        };

        /**
        * Disables the KeyListener by removing the DOM event listeners from the
        * target DOM element
        * @method disable
        */
        this.disable = function() {
            if (this.enabled) {
                YAHOO.util.Event.removeListener(attachTo, event, handleKeyPress);
                this.disabledEvent.fire(keyData);
            }
            this.enabled = false;
        };

        /**
        * Returns a String representation of the object.
        * @method toString
        * @return {String}  The string representation of the KeyListener
        */
        this.toString = function() {
            return "KeyListener [" + keyData.keys + "] " + attachTo.tagName +
                    (attachTo.id ? "[" + attachTo.id + "]" : "");
        };

    };

    /**
     * Constant representing the DOM "keydown" event.
     * @property YAHOO.util.KeyListener.KEYDOWN
     * @static
     * @final
     * @type String
     */
    YAHOO.util.KeyListener.KEYDOWN = "keydown";

    /**
     * Constant representing the DOM "keyup" event.
     * @property YAHOO.util.KeyListener.KEYUP
     * @static
     * @final
     * @type String
     */
    YAHOO.util.KeyListener.KEYUP = "keyup";

    /**
     * keycode constants for a subset of the special keys
     * @property KEY
     * @static
     * @final
     */
    YAHOO.util.KeyListener.KEY = {
        ALT          : 18,
        BACK_SPACE   : 8,
        CAPS_LOCK    : 20,
        CONTROL      : 17,
        DELETE       : 46,
        DOWN         : 40,
        END          : 35,
        ENTER        : 13,
        ESCAPE       : 27,
        HOME         : 36,
        LEFT         : 37,
        META         : 224,
        NUM_LOCK     : 144,
        PAGE_DOWN    : 34,
        PAGE_UP      : 33,
        PAUSE        : 19,
        PRINTSCREEN  : 44,
        RIGHT        : 39,
        SCROLL_LOCK  : 145,
        SHIFT        : 16,
        SPACE        : 32,
        TAB          : 9,
        UP           : 38
    };

Copyright © 2008 Yahoo! Inc. All rights reserved.