Enter to tab script help

Hi All

I have be using the below javascript for a few years now but the latest update from google chrome has stopped it from working. I could never get it to work in either IE or firefox. Is there a fix for this so I can get it working again in google chrome? or is there a better one out there?.

enterAsTab = function(){
	function next(e){
		var l, i, f, j, o = e.target;
		if(e.key == 13 && !/textarea|select/i.test(o.type)){
			for(i = l = (f = o.form.elements).length; f[--i] != o;);
			for(j = i; (j = (j + 1) % l) != i && (!f[j].type || f[j].disabled || f[j].readOnly || f[j].type.toLowerCase() == "hidden"); );				
			e.preventDefault(), j != i && f[j].focus();
		}
	}
	for(var f, i = (f = document.forms).length; i; addEvent(f[--i], "keypress", next));
};

and then I insert the following into a php page

<script type="text/javascript">


enterAsTab();


</script>

Thanks

Rob.

Hi @robrayner, the JS code above is rather hard to read w/ these nondescript variable names. Is this a 3rd party snippet or did you write it yourself?

Anyway, AFAIK <script12> is not a valid tag name… I’d imagine that Chrome just guessed it correctly so that you got the expected result. Also, you didn’t declare enterAsTab as a variable, which would yield an error in strict mode.

Hi @m3g4p0p

The script is a 3rd party snippet. The only reason i put was because in the preview pain for this forum it was not showing up and that was the only way i could get it to display I have now edited the above post to be as in my page.

Where should I declare enterAsTab as a variable? and how do I declare it?

Thanks

Rob.

Off Topic

You need to format any code in your posts so that it shows up correctly.

You can highlight your code, then use the </> button in the editor window, which will format it.

Or you can place three backticks ``` (top left key on US/UK keyboards) on a line before your code, and three on a line after your code. I find this approach easier, but unfortunately some European and other keyboards don’t have that character.

1 Like

Two changes need to be made to get this code working.

First, modern web browsers don’t have the an event.key property, instead they have an event.keyCode property. So you’ll need to use e.keyCode instead. If you want good cross-compatibility you can use both, such as:

if ((e.keyCode || e.charCode) == 13 ...) {

Second, the addEvent function doesn’t exist. That might be in some other library code that you have elsewhere, that decides whether to use addEventListener or attachEvent instead.

I suspect that it will be similar to the following sort of code:

function addEvent(obj, evType, fn, useCapture){
  if (obj.addEventListener){
    obj.addEventListener(evType, fn, useCapture);
    return true;
  } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be attached");
  }
}

With both of those changes in place, the code works on my Chrome web browser, and should work on yours too.

1 Like

Here is an improved version of that script, that has been reworked to be a whole hell of a lot easier to understand.

/*jslint browser */
/*global window */
window.enterAsTab = function () {
    "use strict";
    function isEnterKey(evt) {
        return (evt.keyCode || evt.charCode) === 13;
    }
    function isTextareaOrSelect(field) {
        return (/textarea|select/i).test(field.type);
    }
    function getCurrentIndex(field, fields) {
        var currentIndex = fields.length;
        do {
            currentIndex -= 1;
        } while (fields[currentIndex] !== field);
        return currentIndex;
    }
    function isInvalidField(field) {
        return !field.type || field.disabled || field.readOnly || field.type.toLowerCase() === "hidden";
    }
    function getNextIndex(currentIndex, fields) {
        var nextIndex = currentIndex;
        do {
            nextIndex = (nextIndex + 1) % fields.length;
        } while (nextIndex !== currentIndex && (isInvalidField(fields[nextIndex])));
        return nextIndex;
    }
    function next(evt) {
        if (!isEnterKey(evt) || isTextareaOrSelect(evt.target)) {
            return;
        }
        var field = evt.target;
        var fields = field.form.elements;
        var currentIndex = getCurrentIndex(field, fields);
        var nextIndex = getNextIndex(currentIndex, fields);
        if (nextIndex !== currentIndex) {
            fields[nextIndex].focus();
        }
        evt.preventDefault();
    }
    function addEvent(obj, evType, fn, useCapture) {
        if (obj.addEventListener) {
            obj.addEventListener(evType, fn, useCapture);
            return true;
        }
        if (obj.attachEvent) {
            var r = obj.attachEvent("on" + evType, fn);
            return r;
        }
        window.alert("Handler could not be attached");
    }
    var forms = document.forms;
    var i = forms.length;
    while (i) {
        i -= 1;
        addEvent(forms[i], "keypress", next);
    }
};
1 Like

Whoops, the following doesn’t work:

return (evt.key || evt.keyCode) === 13;

The following does work:

return (evt.keyCode || evt.charCode) === 13;

You can see a working example at https://jsfiddle.net/pmw57/2qk0qLwu/

According to a Quirksmode article on detecting keystrokes, keyCode and charCode are used to obtain the code for the key that was pressed.

The .key property (that was used in the original code) in modern web browsers gives a string representation of the key that was pressed. “Enter” for the enter key, “a” for the letter a, and so on. I’m told by MDN’s KeyboardEvent.key documentation that early Internet Explorer’s implementation used an older spec and thus results in different results.

The code in the above posts has been updated to reflect this improvement.

TLDR: evt.key is bad. Use keyCode or charCode instead.

4 Likes

Thank you thank you @Paul_Wilkins that works a charm.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.