jhenner
Messages postés5Date d'inscriptionmardi 16 mars 2004StatutMembreDernière intervention 4 mai 2018
-
2 mai 2018 à 09:50
jhenner
Messages postés5Date d'inscriptionmardi 16 mars 2004StatutMembreDerniè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.
..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 :)
Reivax962
Messages postés3671Date d'inscriptionjeudi 16 juin 2005StatutMembreDernière intervention11 février 20211 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
jhenner
Messages postés5Date d'inscriptionmardi 16 mars 2004StatutMembreDerniè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 ?
Reivax962
Messages postés3671Date d'inscriptionjeudi 16 juin 2005StatutMembreDernière intervention11 février 20211 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)
jhenner
Messages postés5Date d'inscriptionmardi 16 mars 2004StatutMembreDerniè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é.
jhenner
Messages postés5Date d'inscriptionmardi 16 mars 2004StatutMembreDerniè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/
2 mai 2018 à 10:09
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 ?
2 mai 2018 à 10:12
Modifié le 2 mai 2018 à 11:22
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é.
Modifié le 4 mai 2018 à 17:29