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

JavaScript Discussion :

Transformer un prompt en boite modale


Sujet :

JavaScript

  1. #1
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut Transformer un prompt en boite modale
    Bonjour,

    je créé un jeu dans lequel le joueur doit trouver des éléments sur une image.
    Pour répondre, il écrit sa réponse.
    Pour cela, j'ai utilisé un prompt.
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
      const result = prompt("Entre le nom du jeu :" , "");

    J'aimerais qu'il prenne la même forme que la boite de dialogue déjà mis en place :

    Dans le css, j'ai mis exactement tes choix (je veux d'abord comprendre comment afficher avant de modifier les paramètres):
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    /*CSS boite de dialogue*/
    dialog {position: fixed;top: 40%;left: 50%;margin: 0;padding: 1em 2em 0;min-width: 20em;border: 2px solid #1A4;text-align: center;box-shadow: 0 0 0.5em #000;transform: translate(-50%, -50%);}
    dialog button {margin: .5em 0 .5em;padding: .5em 2em;border: 0;border-radius: 4px;text-shadow: none;font-size: inherit;outline-color: #6F9;outline-offset: 2px;color: #FFF;background-color: #1A4;background-image: none;box-shadow: 0 0 1em #888;transition: none;cursor: pointer;}
    dialog button:not(:disabled):hover {color: #FFF;background-position: 0;}
    dialog button:focus-within {outline: 2px solid #6F9;}

    Dans le html :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /*Boite de dialogue*/
     
    <dialog id="modal-info">
        <p class="modal-header">Vous avez cliqué sur :</p>
        <p class="modal-content"></p>
        <p class="modal-footer"><button data-role="close">Fermer</button></p>
      </dialog>


    et dans le script,
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (result === elClicked["dataset"]["id"]) {
     
        const msg = "Bravo, c'était bien "+ elClicked["dataset"]["id"];
      showModal(msg);

    - et enfin la définition de la fonction d'affichage
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /*Création de la boite de dialogue*/
    function showModal(html) {
      modal.querySelector(".modal-content").innerHTML = html;
      modal.showModal();
    };
     
    this.modal = document.getElementById("modal-info");
      const btnClose = modal.querySelector("[data-role='close']");
      btnClose.addEventListener("click", () => {
        modal.close();
      });

    Je me demande, si je peux réutiliser la même boite de dialogue pour remplacer mon prompt en mettant input="text"Du coup, j'ai repris mes éléments comme ceci :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <dialog id="modal-question">
        <p class="modal-header2">Quelle est l'anecdote derrière cet élément ?</p>
        <p class="question2"></p>
        <p class="modal-footer"><button data-role="close">Fermer</button></p>
      </dialog>

    Pour remplacer prompt("Entre le nom du jeu :" , "");, j'ai mis
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      let question = 
    showModal2(question);

    et j'ai défini
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /*Création de la boite de dialogue prompt*/
    function showModal2(html) {
      <input class="question2" type="text" />
      modal.querySelector(".question2").innerHTML = html;
      modal.showModal2();
    };
     
    this.modal = document.getElementById("modal-question");
      const btnClose = modal.querySelector("[data-role='close']");
      btnClose.addEventListener("click", () => {
        modal.close();
      });

    Evidemment, cela ne fonctionne pas, cela empêche même de cliquer dans les area ainsi que l'affichage des vies restantes.

    Une idée de mon erreur?
    Merci par avance.

  2. #2
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    Je me rends compte que je n'ai déjà pas défini de button OK et que sans ça, je ne risque pas d'arriver à valider un quelconque renseignement.

    Vu que rien ne s'affiche je me dis que je n'ai pas bien défini ma requête.
    Pourtant la fonction showModal2(question) devrait se lancer au clic vu qu'elle est contenu dans la fonction fonctionSurClicJe ne vois pas ce qui l'empêche de se lancer quand bien même je ne pourrai pas y répondre.
    Une idée?

  3. #3
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    Bonjour,
    ... pour commencer et en vrac ...
    Je me demande, si je peux réutiliser la même boite de dialogue pour remplacer mon prompt en mettant input="text"
    C'est une question de feeling et surtout de besoin.
    J'ai vu que certains t'ont proposé des solutions que tu n'as pas mises en oeuvre.

    Je ne résiste donc pas à l'envie de te soumettre une façon de faire :
    Custom modal, si cela peut servir.

    J'aimerais qu'il prenne la même forme que la boite de dialogue déjà mis en place :
    Là c'est du cosmétique et le CSS sert à cela.


    Evidemment, cela ne fonctionne pas,
    Pas surprenant au vu de ce que tu as écris, mélange JavaScript et HTML.

    Rappel pour démarrer :
    Il faut bien être conscient que des appels à alert, confirm et prompt sont des « appels bloquants », le script attend avant de passer à la suite. Cela n'est pas le cas avec les modales, et avec rien d'autres d'ailleurs.
    Avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    alert("Message à afficher")
    console.log("alert cliquée !");
    ... « alert cliquée » ne s'affichera dans la console qu'une fois la boîte d'alert validée.

    Avec le code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    elemDialog.showModal();
    console.log("Modale cliquée !");
    ... « Modale cliquée » s'affichera avant une quelconque action sur la boîte modale ne soit effectuée.

    Tout cela pour dire que tu ne peux pas gérer les événements comme avec des alert, confirm et prompt classiques, événements synchrones.

    Pour pallier à cela on a recours à une fonction de rappel, ou callback, et qui s'effectuera donc en mode asynchrone.

    On peut « simuler » le comportement de la façon suivante, ce n'est qu'une solution parmi d'autres, en utilisant un formulaire et en se servant de son événement onsubmit, pour gérer les actions à effectuer.

    On va créer l'élément dialog-prompt comme suit :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <dialog id="dialog-prompt" class="dialog-modal dialog-form">
      <form id="saisie-jeu" method="dialog">
        <div class="dailog-main">
          <p class="dialog-header">Entrer le nom du jeu :</p>
          <p class="dialog-body"><input type="text" name="nom" value=""></p>
          <p class="dialog-footer">
            <button class="btn-accept" data-role="accept">Valider</button>
            <button class="btn-cancel" data-role="cancel">Annuler</button>
          </p>
        </div>
      </form>
    </dialog>

    On crée une fonction que l'on va appeler getSaisie, à la quelle on passera l'élément area cliqué :
    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
    function getSaisie(area) {
      // récup. des éléments
      const modalSaisie = document.getElementById("dialog-prompt");
      const formSaisie = modalSaisie.querySelector("FORM");
      // remise à zéro des champs
      formSaisie.reset();
      // pas de addEventListener ici
      formSaisie.onsubmit = function(e) {
        e.preventDefault();
        // si bouton valider
        if ("accept" === e.submitter.dataset.role) {
          traiteValeur(formSaisie, area);
        }
        // on ferme
        modalSaisie.close();
      }
      // on affiche
      modalSaisie.showModal();
    }
    On notera que la fonction traiteValeur, à définir, va s'occuper du traitement et donc que cette partie va disparaître de la fonction fonctionSurClic.

    Maintenant il faut bien appeler la fonction getSaisie et c'est dans la fonction fonctionSurClic que cela va se faire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function fonctionSurClic(e) {
      // récup. élément cliqué
      const elClicked = e.target;
      const imgFond = document.getElementById("img-fond");
      if (imgFond.classList.contains("img-disabled")) {
        setStateImageFond(true);
        return;
      }
      // demande à utilisateur
      getSaisie(elClicked);
    }
    C'est tout pour cette fonction, l’enchaînement se fera getSaisie -> [SUBMIT] -> traiteValeur.

    Il reste à définir la fonction traiteValeur qui va reprendre ce qui a été supprimé dans la fonction fonctionSurClic.
    Cela pourrait ressembler à :
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    function traiteValeur(form, area) {
      // récup. de la saisie
      const elemSaisie = form.querySelector("[name='nom']");
      const nomJeu = elemSaisie.value.trim();
      const reponse = area.dataset.nom;
      // le test
      if (reponse === nomJeu) {
        // bingo gagné !
        compt += 10;
        // ajout création d'un point sur l'image
        addPointOnImage(area);
        // mise à jours core
        document.getElementById("champDuPrompt").innerHTML = compt;
        // (1) suppression de l'écouteur
        area.removeEventListener("click", fonctionSurClic);
        // affichage message
        const msg = "Super, <b>" + nomJeu + "</b><br>est une bonne réponse !";
        showModal(msg);
      }
      else {
        // fiasco perdu !
        let msg;
        vie -= 1;
        // mise à jour affichage nbr vies
        setNbrVies(vie);
        document.getElementById("nbdevies").innerHTML = vie;
        // traitement résultat
        if (vie == 0) {
          msg = "GAME OVER";
        }
        else {
          msg = "Il ne vous reste plus que " + vie + " vies";
        }
        // affichage message
        showModal(msg);
      }
    }
    Il ne te reste plus qu'à analyser, comprendre le principe et intégrer le total
    moi je vais prendre un cachet

  4. #4
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    Ah ok.

    En fait j'essayais de recréer une deuxième fonction d'affichage (ce qui est inutile) alors qu'il fallait décomposer le prompt en deux sous-fonctions (une pour la saisie de la réponse et une qui traite la réponse donnée et la compare aux nom des area.
    J'y étais pas du tout. Mais j'ai compris, globalement le sens de ce que tu as fait, même s'il a fallut que je cherche ce qu'était :
    - form- method- preventDefault- .value.trimet je suis pas sur d'avoir tout saisit. Mais au moins, je découvre des choses.
    Merci encore.

  5. #5
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    J'ai à présent une autre question qui va dans la continuité de celle-ci. Mes 2 boites de dialogue sont prêtes dialog id="modal-info" et dialog id="dialog-prompt".
    Dans la première, j'ai un modal-header qui renvoie "Vous avez cliqué sur". Or dans le cas où la réponse est erronée, cela donne :

    "Vous avez cliqué sur"
    " Il ne vous reste plus que 2 vies"

    Je trouve que c'est bizarre, d'où ma question. Est-il possible de supprimer le modal-header dans le cas où la réponse est fausse.

    Si ce n'est pas possible, dois-je créer 2 boites de dialogue distinctes, une pour les bonnes réponses et un pour les mauvaises?

    Merci par avance

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    Ton élément <p class="modal-header">Vous avez cliqué sur :</p> est prêt à recvoir le HTML que tu veux, il te suffit de faire un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    modal.querySelector(".modal-header").innerHTML = titre;
    Ceci étant tu as la possibilité de supprimer cet élément et de passer en paramètre le titre avec le message.

    Donc sans rien changer à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function showModal(html) {
      modal.querySelector(".modal-content").innerHTML = html;
      modal.showModal();
    };
    faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const msg = "<b>BRAVO</b><br><b>" + nomJeu + "</b><br>est une bonne réponse !";
    showModal(msg);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const msg = "<b>PERDU</b><br>Il ne vous reste plus que " + vie + " vies";
    showModal(msg);

    Autre solution, en gérant un titre, la fonction devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function showModal(titre, html) {
      modal.querySelector(".modal-header").innerHTML = titre;
      modal.querySelector(".modal-content").innerHTML = html;
      modal.showModal();
    };
    et dans ce cas cela s'utilise comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const title = "<span class='bingo'>BRAVO</span>";  // stylé directement en CSS
    const msg = "<b>" + nomJeu + "</b> est une bonne réponse !";
    showModal(title, msg);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const title = "<span class='error'>PERDU</span>";  // stylé directement en CSS
    const msg = "Il ne vous reste plus que " + vie + " vies";
    showModal(title, msg);
    Je préfère cette deuxième solution mais c'est une affaire de goûts.

  7. #7
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2018
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2018
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    Merci beaucoup,
    j'ai opté pour la solution 2, en modifiant la petite erreur, dans la fonction du définis titre et quand tu l'appelles tu as mis title.

  8. #8
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 048
    Points : 44 562
    Points
    44 562
    Par défaut
    en modifiant la petite erreur, dans la fonction du définis titre...
    Il y avait bien une erreur mais pas celle que tu croyais. Dans le dernier code il fallait lire showModal(title, msg) et non showModal(msg), c'est corrigé !


    Attention ne pas confondre le nom de la variable passée à la fonction et le nom du paramètre utilisé dans la fonction, ils peuvent être différents et le sont souvent.

    Soit la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function nomDeLaFonction(a) {
      console.log(a);
    }
    peut être appelée comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const maVariable = "Bonjour vous !";
    nomDeLaFonction(maVariable);
    // ou encore
    nomDeLaFonction("Bonjour vous !");
    Le résultat sera le même en console.

    On aurait pu faire encore pire avec par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function nomDeLaFonction() {  // pas de nommage des paramètres
      console.log(arguments[0]);
    }
    ... ou encore ... non j'arrête cela va embrouiller

    Dans un premier temps, je te recommande la lecture, facile, de Déclaration de fonction pour y voir plus clair !

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

Discussions similaires

  1. Boites modales, ça fonctionne, mais pourquoi?
    Par Guyt54 dans le forum Android
    Réponses: 2
    Dernier message: 12/05/2012, 14h55
  2. Affichage de quelques lettres dans un TextArea ou boite modale
    Par hamzawhy dans le forum Débuter avec Java
    Réponses: 8
    Dernier message: 14/02/2012, 22h08
  3. Réponses: 3
    Dernier message: 26/11/2010, 10h14
  4. transformer un code en boite de dialogue
    Par bourgui78 dans le forum Tkinter
    Réponses: 4
    Dernier message: 25/08/2008, 08h58
  5. [MFC] Probleme d'affichage avec boite modale
    Par kitsune dans le forum OpenGL
    Réponses: 2
    Dernier message: 04/09/2007, 06h53

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