web-dev-qa-db-fra.com

Comment déplacer le focus sur le champ suivant lorsque vous appuyez sur Entrée?

Pouvez-vous s'il vous plaît me dire comment déplacer le focus sur le champ suivant lorsque la touche Entrée est enfoncée? J'utilise le plugin dform (qui convertit JSON en formulaire). 

Je l'ai googlé, mais cela ne fonctionne pas. Pourquoi mon objectif ne passe-t-il pas au champ suivant?

JSFiddle: http://jsfiddle.net/5WkVW/1/

$(document).keypress(function(e) {
    if(e.which == 13) {

            // Do something here if the popup is open
            alert("dd")
            var index = $('.ui-dform-text').index(this) + 1;
            $('.ui-dform-text').eq(index).focus();

    }
});

* Remarque (tiré des commentaires): Il doit également fonctionner sur les pages pour lesquelles les valeurs tabindex ne sont pas définies.

11
Shruti

Elle échoue car this est la document dans votre code.

Vous souhaitez utiliser l'index de l'élément actuellement sélectionné (document.activeElement) ou, si vous utilisez des événements délégués, vous pouvez vous assurer que this est l'élément actuel.

Cette version finale fonctionne qu’il existe ou non tabindexes. Il entoure également:

JSFiddle 1: http://jsfiddle.net/TrueBlueAussie/5WkVW/11/

JSFiddle 2: http://jsfiddle.net/TrueBlueAussie/5WkVW/12/

Ils utilisent tous les deux un sélecteur jQuery personnalisé que j’ai ajouté et appelé :focusable pour sélectionner tous les éléments activables (y compris les liens):

// register jQuery extension
jQuery.extend(jQuery.expr[':'], {
    focusable: function (el, index, selector) {
        return $(el).is('a, button, :input, [tabindex]');
    }
});

$(document).on('keypress', 'input,select', function (e) {
    if (e.which == 13) {
        e.preventDefault();
        // Get all focusable elements on the page
        var $canfocus = $(':focusable');
        var index = $canfocus.index(this) + 1;
        if (index >= $canfocus.length) index = 0;
        $canfocus.eq(index).focus();
    }
});

Vous pouvez utiliser le même sélecteur personnalisé dans le gestionnaire d'événements si vous le souhaitez. Ensuite, cela fonctionnera même sur les liens d'ancrage (si vous modifiez l'événement en keydown au lieu d'appuyer sur la touche):

par exemple.

$(document).on('keydown', ':focusable', function (e) {

Exemple avec lien: http://jsfiddle.net/5WkVW/15/

Ceci utilise également une on déléguée, à l'écoute de l'événement keydown sur la document. Il then applique le sélecteur jQuery, il then applique la fonction à tout élément correspondant ayant provoqué l'événement. Ceci est beaucoup plus efficace car il n'applique que le sélecteur au moment de l'événement (plutôt que d'appliquer plusieurs gestionnaires d'événements à chaque élément de correspondance DOM).


Anciennes versions ci-dessous:

JSFiddle: http://jsfiddle.net/TrueBlueAussie/5WkVW/3/

$(document).keypress(function(e) {
    if(e.which == 13) {

            // Do something here if the popup is open
            //alert("dd")
            var index = $('.ui-dform-text').index(document.activeElement) + 1;
            $('.ui-dform-text').eq(index).focus();

    }
});

* Remarque: alerts pouvant interférer avec focus, utilisez donc console.log pour une sortie comme celle-ci et affichez-la dans la fenêtre de débogage de la plupart des navigateurs (comme les outils de débogage de Chrome F12).

Mise à jour: http://jsfiddle.net/TrueBlueAussie/5WkVW/4/

Celui-ci revient au premier élément du dernier et fonctionne également sur les sélections (le comportement par défaut est bloqué, de sorte que vous ne pouvez utiliser que de l'espace pour ouvrir ou monter/descendre pour sélectionner des options.

$('input,select').on('keypress', function (e) {
    if (e.which == 13) {
        e.preventDefault();
        var $next = $('[tabIndex=' + (+this.tabIndex + 1) + ']');
        console.log($next.length);
        if (!$next.length) {
            $next = $('[tabIndex=1]');
        }
        $next.focus();
    }
});

Version "document" demandée: http://jsfiddle.net/TrueBlueAussie/5WkVW/5/

$(document).on('keypress', 'input,select', function (e) {
    if (e.which == 13) {
        e.preventDefault();
        var $next = $('[tabIndex=' + (+this.tabIndex + 1) + ']');
        console.log($next.length);
        if (!$next.length) {
            $next = $('[tabIndex=1]');
        }
        $next.focus();
    }
});
27
Gone Coding

Ill créé une version non-jQuery. Donc, seulement du Javascript pur; https://jsfiddle.net/mm0uctuv/2/

Javascript:

var inputs = document.querySelectorAll("input,select");
for (var i = 0 ; i < inputs.length; i++) {
   inputs[i].addEventListener("keypress", function(e){
      if (e.which == 13) {
         e.preventDefault();
         var nextInput = document.querySelectorAll('[tabIndex="' + (this.tabIndex + 1) + '"]');
         if (nextInput.length === 0) {
            nextInput = document.querySelectorAll('[tabIndex="1"]');
         }
         nextInput[0].focus();
      }
   })
}

HTML:

<form>
   Field 1: <input type="text" tabindex="1"><br>
   Field 3: <input type="text" tabindex="3"><br>
   Field 2: <input type="text" tabindex="2">
</form>
3
Ramon Bakker

Le code suivant devrait le faire; il utilise la propriété tabIndex. Faites-nous savoir si ce n'est pas acceptable:

$(function() {
    $('input').on('keypress', function(e) {
        e.which !== 13 || $('[tabIndex=' + (+this.tabIndex + 1) + ']')[0].focus();
    });
});

La liste déroulante a déjà la touche entrée destinée à l’ouvrir.

JS FIDDLE DEMO

Pour pouvoir faire quelque chose avant de passer à l'élément de formulaire suivant, vous pouvez utiliser la version suivante:

$(function() {
    $(document).on('keypress', function(e) {
        var that = document.activeElement;
        if( e.which == 13 ) {
            e.preventDefault();
            alert( "dd" );
            $('[tabIndex=' + (+that.tabIndex + 1) + ']')[0].focus();
        }            
    });
});

D&EACUTE;MO

2
PeterKA

Sur la div de niveau supérieur, ajoutez onKeyDown={this.onKeyDown.bind(this)} et ajoutez la méthode suivante (ES6) à la même classe que la div:

onKeyDown(event) {
    if (event.keyCode === 13) {
        event.preventDefault()
        const inputs =
            Array.prototype.slice.call(document.querySelectorAll("input"))
        const index =
            (inputs.indexOf(document.activeElement) + 1) % inputs.length
        const input = inputs[index]
        input.focus()
        input.select()
    }
}
2
Ralph

Essayez le code JavaScript suivant que j'ai modifié de votre violon. Le comportement par défaut des éléments sélectionnés consiste à développer la pression de touche. Le signe plus au début de + $ (this) .attr ("tabindex")

Convertit la valeur de l'attribut text en int.

$(".ui-dform-text").keypress(function(e) {
    if(e.which == 13) {

        // Do something here if the popup is open
        alert($(this).attr("tabindex"));
        var index = +$(this).attr("tabindex") + 1;


        $("[tabindex='" + index +"']").focus();
    }
});
0
JDTLH9