3 votes

Foundation6 reveal popup form field unwanted focus lost (in jQuery events ?)

Je suis en train de coder un formulaire popup en utilisant Foundation6 reveal. Je suis confronté à un problème JavaScript que j'ai retracé et qui a probablement quelque chose à voir avec la liaison ou la gestion des événements de jQuery.js / Foundation.js.

screenshot from codepen

Lorsque je clique sur le champ de texte (ou tout autre champ) dans la fenêtre d'affichage, le champ reçoit le focus, puis la fenêtre d'affichage se cache et se réaffiche rapidement et le champ a perdu le focus. La fenêtre d'affichage change également de position sur l'écran. La seule façon d'accéder aux champs de texte est d'utiliser la touche de tabulation.

index.html :

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.2.4/foundation.css"/>    
        <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.2.4/foundation.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        <script src="app.js"></script>   
    </head>
    <body>
        <section class="container clearfix">
            <h3>Click button to open modal and test focus lost problem:</h3>
            <p><a href="modalform.html" class="button" data-open="newFormModal" data-showloading="1">Test focus modal form</a></p>
        </section>
        <div class="reveal" id="newFormModal" data-reveal data-close-on-click><section class="modalContent"></section><button class="close-button" data-close aria-label="Close reveal" type="button"><i class="fi-x"></i></button></div>
    </body>
</html>

modalform.html

<h3 class="modalheader">PopupForm</h3>
<form method="post" accept-charset="utf-8" class="ajaxModal" data-showloading="1" data-open="newFormModal" action="/test/modalform3">
  <div style="display:none;"><input type="hidden" name="_method" value="POST" /></div>
  <div class="input text"><label for="ga-20x28">Product 1 qty:</label><input type="text" name="ProductQuantities[726][value]" id="ga-20x28" value="0" /></div> <input type="hidden" name="ProductQuantities[726][name]" value="GA 20x28" />
  <div class="input text"><label for="ga-30x40">Product 2 qty:</label><input type="text" name="ProductQuantities[727][value]" id="ga-30x40" value="0" /></div> <input type="hidden" name="ProductQuantities[727][name]" value="GA 30x40" />
  <div class="input text"><label for="ga-50x70">Product 3 qty:</label><input type="text" name="ProductQuantities[728][value]" id="ga-50x70" value="0" /></div> <input type="hidden" name="ProductQuantities[728][name]" value="GA 50x70" />
<button type="submit">Next</button>
</form>
<button data-close="" class="refreshId" type="submit">Close</button>

app.js :

$(document).ready(function() {

    $(document).foundation();

    $("body").on("click", "a[data-open]", function(e) {
        e.preventDefault();

        var $this = $(this);
        var modalName = $this.data("open");
        var $modal = $("#" + modalName);
        var $target = $modal.children(".modalContent");
        var requestUri = $(this).attr('href');
        var requestData;
        var method;
        if($this.attr('data-request')) {
            requestData = $(this).data("request");
            method = 'POST';
        } else {
            requestData = "";
            method = 'GET';
        }

        // Load content:
        var request = $.ajax({
            url: requestUri,
            method: method,
            data: requestData,
            dataType: "html",
            timeout: 60000
        });

        request.done(function(response) {
            $target.html(response);
            $target.foundation();
        });
    });
});

Vous pouvez y tester le comportement (du moins sur mes navigateurs Firefox et Chrome) : [ http://codepen.io/repeat_spacer/pen/bBRZKd ][1] . Ouvrez la fenêtre popup de révélation à partir du bouton et essayez de modifier la valeur d'un champ de texte. Il n'est pas possible d'entrer dans le champ avec un clic de souris.

J'espère que quelqu'un pourra m'indiquer le problème ou comment continuer à le tracer.

UPDATE :

J'ai nettoyé le code de modalform.html (il y a un truc ajax qui révèle le chargement d'un nouveau formulaire, j'y ai mis le chargement du formulaire suivant par ajax). Donc maintenant la fonctionnalité "load next form" ne fonctionne pas, mais d'un autre côté le comportement "focus lost" a disparu.

modalform_updated.html :

<h3 class="modalheader">PopupForm</h3>
<form method="post" accept-charset="utf-8" class="ajaxModal" action="submitmodal.php">
  <div style="display:none;"><input type="hidden" name="_method" value="POST" /></div>
  <div class="input text"><label for="p1qty">Product 1 qty:</label><input type="text" name="ProductQuantities[p1][value]" id="p1qty" value="0" /></div>
  <div class="input text"><label for="p2qty">Product 2 qty:</label><input type="text" name="ProductQuantities[p2][value]" id="p2qty" value="0" /></div>
  <div class="input text"><label for="p3qty">Product 3 qty:</label><input type="text" name="ProductQuantities[p3][value]" id="p3qty" value="0" /></div>
  <button type="submit">Submit</button>
</form>
<button data-close="" class="refreshId" type="submit">Close</button>

Mise à jour du codepen : http://codepen.io/repeat_spacer/pen/MbrYvj

UPDATE 2 :

Voici la raison pour laquelle je dispose de data-open (Foundation Reveal open-attribute) dans les attributs de formulaire. Il semble être à l'origine du comportement car il déclenche l'événement Foundation Open lorsqu'un champ du formulaire est cliqué. La solution rapide serait donc de le filtrer d'une manière sale.

Voici fiddler avec la fonctionnalité multi popup que je veux avoir : http://codepen.io/repeat_spacer/pen/JbMdPm (la première popup modale charge par ajax le contenu de la popup suivante dans la même modale)

2voto

Repeat Spacer Points 116

Ok, j'ai réussi à le faire fonctionner. Comme je m'en doutais, le problème se situait au niveau de la liaison entre les événements de la Fondation.

Je pensais à une généralité fantaisiste, quand j'ai ajouté data-open="modalName" dans les attributs du formulaire pour indiquer dans quelle modale je veux qu'Ajax charge la page modale suivante (tout comme je dois le faire dans le premier bouton pour révéler la fenêtre modale).

Maintenant, quand le data-open est dans les attributs du formulaire, il déclenche l'événement reveal open chaque fois que l'on clique sur un élément du formulaire. L'événement fermera toutes les révélations et ouvrira ensuite la révélation dont l'identifiant se trouve dans l'attribut data-open, ce qui entraîne la perte du focus.

J'ai maintenant enregistré le nom de la modale en data-modalname et tout fonctionne comme prévu.

Modification HTML :

<form method="get" accept-charset="utf-8" class="ajaxModal" data-showloading="1" data-modalname="this" action="modalform2.html">

Et ensuite changer le gestionnaire d'événement en JS pour lire le nom de la modale à partir de là.

CodePen fonctionnel : http://codepen.io/repeat_spacer/pen/QGazJj

1voto

kball Points 689

Je pense que le problème que vous rencontrez ici est le fait que vous placez votre gestionnaire d'événement sur body ce qui signifie qu'il sera exécuté chaque fois qu'un élément de la page sera cliqué. Le fait de cliquer dans la fenêtre d'affichage déclenche le gestionnaire d'événement, qui rouvre la modale d'affichage, ce qui perturbe le focus.

Pour résoudre ce problème, attribuez votre gestionnaire de clic à un autre élément de la page. Ou si vous voulez VRAIMENT l'avoir sur le corps, faites quelque chose pour vérifier si oui ou non la révélation est déjà ouverte avant de la déclencher... à la manière de

$("body").on("click", "a[data-open]", function(e) {
   if($('body').hasClass('is-reveal-open')) { return; }
   // rest of handler
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X