Search code examples
javascriptfocusprototypejsdom-events

Focus on text area after tab in prototype Javascript library


I am trying to make a text area tab-aware and as a part of it I have written the following Javascript. I am using prototype js library,

document.observe("dom:loaded", function (){
    $('tabawaretextarea').observe('keydown',function(e) {
            if(e.keyCode === 9) { // tab was pressed
            $('tabawaretextarea').value = $F('tabawaretextarea')+"\t";
                            $('tabawaretextarea').focus();
            return false;
        }
    })
});

As expected, the tabs are getting appended at the end. However, my text area loses the focuse and the HTML element next to the text area is getting focused. I believe the return false should do the magic but it does not.

Apart from this, I also tried setting all elements tabindex to -1, some article said I have to use "autoTab" class and set maxlength for tab to work - I tried doing that, as I am using a spring based <form:textarea/> attribute maxlength is not allowed(even otherwise maxlength is not allowed in text areas).

Any suggestions?


Solution

  • return false; does nothing in prototype event handlers. To suppress the default action, use Event.stop(). Also, you'll need to do this on keypress, not keydown:

    document.observe("dom:loaded", function (){
        $('tabawaretextarea').observe('keypress',function(e) {
            if(e.keyCode === 9) { // tab was pressed
                $('tabawaretextarea').value += "\t";
                e.stop();
            }
        });
    });
    

    NOTE: This works in FF but this will not work in Chrome and AFAIK there is no workaround. I've not tested IE, Opera or Safari.

    EDIT: 'keydown' does actually work, and works in Chrome and FF. Again, other browsers not tested, but here is the solution:

    document.observe("dom:loaded", function (){
        $('tabawaretextarea').observe('keydown',function(e) {
            if(e.keyCode === 9) { // tab was pressed
                $('tabawaretextarea').value += "\t";
                e.stop();
                // note that we don't need to focus() the element as it hasn't lost focus
            }
        });
    });
    

    See it on jsFiddle