Bonjour à tous,
Je bloque sur la fonction Next de Jquery que j´utilise sur des input dynamiques.
Mes input se créent via une boucle Foreach en php.
Cette boucle lit un Array contenant les noms et id de mes input que je génère via un echo.

Côté Jquery, je verifie sur un .on('keyup') si on appuie sur la touche entrée alors je fais un .next.focus() pour que le curseur se mette sur le input suivant.
Et là ca ne fonctionne pas.

J'ai fait le test avec des inputs saisie manuellement directement en html, et là, ça fonctionne.

Donc il y a bien un problème avec le fait que mes input proviennent d'une boucle, mais je ne sais comment régler ça.

Je comprends le truc par le fait que ma page doit avoir fini de charger avant que mon php ai généré mes inputs.

L'idée globale du projet, c'est de sortir une liste d'étudients via une BDD sql, de générer des inputs, et de venir bipper des carte RFID, et de les renvoyer ensuite dans la BDD.
=> Affectation de cartes en masse

Merci d´avance pour vos lumières.

<!DOCTYPE html>
<html lang="fr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Affectation cartes</title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
</head>

<body>
    <script type='text/javascript'>
        $(document).ready(function() {
            $(".cardValue").on('keyup', function(keyValue) {
                if (keyValue.keyCode == 13) { //If keyCode is "Enter" = 13
                    $(this).next('.cardValue').focus();
                }
            });

        });
    </script>
    <form action="" method="post">
        <?php
        $arrayStudents[] = array('id' => 111, 'name' => 'Luke');
        $arrayStudents[] = array('id' => 222, 'name' => 'Leia');
        $arrayStudents[] = array('id' => 666, 'name' => 'Anakin');

        $tabIndexValue = 1;
        foreach ($arrayStudents as $oneStudent) {
            echo $oneStudent['name'] . " : <input type='text' tabindex=" . $tabIndexValue . " class='cardValue' name = '" . $oneStudent['id'] . "' placeholder='" . $oneStudent['name'] . "'><br>";
            //Ca ne fonctionne pas avec les input provenant de cette boucle.
            $tabIndexValue++;
        }
        ?>
        <input type='text' class='cardValue'><input type='text' class='cardValue'><!--Ca fonctionne avec ces input-->
    </form>
</body>

</html>

5 réponses


Stéphane Belazouz
Réponse acceptée
<!DOCTYPE html>
<html lang="fr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Affectation cartes</title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
</head>

<body>
    <script type='text/javascript'>
        $(document).ready(function() {
            $(".cardValue").on('keyup', function(e) {
                if (e.keyCode == 13) {
                    $(e.target).nextAll('.cardValue')[0]?.focus();
                }
            });

        });
    </script>
    <form id="myForm" action="" method="post">
        <?php
            $arrayStudents[] = array('id' => 111, 'name' => 'Luke');
            $arrayStudents[] = array('id' => 222, 'name' => 'Leia');
            $arrayStudents[] = array('id' => 666, 'name' => 'Anakin');

        $tabIndexValue = 1;
        foreach ($arrayStudents as $oneStudent) {

            echo "<label for='{$oneStudent['id']}'>{$oneStudent['name']} :</label>  <input type='text' id='{$oneStudent['id']}' class='cardValue' name='{$oneStudent['id']}' placeholder='{$oneStudent['name']}' /><br />";

            $tabIndexValue++;
        }
        ?>
        <input type='text' class='cardValue'><input type='text' class='cardValue'><!--Ca fonctionne avec ces input-->
    </form>
</body>

</html>

Explication :

La fonction next de jquery va regarder uniquement l'element qui suit l'element courant, si tu specifies un selecteur il prendra l'élément qui suit directement uniquement si le selecteur remplit la condition. Hors dans ton code l'element suivant est un <br /> et ne répond donc pas au critère. Le ciblage s'arrête donc.

cf : https://api.jquery.com/next/ : Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector.

Dans ma proposition j'utilise nextAll() pour récuperer tout les éléments qui suivent l'input courant avec le selecteur '.cardValue' et j'active le focus sur le premier qui arrive.

cf : https://api.jquery.com/nextAll/

NB : le dernier input n'aura pas d'élément suivant dans le tableau, je rend donc optionel l'éxécution du focus.

Autres remarques :

"Donc il y a bien un problème avec le fait que mes input proviennent d'une boucle, mais je ne sais comment régler ça.
Je comprends le truc par le fait que ma page doit avoir fini de charger avant que mon php ai généré mes inputs."

Je vulgarise un peu la chose :) mais contrairement à javascript coté client (le code javascript qui s'éxécute dans ton navigateur), le code PHP va "générer" intégralement l'html au naviguateur et une seul fois par appel de la page. En javascript tu peux éfféctivement "après chargement de la page" rencontrer ce type de problème si tu manipules le dom sans prendre soin qu'il ne soit entierement chargé. N'hésite pas à te documenter sur ces spécificitées, c'est assez important de les comprendres, c'est pourquoi je me permet de te le souligner.

Avec ton code il va manquer des guillemets autour du tabindex, ce qui casse peut être la structure HTML.

Wyllou
Auteur

Non malheureusement j'ai testé, mais ça ne change rien :/

Wyllou
Auteur

Ah ok.
Super ça fonctionne.
Effectivement je pensais que le fait d'indiquer la classe sur le next ciblait que ces éléments là.
Du évidemment nextAll c'est good.
Merci beaucoup.

C'est donc le ? après le [0] qui détermine que c'est optionnel. Je ne connais pas.

Wyllou
Auteur

Cool, merci Stéphane.
C'est mon problème de petit développeur qui est passé à Jquery par besoin de faire de l'ajax sans avoir mis la tête dans JS.
Bouuu pas bien.
Un grand merci en tout cas.