On('click', 'monbouton', function(){}

Résolu/Fermé
jhenner Messages postés 5 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 4 mai 2018 - 2 mai 2018 à 09:50
jhenner Messages postés 5 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 4 mai 2018 - 4 mai 2018 à 17:26
Bonjour,

Je suis en train de travailler sur un gestionnaire d'habilitation qui va permettre aux utilisateurs enregistrés d'accéder à une ou plusieurs applications en ligne.

J’ai créé un formulaire qui permet de sélectionner un utilisateur d'autoriser son accès à une application web.
Le formulaire est on ne peut plus simple et tous les échanges avec la base de données s’effectuent avec AJAX.


Mon formulaire

Dans mon formulaire j'ai :

Un évènement attaché à un menu déroulant (bootstrap-select) qui permet de sélectionner un utilisateur et de récupérer de la table sql des utilisateurs les informations dont j'ai besoin.

<div class="container">
    <h1>Ajouter un utilisateur</h1>
    <div id="addform" class="col-lg-6">
        <form action="#" class="form-horizontal" enctype="application/x-www-form-urlencoded">
            <div class="form-group">
                <label class="control-label col-lg-4" for="identite">Identifiant : </label>
                <div class="col-lg-8">
                    <select id="idselection" class="selectpicker" data-live-search="true" title="Matricule/Nom" data-width="auto">
                        <option selected disabled ></option>
                        <?php foreach ($userslist as $item): ?>
                        <option value="<?= $item->matricule; ?>" ><?= $item->nom; ?> <?= $item->prenom; ?> <?= $item->matricule; ?></option>
                        <?php endforeach; ?>
                    </select>
                </div>
            </div>
        </form>
        <div id="user" data-app="<?= is_numeric($this->request->params[0]) ? $this->request->params[0] : null; ?>"></div>
    </div>
</div>


Le résultat de la requête est affiché dans le div#user par chargement d'un fichier php userprofile.php dans lequel j'insère les informations :

<div class="userprofilebox">
    <div class="input-group">
        <span class="input-group-addon">NOM : </span>
        <p id="nom" class="form-control"></p>
    </div>
    <div class="input-group">
        <span class="input-group-addon">PRENOM : </span>
        <p id="prenom" class="form-control"></p>
    </div>
    <div class="input-group">
        <span class="input-group-addon">MATRICULE : </span>
        <p id="matricule" class="form-control"></p>
    </div>
    <div class="input-group">
        <span class="input-group-addon">SERVICE : </span>
        <p id="service" class="form-control"></p>
    </div>
    <div class="row">
        <button id="validate" class="btn btn-success" type="button" value="" ><span class="glyphicon glyphicon-ok"></span> Habiliter</button>
        <a class="btn btn-danger" href="<?= WEBROOT; ?>/app/liste" target="_parent" title="Retour à la liste des applications" ><span class="glyphicon glyphicon-remove"></span> Abandon</a>
    </div>
</div>


..et je clique sur le bouton Habiliter pour enregistrer cette nouvelle habilitation.

Mon Jquery :

$(function () {

	// Selection de l’utilisateur

    $("#idselection").on('changed.bs.select', function (e) {
    	    var identifiant = $(this).val();
        	function reponse(callback) {
                  $.ajax({
                          url: "applications/activedirectory/PHPScripts/ajax-get-user", // requete sur table des utilisateurs
                          method: "post",
                          data: {ref: identifiant},
                          dataType: 'JSON'
                  })
                    .done(function (data, textStatus, jqxhr) {
                        	callback(data);
                    })
                    .fail(function (jqxhr) {
                        	callback(jqxhr.responseText);
                    });
        	}

// Résultat de la requête est affiché dans la page  userprofile.php chargée dans un div (J'avais la flemme de générer du DOM)
            reponse(function (data) {
                	var app = $("#user").data('app');
                    $("#user")
                                      .load('userprofile', function (e) {
                                              $(this).find('#nom').text(data.nom);
                                              $(this).find('#prenom').text(data.prenom);
                                              $(this).find('#matricule').text(data.matricule);
                                              $(this).find('#service').text(data.service);
                                              $(this).find('#validate').attr('value', data.matricule); // Bouton de validation 
                                      })

					// Click sur le bouton de validation
                						.on('click', 'button#validate', function (e) {
                    							function calling(callback) {

														// Requête INSERT dans la table des habilitations
                                                        $.ajax({
                                                            url: "applications/activedirectory/PHPScripts/ajax-add-user", 
                                                            method: "post",
                                                            data: {app: app, ref: identifiant},
                                                            dataType: 'JSON'
                                                        })
                                                        
                                                          .done(function (data, textStatus, jqxhr) {
                                                              callback(data);
                                                          })

                                                          .fail(function (jqxhr) {
                                                              callback(jqxhr.responseText);
                                                          });
                    					}


	       							// Affichage d’un message (erreur ou succès)
                                      calling(function (data) {
                                          var msg = "<div class='col-lg-12 alert alert-info'>";
                                          msg += "<button type='button' class='close' aria-label='Close' data-dismiss='alert'><span aria-hidden='true'>×</span></button>";
                                          msg += "<h4>Message</h4>";
                                          msg += "<p>" + data +"</p>";
                                          msg += "</div>";

                                          $("#user").before(msg);
                                      });
                			});
        		});
    	})
});


Ce que j'obtiens :

Tous fonctionne à merveille (hormis les messages mais ça c'est un détail) ! Sauf… que dans la console du navigateur je vois apparaître l’impensable ! l’inimaginable !

Dans mon formulaire je sélection un utilisateur, les informations s'affichent, je clique sur le bouton button#validate, il est enregistré dans la table des utilisateurs habilités.

Je continue, je sélectionne un autre utilisateur, les informations de ce nouvel utilisateur remplacent les précédentes, je clique sur le bouton button#validate, il est enregistré.

etc.. donc je suis content !

MAIS !

Voilà ce qu'il se passe lorsque je surveille l'activité dans la console du navigateur -> network onglet XHR

Premier utilisateur : une requête vers ajax-add-user.php

Deuxième utilisateur : je vois 2 requêtes vers ajax-add-user.php ( l' utilisateur précédent suivi du nouveau)

Troisième : je vois 3 requêtes vers ajax-add-user.php… (les deux utilisateurs précédents suivis du nouveau).

etc..


Ma seule piste c’est la délégation du click sur le bouton #validate.


Pour l'heure j'ai réécrit le code jquery différemment en séparant les évènements **change** et **click**

$(function(){
		$("#idselection").on('changed.bs.select', function (e) {...}
        $(#user).on('click', 'button#validate', function (e) {..}
});



C'est moche mais ça fonctionne aussi.
Si quelqu'un pouvait m'expliquer d’où vient cette démultiplication du contenu de l'évènement *CLICK*, et pourquoi, ça serait simpa :)





--
A voir également:

1 réponse

Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
2 mai 2018 à 10:04
Bonjour,

Ce bout de code
					// Click sur le bouton de validation
                			.on('click', 'button#validate', function (e) {

est placé à l'intérieur du callbak défini là
reponse(function (data) {
.

Donc chaque fois que tu changes ton Select tu as un événement supplémentaire qui s'ajoute au bouton Valider :)

Xavier
1
jhenner Messages postés 5 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 4 mai 2018
2 mai 2018 à 10:09
Merci beaucoup pour ta réactivité et ta réponse !
Donc si je comprend bien ça signifie que les valeurs précédentes stockées dans les variables ne sont pas "oubliées" et s'affichent à nouveau dans la console ?
0
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
2 mai 2018 à 10:12
Cela signifie que le callback est rajouté à chaque fois à ton bouton, avec les valeurs qui lui sont données. Il faudrait mettre un point d'arrêt et le jouer dans un débugger pour voir exactement quelles sont les valeurs transmises, mais oui, je ne serais pas étonné qu'il garde en mémoire son contexte de déclaration (c'est à la fois le piège et la facilité de ces déclarations de fonctions à la volée dans des contextes fermés... Je préfère personnellement éviter les fonctions imbriquées dans des fonctions ou dans des callbacks pour, justement, éviter de me mélanger les pinceaux dans la portée des variables)
0
jhenner Messages postés 5 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 4 mai 2018
Modifié le 2 mai 2018 à 11:22
Grand merci à toi !

Pour info, dans la console du navigateur seule la valeur courante est transmise.
Je vais chercher une solution à ce problème, je la posterai dès que j'aurai trouvé.
0
jhenner Messages postés 5 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 4 mai 2018
Modifié le 4 mai 2018 à 17:29
Un article m'a été conseillé, il explique mon erreur (en anglais) : https://triangle717.wordpress.com/2015/12/14/js-avoid-duplicate-listeners/
0