Perform a tab with js

Ahh, I think that we’re getting confused about things. I’ve been talking about the tab key on your keyboard, the one on the left just above the caps lock key.

I am talking about that one too… :)(:

I have an idea… but ill start out by asking with a single part instead of the whole thing :slight_smile:
hmm let’s start from square one— not the beginning, but soon after (because programmers start counting at 0) :stuck_out_tongue: :

So the following listens for the tab key being pressed:

body.onkeydown = function (evt) {
    var allowDefault = true;
    evt = evt || event;
 
    if (evt.keyCode === 9) {
        // tab was pressed
    }
    return allowDefault;
};

So from this, how can I interrupt and stop what the tab-key normally does and instead alert(“tab was prevented and replaced with this alert”);

Here’s an example using standard event registration:


function getOrder = function () {
    // do stuff here
}

document.getElementById('getOrder').onclick = getOrder;

And here’s an example using advanced event registration:


function addEvent(el, evtType, func) {
    if (el.addEventListener) {
        el.addEventListener(evtType, func, false);
    } else if (el.attachEvent) {
        el.attachEvent('on' + evtType, func);
    } else {
        throw exception('Handler could not be attached');
    }
}
        
function getOrder = function () {
    // do stuff here
}

addEvent(document.getElementById("getOrder"), 'click', getOrder);

The problem though with using advanced event registrations though is that in Internet Explorer, the this keyword always refer to the window object, and not to the element that triggered the event.

You can do that by setting allowDefault to false, which when it’s returned from the function, will prevent the default behaviour of that event from happening.

Do you mean like this (changes in bold):
body.onkeydown = function (evt) {
var allowDefault = false;
evt = evt || event;

if (evt.keyCode === 9) {
    // tab was pressed
}
return allowDefault;

};
if(function(evt) == false){
alert(“tab was prevented and replaced with this alert”);
}

or was i supposed to set allowDefault to false elsewhere…

No, not like that. That will prevent the default of every key that is ever pressed.
Instead, you only want that to occur when the tab key is pressed.

Secondly, you may want to call a function when the tab key is pressed, so that you can more easily encapsulate what you want to achieve.


...
if (evt.keyCode === 9) {
    allowDefault = handleTabKey();
}
...


function handleTabKey() {
    // potentially other stuff here, and then
    return false;
}

I thought so, but I wanted to try that to confirm it with you.

Also why have a function handleTabKey() return something. Isn’t it useless or less useful right now, but wouldn’t it help later in executing other things after interrupting the tab’s default function ?

But for now, without other things happening, can’t we set allowDefault to false without a function like so:


body.onkeydown = function (evt) {
    var allowDefault = true;
    evt = evt || event;
 
    if (evt.keyCode === 9) {
        // tab was pressed
        allowDefault = false
    }
    return allowDefault;
    
    if(allowDefault === false){
        alert("tab was prevented and replaced with this alert");
    }  
};

or this… (it seems like they do the same thing— the latter with less code)


body.onkeydown = function (evt) {
    var allowDefault = true;
    evt = evt || event;
 
    if (evt.keyCode === 9) {
        // tab was pressed
        alert("tab was prevented and replaced with this alert");
    }
    return allowDefault;
};

or even this…
(or without using allowDefault at all, for now, and therefore not intialising or returning it. And executing what replaces the tab’s default behaviour straight when the tab key is detected in the if statement*)


body.onkeydown = function (evt) {
    evt = evt || event;
 
    if (evt.keyCode === 9) {
        // tab was pressed
        alert("tab was prevented and replaced with this alert");
    }
};

*I can see how this would be messy code, is that why you suggested to encapsulate it into a function?

2 more questions:
1.) So do all of the above do the same thing?
2.) Is that same thing interrupting the tab button’s function once pressed and alerting the message instead?

Because that then passes control of whether the default behaviour continues to occur or not to the function, which is where such decisions should be based.

Yes it would.

Doing it that way means that the onkeydown function is doing more than it should be doing. Also, the alert about the tab could occur in a better location than outside of the section that relates to tabs.

Yes, that’s better. Now the code that relates to the tab key being pressed is within the section of code that determines whether it was the tab key that was pressed.

No, you don’t want to remove that allowDefault part.
The web browser will always perform its default behavior unless you explicitly return a value of false from the function.

That’s right.

They’re similar, and have been commented on above.

I don’t understand what you’re asking there.

That’s right.[/QUOTE]
ah okay. i’ll keep that in mind for later on.

ah okay. I understand :slight_smile:
Then for now, we’ll go with this:

body.onkeydown = function (evt) {
    var allowDefault = true;
    evt = evt || event;
 
    if (evt.keyCode === 9) {
        // tab was pressed
        alert("tab was prevented and replaced with this alert");
    }
    return allowDefault;
};

Its okay. I worded that weird, but you answered it still before.(:

okay this is completely different, but related…
Suppose I wanted to execute tab when enter is pressed. I know enter’s keyCode is 13, but how would the js for that work…

That would be much more difficult. It’s not possible to just replace one keystroke with a different one.

Instead, you would need to prevent the web browser’s default action, find the active field on the page (which might not have an active one) and then loop through the fields looking for the one that’s active, get the next field area and set that next focus to the next field.

Finally, the expected behavior that the user expects from the web browser will be different from what they have experienced on thousands of other sites that the user uses (where Enter submits active form), so you are likely to have usability problems to deal with there too.

Ah okay. That sounds horribly hard— let’s scratch that.

How about this:
Inside the if statement, that checks if the keyCode is 9, is where we can add things to the default functionality of what happens once the tab-button is pressed. But if we want to rewrite the behaviour, we set the allowDefault to false and then we write the new behaviour.
1.) so in this if statement and / or the entire function (when allowDefault is true) is where the default action of the tab button occurs, right?
2.) Is there a way I can set the default behaviour, without my changes, to a variable?
Or store it somehow?
something like soring the result of this in complete pseudo-code whatWasGoingToHappenDefaultly().or tabKey.whatWasGoinfToHappenByDefault()

Does that make sense? Do you understand? Or have some ideas?

Nope, inside that function is what happens when the tab is pressed down on the keyboard. After that function finishes, the web browser carries on with its own default (non-scripted) behaviour for when the key is pressed, unless of course false has been returned from the function to suppress that default behaviour.

Nope, it’s not possible to do that.

Pardon my french: ****! I was hoping it could be bloody done that way…
Guess GlaDOS was wrong… " The best solution to a problem is usually the easiest one ".
or at least not the easiest sounding one…

hmmm time for some out-of-the-box-thinking

what if, inside the function called once #button is clicked, allowDefault is set to true:

document.getElementById('button').onclick = function () {
    body.onkeydown = function (evt) {
        var allowDefault = true;
        evt = evt || event;
 
        if (evt.keyCode === 9) {
        // tab was pressed
        }
        return allowDefault;
    };
};

Will that preform the tab’s default action once #button is clicked. Or will it just allow the tab’s default action everytime tab is pressed after the button is clicked?

Or what about this… Won’t it execute the tab’s default action once the button is clicked?


body.onkeydown = function (evt) {
    var allowDefault = false;
    evt = evt || event;
 
    if (evt.keyCode === 9) {
        // tab was pressed
        document.getElementById('button').onclick = function () {
            allowDefault = true
        };

    }
    return allowDefault;
};

or this…


document.getElementById('button').onclick = function () {
    allowDefault = true
};
body.onkeydown = function (evt) {
    var allowDefault = false;
    evt = evt || event;
 
    if (evt.keyCode === 9) {
        // tab was pressed
    }
    return allowDefault;
};

or even this…


var buttonPressed = false;
document.getElementById('button').onclick = function () {
    buttonPressed = true;
    return buttonPressed;
};
body.onkeydown = function (evt) {
    var allowDefault = false;
    evt = evt || event;
 
    if (evt.keyCode === 9) || (buttonPressed === true){
        // tab was pressed
        allowDefault = true
    }
    return allowDefault;
};

Nope, for when the internal onclick event fires, the function won’t be in the same scope as the rest of the code there.

Different scopes again, one being a global scope and the other being local to the function.

Just what are you trying to achieve?

Honestly, I am just trying to create a button that does the following once clicked:
Moves to the next input, textarea, or select in a form.

By moves, I mean focuses on.

Is there a way one can apply focus to an id?

It sounds like a simple thing, but once you click on the button the web browser doesn’t know where the focus was before that.
So, you need to do what was mentioned in post #29

Sure thing, with the elem.focus() method.

oh. okay…

What if I gave each of the different elements in the form an id of inputX. X being the number of input that it is starting at 0 and increasing as one goes down the form.

Could you help me write a script that on click of #button focuses on the element with the id #inputX. and X is +1 of what ever X was before?
so maybe something like this (mostly in pseudo-code):

var X = 0;
#button.click( function(){
X = intFormOf(lastCharacterInX) + 1
var idName=“input”+stringFormOf(X)
idName.focus()
});

It can be done without adding vast numbers of unique identifiers to your HTML, by using the onblur event to keep track of what that previous element was. That way you can just loop through the elements within a form, and when you come across one that matches you know that the next one is what should then receive the focus.

Why though are you using an on-screen button when the behaviour you want works automatically within the web browser by pressing the tab key on the keyboard?

well its part of a project that I am working on and I don’t have control over changing this form. :frowning:
But it less than normal, but not too small viewports (usually older machines) the form is partially hidden. My task was to make it work in small(er) viewports without a scroll-bar.
So I thought tabbing through the form. The boss-man :lol: liked that idea and told me to go through with it. So I told him that its already there— pretty much all keyboards do it.

But, he insisted that everyone has to contribute on all parts of the project and told me to make a button on the side of the form that tabs.

So I am kind of stuck with getting this to work— if i want to get paid that it :slight_smile:

Its kind of like auto-tab in forms, but we don’t know how much the user is going to type. As there is no limit.
Well, there is an assumed limit, but nothing strict like on Twitter.

Does my reasoning shed some light on my situation now (and why I have been so persistent in finishing this) ?
And would / could you help me with the blur and focus script?
:slight_smile:

You need to tell your boss that web browsers don’t work in that way. It can be possible to partially simulate things, but it will be a costly exercise for your boss that won’t result in much of a beneficial result.

It’s our job as web developers to help our boss achieve what he wants, and also to advise and educate him when he tries to do what is not reasonable or practical, or cost-effective.

okay. will do tomorrow morning.

but, could you still help me start a script that blurs the current field and focus on the next one?
Like you described here:

It can be done without adding vast numbers of unique identifiers to your HTML, by using the onblur event to keep track of what that previous element was. That way you can just loop through the elements within a form, and when you come across one that matches you know that the next one is what should then receive the focus.

Its just that I want to cover my bases and at least have something because the project deadline is Sunday, but this form and my part in it was a small part of the rest I have to develop.