IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

jQuery Discussion :

Ajax/Jquery créer de nouveaux éléments : comment attacher les listeners par défaut ? [AJAX]


Sujet :

jQuery

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 396
    Points : 396
    Points
    396
    Par défaut Ajax/Jquery créer de nouveaux éléments : comment attacher les listeners par défaut ?
    Bonjour,

    Je fais un appel Ajax dans du code Jquery, qui ressemble à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $.ajax({
    	type: 'POST',
    	dataType: 'json',
    	url:  '/evenement/updateAgenda.php',
    	data: { agenda_id: agenda_id, selection: 'duplicate' },
    	success: function(data) {
    		clone = tr.clone();
    		// Actualise l'ID de l'élément dupliqué
    		clone.attr('id', data.id);
    
    		table.append(clone);
    	}
    });
    Cette dernière instruction me créé un nouvel élément <tr> qui contient des <input>, et sur ces input, j'ai des listeners qui ressemblent à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $('input').click(function() {
      // etc.
    });
    Mon problème est que le listener n'est pas exécuté pour les nouveaux input créés dynamiquement. Je pense qu'il s'agit d'un problème classique de javascript mais je n'arrive pas à y trouver une solution.

    Merci de votre aide !

  2. #2
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Comme toujours : il suffit de lire la doc : .on()
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 396
    Points : 396
    Points
    396
    Par défaut
    Merci (malgré la condescendance, car souvent lorsqu'on connait peu un langage, le problème de la doc est parfois de savoir quoi chercher).

    Du coup, en remplaçant mon code par ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    function statut_changed() {
    	// etc.
    };
    $('.prog_etat').on('click', statut_changed);
     
    // ... 
    success: function(data) {
    	clone = tr.clone();
    	clone.attr('id', data.id);
     
    	if (clone.attr('class') == 'prog_etat') {
    		clone.on('click', statut_changed);
    	}
    	if (clone.attr('class') == 'prog_etat' && clone.val() == 'reporte') {
    		// etc.
    	}
    	// etc.
     
    	table.append(clone);
    }
    tout marche nickel. Par contre, je trouve qu'il y a une redondance de déclaration des listeners très moche en implémentant cette solution. Y aurait-il une solution plus propre ?

  4. #4
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Ca va peut-être te paraitre condescendant (), mais il semble que tu n’aies pas tout lu. Notamment ce qui concerne le rôle du paramètre selector...
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 396
    Points : 396
    Points
    396
    Par défaut
    J'avais lu ça, mais au premier coup d'oeil je n'avais pas eu l'impression que ça me servait. Par contre, du coup effectivement ça me permet de pallier à mes conditionnelles ; mais je suis toujours obligé de dupliquer la déclaration de mes listeners.

    Le mieux que j'ai trouvé à faire, c'est de déclarer une fonction d'initialisation des listeners, et de la rappeler lors du success. Ça fait la même chose en plus propre, mais je suis étonné que cela ne se fasse pas de base sans mention explicite.

    Merci en tout cas de m'avoir indiqué le "on()" !

  6. #6
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Non. Tu n'as pas compris le rôle des événements délégués !
    Le principe est de poser le gestionnaire sur un ancêtre commun et de préciser à quelles balises doit s'appliquer le gestionnaire.
    Le but : soit n'avoir à utiliser qu'un seul gestionnaire pour plusieurs éléments, soit pouvoir créer des gestionnaires pour des éléments n'existant pas encore.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $('#conteneur').on('click', 'input', callback);
    Dans cet exemple, la balise ayant l'id conteneur reçoit un gestionnaire d'événement.
    Lorsque cet événement est déclenché, la fonction vérifie si l'élément qui a déclenché l'événement est bien de type <input>, si c'est le cas, alors la fonction callback est exécutée.
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 396
    Points : 396
    Points
    396
    Par défaut
    Ok. Après avoir tourné un peu en rond pour réaliser la portée de cet "ancêtre commun", je vois que cette solution contourne le problème des éléments nouvellement créés puisqu'il repose sur un gestionnaire d'un élément pérenne.

    Je me retrouve donc avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $('#listAgenda').on('click', '.prog_etat', reportDateActualisation);
    $('#listAgenda').on('click', '.prog_etat', saveProgEtat);
    $('#listAgenda').on('change', '.heuredebut, .heurefin, .report_date', saveInput);
    $('#listAgenda').on('click', '.duplique', duplicateAgenda);
    $('#listAgenda').on('click', '.delete', deleteDate);
    sans avoir à attacher nulle part d'autre (comme les input créés à la volée) d'événement sur mes éléments. Donc c'est parfait, merci beaucoup

  8. #8
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 637
    Points : 66 661
    Points
    66 661
    Billets dans le blog
    1
    Par défaut
    c'est rationalisable ...
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 396
    Points : 396
    Points
    396
    Par défaut
    Que veux-tu dire ? Qu'on peut mutualiser ce code pour les deux événement attachés à prog_etat ?

    Si il s'agit de ça, c'est un choix volontaire pour avoir un code un peu plus clair.

  10. #10
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 637
    Points : 66 661
    Points
    66 661
    Billets dans le blog
    1
    Par défaut
    non pour les evenements aussi
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  11. #11
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    A part regrouper les deux premiers et chainer les suivants, j'avoue que je ne vois pas trop...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $('#listAgenda').on({
        'click': reportDateActualisation,
        'click': saveProgEtat
    }, '.prog_etat', )
      .on('change', '.heuredebut, .heurefin, .report_date', saveInput)
      .on('click', '.duplique', duplicateAgenda)
      .on('click', '.delete', deleteDate);
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    396
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 396
    Points : 396
    Points
    396
    Par défaut
    Exact, merci. Je n'ai pas encore le réflexe du chaînage (bien pratique) à outrance sur jquery.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 02/12/2014, 17h34
  2. Comment changer les noms par défaut d'un objet ?
    Par zoltix dans le forum PowerAMC
    Réponses: 1
    Dernier message: 06/01/2011, 02h08
  3. Réponses: 3
    Dernier message: 09/02/2010, 20h01
  4. Réponses: 1
    Dernier message: 18/06/2008, 15h28
  5. Réponses: 9
    Dernier message: 13/06/2005, 17h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo