Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Ajax] Garder la valeur du champ après une requête

Sujet résolu
    20 janvier 2020 à 16:43:45

    Bonjour,

    j'espère être au bon endroit. J'ai une requête Ajax qui vérifie lors de la perte de focus de l'input que le nom entré dans l'input n'est pas déjà utilisé.

    La requête vérifie et rafraichit systématiquement la page (je n'ai pas réussi à faire sans), avec un message d'erreur si le nom est déjà utilisé et sans message si le nom n'est pas déjà connu.

    J'ai actuellement deux problèmes (mais le deuxième est certainement lié au premier) :

    - lors du rafraichissement, il perd la valeur de l'input.

    - même en remplissant le formulaire et en complétant le champ en dernier, le formulaire ne se valide plus.

    Il s'agit d'une appli développée avec le framework Slim, mais je ne sais pas si le problème est lié à Ajax ou à Slim/PHP.

    ****

    autoFormForAdd.twig

        <div id="message" class="row container">
            <div class="row">
                <div class="col s10 offset-s1">
                    <div class="card blue-grey darken-1">
                        <div class="card-content white-text">
                            <span class="card-title"><i class="material-icons">report_problem</i>  Attention</span>
                            <p>Les champs marqués avec une <span class="option">*</span> sont facultatifs</p>
                        </div>
                    </div>
                </div>
                {% if message is defined %}
                    <div  class="col s10 offset-s1">
                        {# Si c'est une erreur #}
                        {% if message.etat == "ko" %}
                        <div class="card red darken-1">
                            {% else %}
                            <div class="card green darken-1">
                                {% endif %}
                                <div class="card-content white-text">
                                    <span class="card-title">Message</span>
                                    {{ message.retour }}
                                </div>
                            </div>
                        </div>
                    </div>
                {% endif %}
    
                {% if auto is defined %}
                <form class="col s12" id='form1' action="{{ path_for('administration-table-automates-mod-post') }}" method="post">
                    <input type="hidden" name="id" value="{{ auto.auto_id }}">
                    {% else %}
                    <form class="col s12" action="{{ path_for('administration-table-automates-add-post') }}" method="post">
                        {% endif %}
                        <div class="card">
                            <div class="card-content">
                                <span class="card-title">Informations générales</span>
                                <div class="row">
                                    <div class="input-field col s6">
                                        {% if auto is defined %}
                                            <input id="nom" name="nom" type="text" value="{{ auto.auto_nom }}" >
                                        {% else %}
                                            <input id="nom" name="nom" type="text" >
                                        {% endif %}
                                        <label for="nom">Nom</label>
                                    </div>
                                    <div class="input-field col s6">
                                        {% if auto is defined %}
                                            <input id="url" name="url" type="text" value="{{ auto.auto_detail }}">
                                        {% else %}
                                            <input id="url" name="url" type="text">
                                        {% endif %}
                                        <label for="url">URL<span class="option">*</span></label>
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="input-field col s12">
                                        {% if auto is defined %}
                                            <textarea id="description" name="description" class="materialize-textarea">{{ auto.auto_commentaire }}</textarea>
                                        {% else %}
                                            <textarea id="description" name="description" class="materialize-textarea"></textarea>
                                        {% endif %}
                                        <label for="description">Description<span class="option">*</span></label>
                                    </div>
                                </div>
                            </div>
                        </div>
    
                        //// ici suite du formulaire////
        </div>
    
    
        {% block script %}
    
    
            <script>
                document.querySelector('#add1').addEventListener('click', function(event) {
    
                    var last = document.querySelector('#Libelle tbody tr:last-child');
                    last.parentNode.appendChild(last.cloneNode(true));
    
                });
            </script>
    
            <script>
                document.querySelector('#add2').addEventListener('click', function(event) {
    
                    var last = document.querySelector('#Fichier tbody tr:last-child');
                    last.parentNode.appendChild(last.cloneNode(true));
    
                });
            </script>
    
            <script>
                function remplir(){
                    exp =/[a-zA-Z0-9_]\.[a-z]{3,4}$/;
                    exp1=/[&ïöîôâäûü\+\(\)\{\}\[\]é"'èçà=€@à$£ù%*§¤\*²;\?\!,<>^¨]/;
    
    
                    var elem = document.getElementsByClassName('auto_param1');
    
                    for (var i = 0; i < elem.length; i++) {
                        //remplace chaque espace par "_"
                        while(elem[i].value.includes(' ')){
                            elem[i].value = elem[i].value.replace(" ","_");
                        }
                        if (!exp.test(elem[i].value)){
                            alert('Le nom du fichier '+ (i+1) + ' est incorrect');
                        }
                        if (exp1.test(elem[i].value)){
                            alert('Le nom du fichier '+ (i+100) + ' est incorrect');
                        }
                    }
    
                }
    
    
            </script>
    
    
            <script>
                $(document).ready(function() {
                    $('select').material_select();
                });
            </script>
            <script type="text/javascript" src="{{ base_url() }}/js/formChecker.js"></script>
            <script src="{{ base_url() }}/js/selectAll-None.js"></script>
            <script src="{{ base_url() }}/js/infobulle.js"></script>
            <script>
                window.onload = function() {
                    sauvegardeCheck();
                    typeCheck();
                    eventListenerSelect();
    
                }
            </script>
    
    
    
    
            <script>
                document.querySelector('#nom').onfocus = function() {
                    checkNameAuto();
                }
            </script>
    
        {% endblock %}
    

    Le id="message" récupère et affiche la data du formChecker.js

    ****

    formChecker.js

    /**
     * Requête Ajax : Permettant le controle du nom de l'automate dans l'input
     * de façon interactive
     */
    function checkNameAuto() {
    
        // Recupération de l'input id=nom
        var inputName = document.getElementById('nom');
    
        // On attend que l'input perde le focus
        inputName.onblur = function (e) {
    
            //on récupère la valeur de l'input
            var name = inputName.value;
            //console.log(name);
    
            //on effectue la requête ajax
            $.ajax({
                type: "GET",
                url: "/administration/table/automates/form/checkName",
                data: {
                    nom: name
                },
                success: function (data) {
                    //console.log(data);
                    $('#message').html(data);
                }
            })
        }
    }
    
    
    

    ****

    AdministrationController.php

        /**
         * Controle que le nom de l'automate n'est pas déjà présent dans la table
         * @param Request $request
         * @param Response $response
         * @param $args
         * @return Response
         */
        public function ckeckNameNotDuplicated(Request $request, Response $response, $args)
        {
            //permet de savoir d'avoir un tableau des paramètres de la request
            //var_dump($request->getQueryParams());
    
            //décode le paramètre "nom" de l'url
            $name = urldecode($_GET["nom"]);
            //var_dump($name);
    
            // Recherche combien de fois le nom affiché dans le champs est présent dans la base de donnée
            $double = $this->modelAutomates->getCheckNameAutoDoublon($name);
            //var_dump($double);
    
            // S'il est déjà présent
            if ($double !== false) {
                // afficher message d'erreur
                $message = array();
    
                $message['etat'] = 'ko';
                $message['retour'] = "Vous ne pouvez pas utiliser ce nom - Nom déjà utilisé ";
                $this->logger->error($message['retour']);
    
    
                // rafraichissement de la page en cas d'erreur
                // Récupération des données
                $ordis = $this->modelAutomates->getOrdiListForForm();
                $saufAutos = $this->modelAutomates->getAutoListeCanUseFiles();
                $paramLibelleIE = $this->modelAutomates->getParamLib();
                // Rendu
                $this->view->render($response, "autoFormForAdd.twig", array(
                    "ordis" => $ordis,
                    "libelleIE" => $paramLibelleIE,
                    "autosSauf" => $saufAutos,
                    "message" => $message
                ));
    
                return $response;
            }
            //rafraichissement de la page en cas d'erreur
            // Récupération des données
            $ordis = $this->modelAutomates->getOrdiListForForm();
            $saufAutos = $this->modelAutomates->getAutoListeCanUseFiles();
            $paramLibelleIE = $this->modelAutomates->getParamLib();
            // Rendu
            $this->view->render($response, "autoFormForAdd.twig", array(
                "ordis" => $ordis,
                "libelleIE" => $paramLibelleIE,
                "autosSauf" => $saufAutos
            ));
            
            
            // sinon on ne fait rien
            return $response;
        }
    


    ****

    J'aimerai qu'il garde la valeur de l'input pour la réafficher.


    Ensuite je vérifierai si le formulaire fonctionne à nouveau.

    -
    Edité par Pitchounvivi 20 janvier 2020 à 17:02:15

    • Partager sur Facebook
    • Partager sur Twitter
      20 janvier 2020 à 16:51:14

      Salut. Tu ne devrais pas avoir à rafraîchir la page pour ça. Je ne connais pas du tout slim mais je pense que tu devrais renvoyer du JSON plutôt que des vues.
      • Partager sur Facebook
      • Partager sur Twitter
        20 janvier 2020 à 17:21:29

        Salut,

        merci de ton intérêt.

        le problème c'est que j'ai "hérité" d'une appli avec une dette technique énorme. Alors j'ai essayé de coller à l'existant car je n'ai que 2 mois de stage, je n'ai pas la possibilité de la refondre entièrement.

        Je me suis inspirée de fonction qui existait déjà.

            /**
             * Ajoute l'automate
             * @param Request $request
             * @param Response $response
             * @param $args
             * @return Response
             */
            public function tableAutomatesAdd(Request $request, Response $response, $args)
            {
                $message = array();
                // On vérifie le formulaire envoyé
                if (ValidatorManager::checkTableAutomate() === true) {
                    // Préparation des données
                    $clearData = DataParser::formatNewAutomateForDB($_POST);
                    $id = $this->modelAutomates->getAutoMaxID();
                    $id = intval($id["ID"]);
                    $id++;
        
        
                    // Enregistrement dans la base
                    $message = $this->modelAutomates->insertAuto($id, $clearData);
                    $message['nouveau'] = 'oui';
                    $this->logger->info($message['retour']);
                } else {
                    $message['etat'] = 'ko';
                    $message['retour'] = "Enregistrement de l'automate échoué - Erreur dans le champ " . ValidatorManager::checkTableAutomate();
                    $this->logger->error($message['retour']);
        
                    //rafraichissement de la page en cas d'erreur
                        // Récupération des données
                        $ordis = $this->modelAutomates->getOrdiListForForm();
                        $saufAutos = $this->modelAutomates->getAutoListeCanUseFiles();
                        $paramLibelleIE = $this->modelAutomates->getParamLib();
                        // Rendu
                        $this->view->render($response, "autoFormAdd.twig", array(
                            "ordis" => $ordis,
                            "libelleIE" => $paramLibelleIE,
                            "autosSauf" => $saufAutos,
                            "message" => $message
                        ));
                        return $response;
                }
                // Récupération des données
                $ordis = $this->modelAutomates->getOrdiListForForm();
                // Rendu
                $this->view->render($response, "gestionAutomates.twig", array(
                    "ordis" => $ordis,
                    "message" => $message
                ));
                return $response;
            }
        

        Si je ne fais pas la partie, rafraichissement/rendu, le formulaire disparaît entièrement, c'est pourquoi je fonctionne comme ça.

        Mais l'appli est vraiment difficile à "lire", les models font les requêtes SQL et j'ai certain controller qui ont 3550 lignes ...

        Je galère, je mets un temps fou à comprendre comment fonctionne le moindre truc.

        Comment tu vois le truc ?

        Que j'essaie parce que j'ai déjà essayé pleins de choses avant et après mes bricolages ... mais comme je n'ai pas d'aide, je suis certainement partie dans la mauvaise direction.

        -
        Edité par Pitchounvivi 21 janvier 2020 à 9:30:51

        • Partager sur Facebook
        • Partager sur Twitter
          20 janvier 2020 à 18:04:48

          Ok je comprends. Comme je t'ai dit je pense plutôt à renvoyer du JSON, donc dans ton contrôleur

          //Si l'automate existe
          $payload = json_encode([
            'message' => 'L\'automate existe déjà'
          ]);
          $status = 422;
          //Sinon
          $payload = json_encode([
            'message' => 'Ce nom est disponible'
          ]);
          $status = 200;
          //Dans tous les cas
          $response->getBody()->write($payload);
          return $response
                    ->withHeader('Content-Type', 'application/json')
                    ->withStatus($status);
          


          Je ne connais pas slim, je m'inspire de la doc.

          Et ta fonction Js serait

          function checkNameAuto() {
           
              // Recupération de l'input id=nom
              var inputName = document.getElementById('nom');
           
              // On attend que l'input perde le focus
              inputName.onblur = function (e) {
           
                  //on récupère la valeur de l'input
                  var name = inputName.value;
                  //console.log(name);
           
                  //on effectue la requête ajax
                  $.ajax({
                      type: "GET",
                      url: "/administration/table/automates/form/checkName",
                      data: {
                          nom: name
                      },
                      success: function (data) {
                          //console.log(data);
                          alert(data.message);
                      },
                      error: function(data) {
                         alert(data.message)
                      }
                  })
              }
          }

          Bien sûr j'ai mis les alert à titre d'illustration. En réalité tu vas les insérer dans le DOM

          -
          Edité par kulturman 20 janvier 2020 à 18:13:27

          • Partager sur Facebook
          • Partager sur Twitter
            21 janvier 2020 à 12:18:09

            Re, merci pour ton aide, je pense que je ne suis plus très loin.

            Alors j'ai adapté ce que tu m'as indiqué. Ce qui donne :

            ****

            AdministrationController.php

                /**
                 * Controle que le nom de l'automate n'est pas déjà présent dans la table
                 * @param Request $request
                 * @param Response $response
                 * @param $args
                 * @return Response
                 */
                public function ckeckNameNotDuplicated(Request $request, Response $response, $args)
                {
                    //permet de savoir d'avoir un tableau des paramètres de la request
                    //var_dump($request->getQueryParams());
            
                    //décode le paramètre "nom" de l'url
                    $name = urldecode($_GET["nom"]);
                    //var_dump($name);
            
                    // Recherche combien de fois le nom affiché dans le champs est présent dans la base de donnée
                    $double = $this->modelAutomates->getCheckNameAutoDoublon($name);
                    //var_dump($double);
            
            
                    //si l'automate existe déjà
                    if ($double !== false) {
                        //afficher message d'erreur
                        $message = array();
                        $message['etat'] = 'ko';
                        $message['retour'] = "Vous ne pouvez pas utiliser ce nom - Nom déjà utilisé ";
                        $this->logger->error($message['retour']);
            
            
                        $resultat = json_encode($message);
                        //var_dump($double);
            
                        $statusCode = 422;
                        $response->getBody()->write($resultat);
            
                        return $response
                            ->withHeader("Content-Type", "application/json")
                            ->withStatus($statusCode);
                    }
            
                    //afficher message d'erreur
                    $message = array();
                    $message['etat'] = 'ok';
                    $message['retour'] = "Vous pouvez utiliser ce nom - Nom non utilisé ";
                    $this->logger->error($message['retour']);
            
            
                    $resultat = json_encode($message);
            
            
                    $statusCode= 201;
                    $response->getBody()->write($resultat);
            
                    return $response
                        ->withHeader("Content-Type", "application/json")
                        ->withStatus($statusCode);
            
                }

            ****

            formChecker.js

            /**
             * Requête Ajax : Permettant le controle du nom de l'automate dans l'input
             * de façon interactive
             */
            function checkNameAuto() {
            
                // Recupération de l'input id=nom
                var inputName = document.getElementById('nom');
            
                // On attend que l'input perde le focus
                inputName.onblur = function (e) {
            
                    //on récupère la valeur de l'input
                    var name = inputName.value;
                    //console.log(name);
            
                    //on effectue la requête ajax
                    $.ajax({
                        type: "GET",
                        url: "/administration/table/automates/form/checkName",
                        data: {
                            nom: name
                        },
                        datatype: "json",
                        success: function (data) {
            
                            var jsonData = JSON.parse(data.responseText);
                            console.log(jsonData);
            
                            $('#message').html(jsonData.message).show();
                        }
            
                    })
                }
            }
            
            

            j'arrive pas à l'afficher (ailleurs que dans la console) et j'ai un affichage bizarre au niveau du retour de la réponse http dans l'outil de débug (dans réseau)

            **quand il s'agit d'un nom inconnu :

            réponse JSON :

            etat ok
            retour Vous pouvez utiliser ce nom - Nom non utilisé

            charge utile de la réponse :

            {"etat":"ok","retour":"Vous pouvez utiliser ce nom - Nom non utilis\u00e9 "}

            **quand il s'agit d'un nom connu :

            réponse JSON :

            etat ko
            retour Vous ne pouvez pas utiliser ce nom - Nom déjà utilisé

            charge utile de la réponse :

            {"etat":"ko","retour":"Vous ne pouvez pas utiliser ce nom - Nom d\u00e9j\u00e0 utilis\u00e9 "}

            Ma question : est-ce que c'est la charge utile de la réponse en http qui est important ou la réponse json ?

            Est-ce que c'est ça qui empêche l'affichage ?



            • Partager sur Facebook
            • Partager sur Twitter
              21 janvier 2020 à 12:50:00

              C'est la même chose hein, c'est ce que ton console.log affiche?

              {"etat":"ok","retour":"Vous pouvez utiliser ce nom - Nom non utilis\u00e9 "}


              Si ton message ne s'affiche pas dans la page c'est entre autres à cause de la condition (block ligne 11). Je propose donc

              <div class="col s10 offset-s1">
                  <div class="card darken-1" id="messages-card">
                      <div class="card-content white-text">
                          <span class="card-title">Message</span>
                          <strong id="message-text" class="card-title"></strong>
                      </div>
                  </div>
              </div>

              Et dans ton Js

              $('#message-text').html("");
              $.ajax({
                  type: "GET",
                  url: "/administration/table/automates/form/checkName",
                  data: {
                      nom: name
                  },
                  datatype: "json",
                  success: function (data) {
                      handleMessagesDisplay(data);
                  },
                  error: function(data) {
                      handleMessagesDisplay(data);
                  }
              
              })
              
              function handleMessagesDisplay(data) {
                  var jsonData = data.responseJSON; //responseJSON plutôt
                  if(jsonData.etat == 'ok') {
                      $('#messages-card').removeClass("red").addClass("green");
                  }
                  else {
                      $('#messages-card').removeClass("green").addClass("red");
                  }
                  $('#message-text').html(jsonData.message);
              }




              -
              Edité par kulturman 21 janvier 2020 à 13:28:25

              • Partager sur Facebook
              • Partager sur Twitter
                21 janvier 2020 à 14:38:05

                Dans l'absolu, je suis sensée garder l'aspect général du formulaire (ils ont tous se fonctionnement).

                vu de l'affichage

                Le gros blanc en haut correspond à l'entête avec le logo de l'entreprise et la barre de navigation. Je les ai supprimés pour la confidentialité ;)

                Donc normalement, quand il y a un message, j'ai un encadré qui s'affiche entre le gris et le formulaire. et qui correspond à cette partie du fichier twig

                 </div>
                            {% if message is defined %}
                                <div  class="col s10 offset-s1">
                                    {# Si c'est une erreur #}
                                    {% if message.etat == "ko" %}
                                    <div class="card red darken-1">
                                        {% else %}
                                        <div class="card green darken-1">
                                            {% endif %}
                                            <div class="card-content white-text">
                                                <span class="card-title">Message</span>
                                                {{ message.retour }}
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            {% endif %}

                quand il n'y a pas de message dans la réponse l'encadré ne s'affiche pas. Donc par défaut, il ne s'affiche pas car lors du chargement du formulaire, il n'y a pas de message d'erreur ou de validation.

                EDIT:

                je viens de tenter de faire le

                var jsonData = data.responseJSON; //responseJSON plutôt

                mais il me dit que ce n'est pas une fonction et dans ses propositions, j'ai

                response

                responseText

                responseXML

                _response()

                __response()



                -
                Edité par Pitchounvivi 21 janvier 2020 à 14:47:36

                • Partager sur Facebook
                • Partager sur Twitter
                  21 janvier 2020 à 14:55:27

                  Essaie ceci alors

                  $.parseJSON(data);

                  Pour ce qui est du message y a pas de souci. Tu peux garder les deux blocs, de toute façon ils ne s'afficheront pas en même temps je pense.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    21 janvier 2020 à 15:39:21

                    Alors désormais on a toujours l'encadré pour les message qui s'affiche. Mais bon c'est pas le plus embêtant.

                    ****

                    Pour faire les tests, j'ai mis ce que tu m'as demandé :

                    formChecker.js

                    /**
                     * Requête Ajax : Permettant le controle du nom de l'automate dans l'input
                     * de façon interactive
                     */
                    function checkNameAuto() {
                    
                        // Recupération de l'input id=nom
                        var inputName = document.getElementById('nom');
                    
                        // On attend que l'input perde le focus
                        inputName.onblur = function (e) {
                    
                            //on récupère la valeur de l'input
                            var name = inputName.value;
                            //console.log(name);
                    
                    
                            $('#message-text').html("");
                            //on effectue la requête ajax
                            $.ajax({
                                type: "GET",
                                url: "/administration/table/automates/form/checkName",
                                data: {
                                    nom: name
                                },
                                datatype: "json",
                                success: function (data) {
                    
                                    messageDisplay(data);
                                }
                            })
                    
                    
                            function messageDisplay(data) {
                                var jsonData = $.parseJSON(data);
                    
                                if(jsonData.etat == 'ok') {
                                    $('#messages-card').removeClass("red").addClass("green");
                                }
                                else {
                                    $('#messages-card').removeClass("green").addClass("red");
                                }
                    
                                $('#message').html(jsonData);
                            }
                    
                        }
                    }

                    ****

                    le fichier twig

                        <div id="message" class="row container">
                            <div class="row">
                                <div class="col s10 offset-s1">
                                    <div class="card blue-grey darken-1">
                                        <div class="card-content white-text">
                                            <span class="card-title"><i class="material-icons">report_problem</i>  Attention</span>
                                            <p>Les champs marqués avec une <span class="option">*</span> sont facultatifs</p>
                                        </div>
                                    </div>
                                </div>
                                <div class="col s10 offset-s1">
                                    <div class="card darken-1" id="messages-card">
                                        <div class="card-content white-text">
                                            <span class="card-title">Message</span>
                                            <strong id="message-text" class="card-title"></strong>
                                        </div>
                                    </div>
                                </div>
                    
                    
                    ICI le reste du formulaire
                    
                    {% block script %}
                     ICI autres scripts pour le formulaire
                    
                    
                            <script>
                                document.querySelector('#nom').onfocus = function() {
                                    checkNameAuto();
                                }
                            </script>
                    
                        {% endblock %}
                    
                    
                    


                    Il ne semble pas lier la réponse ajax à twig. Il ne fait aucun affichage, pourtant (sur l'image), on voit bien que la réponse possède bien le message.

                    Ce qui me fait supposer que le problème ne vient pas du tout du block logique if message ...

                    -
                    Edité par Pitchounvivi 21 janvier 2020 à 15:51:32

                    • Partager sur Facebook
                    • Partager sur Twitter
                      21 janvier 2020 à 15:55:18

                      Bon, je ne sais pas pourquoi tu continues à enlever la partie "error" dans la requête AJAX o_O (parce que c'est bel et bien nécessaire dans notre cas). De plus ce serait plutôt

                      $('#message').html(jsonData.retour); //j'avais mis message mais j'ai oublié que tu as changé la réponse JSON
                      //Et pas
                      $('#message').html(jsonData);



                      • Partager sur Facebook
                      • Partager sur Twitter
                        21 janvier 2020 à 16:50:19

                        En fait, je l'ai enlevé car tout à l'heure, j'ai fait un test pour voir si on l'utilisait et il me semblerait que non. Après j'ai juste oublié de le remettre.

                        Mais là je l'ai remis, j'ai aucun changement.

                        Pour le

                        $('#message').html(jsonData.retour); //j'avais mis message mais j'ai oublié que tu as changé la réponse JSON

                        Pareil, j'ai essayé plusieurs choses ... mais rien ne va

                        et avec le .retour 

                        il me rend un message : Unresolved variable retour.

                        EDIT:

                        Après la requête ajax, j'ai ce message désormais (je ne sais depuis combien de temps)

                        et c'est le même message si je mets JSON.parse(data).

                        Cela peut venir de là ?

                        EDIT :

                        Bonjour,

                        bon apparemment d'après mes recherches ... Le problème vient bien de la ligne

                        var jsonData = $.parseJSON(data);

                        j'ai le message : SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data

                        Pourtant ma réponse me renvoie bien un objet json

                        j'ai bien dans ma console :

                        et dans la réponse :



                        Je comprends pas ce qui gène.

                        REEDITE :

                        Bon, j'ai avancé, grosso modo, il me reste a ce que le résultat de l'Ajax, s'affiche au bon endroit (dans le formulaire d'origine).

                        Il faut donc lié jsonData.retour de la réponse Ajax à la variable {{message.retour}} dans le fichier twig.

                        Avec la prise en compte de l'état ko pour avoir la couleur rouge dans l'encadré.

                        le fichier twig

                            <div id="message" class="row container">
                                <div class="row">
                                    <div class="col s10 offset-s1">
                                        <div class="card blue-grey darken-1">
                                            <div class="card-content white-text">
                                                <span class="card-title"><i class="material-icons">report_problem</i>  Attention</span>
                                                <p>Les champs marqués avec une <span class="option">*</span> sont facultatifs</p>
                                            </div>
                                        </div>
                                    </div>
                                    {% if message is defined %}
                                        <div  class="col s10 offset-s1">
                                            {# Si c'est une erreur #}
                                            {% if message.etat == "ko" %}
                                            <div class="card red darken-1">
                                                {% else %}
                                                <div class="card green darken-1">
                                                    {% endif %}
                                                    <div class="card-content white-text">
                                                        <span class="card-title">Message</span>
                                                        {{ message.retour }}
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    {% endif %}


                        La requête Ajax :

                        /**
                         * Requête Ajax : Permettant le controle du nom de l'automate dans l'input
                         * de façon interactive
                         */
                        function checkNameAuto() {
                        
                            // Recupération de l'input id=nom
                            var inputName = document.getElementById('nom');
                        
                            // On attend que l'input perde le focus
                            inputName.onblur = function (e) {
                        
                                //on récupère la valeur de l'input
                                var name = inputName.value;
                                //console.log(name);
                        
                                
                                //on effectue la requête ajax
                                $.ajax({
                                    type: "GET",
                                    url: "/administration/table/automates/form/checkName",
                                    data: {
                                        nom: name
                                    },
                                    datatype: "json",
                                    success: messageDisplay,
                                    error: messageDisplay
                                })
                        
                        
                                function messageDisplay(data) {
                                    //console.log(data);
                                    console.log(data.responseJSON);
                        
                                    var jsonData = data.responseJSON; //si ko
                                    //var jsonData = data; // si ok
                        
                        
                                    $('#message').html(jsonData.retour);
                        
                                }
                        
                            }
                        }

                        J'aurai besoin d'une dernière inspiration/aide pour finir.

                        Je remercie l'aide antérieure (@kulturman si tu repasses par là, merci tu m'as bien aidé) et je remercie d'avance mon/ma sauveur(se) qui me permettra de comprendre pourquoi ça ne s'affiche pas comme il faut.o_O

                        -
                        Edité par Pitchounvivi 22 janvier 2020 à 15:29:12

                        • Partager sur Facebook
                        • Partager sur Twitter
                          23 janvier 2020 à 0:12:23

                          PHP et javascript ne s'exécutent pas au même moment. Tu ne peux pas lier le résultat de jsonData à une variable twig pour le simple fait qu'au moment où le Javascript s'exécute la notion de variable PHP (ou twig) n'existe plus, ce n'est donc pas la peine d'essayer, c'est pour ça que je te disais qu'avec le bloc "if" tu n'auras jamais le résultat souhaité.

                          La solution est donc de prévoir un bloc initialement vide dans la page, que l'on va ensuite remplir après la requête AJAX

                          Remets le code que je t'ai donné plus haut et je verrai ce qui ne va pas, c'était bien la bonne piste.

                          Il faut inclure jquery avant tous les autres scripts

                          Je suis bien de sexe masculin :)

                          -
                          Edité par kulturman 23 janvier 2020 à 0:15:12

                          • Partager sur Facebook
                          • Partager sur Twitter
                            23 janvier 2020 à 10:12:18

                            Bonjour,

                            déjà merci pour l'explication sur l'exécution PHP, JavaScript ... Je ne savais pas ou j'avais oublié.

                            Alors voilà ce que ça donne avec tous les blocks remis :

                            Honnêtement, c'est super ça marche vraiment pas mal. La partie affichage en vert si ok ne fonctionne pas. Mais ça vient de la réponse retournée par ajax. J'ai vu ça hier, quand c'est ok, il retourne undefined, mais comme ce qui intéresse mon maître de stage c'est surtout le message d'erreur. On peut faire sans.

                            Sinon j'ai vu que je peux le régler avec ça :

                            function messageDisplay(data) {
                                        //console.log(data);
                                        console.log(data.responseJSON);
                            
                                        var jsonData = data.responseJSON; //responseJSON plutôt
                                        if(data.responseJSON === undefined) {
                                            $('#messages-card').removeClass("red").addClass("green");
                            
                                            var jsonData = data;
                                        }
                                        else {
                                            $('#messages-card').removeClass("green").addClass("red");
                                        }
                                        $('#message-text').html(jsonData.retour);
                            
                                    }

                            ****

                            Jquery est bien avant tous les scripts, il est dans la page de base avant le {{% block script %}}.

                            Je me pose quelques questions :

                            - Faut-il que le bloc MESSAGE en noir soit vraiment déjà présent ? (Parce que mon maître de stage qui est venu voir ou j'en étais, trouve ça moche)

                            - Ou il est possible de le "créer" dynamiquement si on en a besoin (avec insertion dans le DOM, avec appendChild ...etc)?

                            En tout cas, je te renouvelle mes remerciements ... ^^ ... j'ai déjà appris beaucoup de choses.

                            *********

                            EDIT :

                            J'ai trouvé, j'ai géré l'affichage avec du css de materialize dans le fichier twig

                            <div id="message" class="row container">
                                    <div class="row">
                                        <div class="col s10 offset-s1">
                                            <div class="card blue-grey darken-1">
                                                <div class="card-content white-text">
                                                    <span class="card-title"><i class="material-icons">report_problem</i>  Attention</span>
                                                    <p>Les champs marqués avec une <span class="option">*</span> sont facultatifs</p>
                                                </div>
                                            </div>
                                        </div>
                            
                                        <div class="col s10 offset-s1">
                                            <div class="card hide darken-1" id="messages-card">
                                                <div class="card-content white-text">
                                                    <span class="card-title">Message</span>
                                                    <strong id="message-text" class="card-title"></strong>
                                                </div>
                                            </div>
                                        </div>
                            
                                        {% if message is defined %}
                                            <div  class="col s10 offset-s1">
                                                 {#Si c'est une erreur #}
                                                {% if message.etat == "ko" %}
                                                <div class="card red darken-1">
                                                    {% else %}
                                                    <div class="card green darken-1">
                                                        {% endif %}
                                                        <div class="card-content white-text">
                                                            <span  class="card-title">Message</span>
                                                            {{ message.retour }}
                                                        </div>
                                                    </div>
                                                </div>
                                            </div>
                                        {% endif %}

                            J'ai rajouté la class="hide" dans la div contenant l'id="message-card"

                            Et légèrement modifié l'ajax

                            /**
                             * Requête Ajax : Permettant le controle du nom de l'automate dans l'input
                             * de façon interactive
                             */
                            function checkNameAuto() {
                            
                                // Recupération de l'input id=nom
                                var inputName = document.getElementById('nom');
                            
                                // On attend que l'input perde le focus
                                inputName.onblur = function (e) {
                            
                                    //on récupère la valeur de l'input
                                    var name = inputName.value;
                                    //console.log(name);
                            
                                    
                                    //on effectue la requête ajax
                                    $.ajax({
                                        type: "GET",
                                        url: "/administration/table/automates/form/checkName",
                                        data: {
                                            nom: name
                                        },
                                        datatype: "json",
                                        success: messageDisplay,
                                        error: messageDisplay
                                    })
                            
                                    //l'affichage des messages
                                    function messageDisplay(data) {
                                        //console.log(data);
                                        //console.log(data.responseJSON);
                            
                                        if(data.responseJSON === undefined) {
                                            //affiche l'encadré
                                            $('#messages-card').removeClass("hide");
                            
                                            //gère la couleur de fond de l'encadré
                                            $('#messages-card').removeClass("red").addClass("green");
                            
                                            //message reçu du controller (dans le cas ou nom inconnu)
                                            var jsonData = data;
                                        }
                                        else {
                                            //affiche l'encadré
                                            $('#messages-card').removeClass("hide");
                            
                                            //gère la couleur de fond de l'encadré
                                            $('#messages-card').removeClass("green").addClass("red");
                            
                                            //message reçu du controller (dans le cas d'un nom connu)
                                            var jsonData = data.responseJSON;
                                        }
                                        //affichage du message
                                        $('#message-text').html(jsonData.retour);
                                    }
                                }
                            }



                            Avec dans le controller pour gérer tout ça

                                /**
                                 * Controle que le nom de l'automate n'est pas déjà présent dans la table
                                 * @param Request $request
                                 * @param Response $response
                                 * @param $args
                                 * @return Response
                                 */
                                public function ckeckNameNotDuplicated(Request $request, Response $response, $args)
                                {
                                    //permet d'avoir un tableau des paramètres de la request
                                    //var_dump($request->getQueryParams());
                            
                                    //décode le paramètre "nom" de l'url
                                    $name = urldecode($_GET["nom"]);
                                    //var_dump($name);
                            
                                    // Recherche combien de fois le nom affiché dans le champs est présent dans la base de donnée
                                    $double = $this->modelAutomates->getCheckNameAutoDoublon($name);
                                    //var_dump($double);
                                    
                            
                                    //si l'automate existe déjà
                                    if ($double !== false) {
                                        //afficher message d'erreur
                                        $message = array();
                                        $message["etat"] = "ko";
                                        $message["retour"] = "Vous ne pouvez pas utiliser ce nom - Nom déjà utilisé ";
                                        $this->logger->error($message["retour"]);
                            
                                        //transforme la variable message en json
                                        $resultat = json_encode($message);
                                        //var_dump($message);
                            
                                        //valeur que doit rendre la reponse de la requête http
                                        $statusCode = 409;
                            
                                        //passage de l'objet json au body de la requête http
                                        $response->getBody()->write($resultat);
                            
                                        //envoie de la réponse :
                                        // - avec dans son header l'information indispensable indiquant que le body est en json
                                        // - avec dans le header également la valeur du status de la requête http
                                        return $response
                                            ->withHeader("Content-Type", "application/json")
                                            ->withStatus($statusCode);
                                    }
                            
                                    //afficher message signalant que tout est ok
                                    $message = array();
                                    $message["etat"] = "ok";
                                    $message["retour"] = "Vous pouvez utiliser ce nom - Nom non utilisé ";
                                    $this->logger->error($message["retour"]);
                            
                                    //transforme la variable message en json
                                    $resultat = json_encode($message);
                            
                                    //valeur que doit rendre la reponse de la requête http
                                    $statusCode= 200;
                            
                                    //passage de l'objet json au body de la requête http
                                    $response->getBody()->write($resultat);
                            
                                    //envoie de la réponse :
                                    // - avec dans son header l'information indispensable indiquant que le body est en json
                                    // - avec dans le header également la valeur du status de la requête http
                                    return $response
                                        ->withHeader("Content-Type", "application/json")
                                        ->withStatus($statusCode);
                            
                                }
                            



                            ENCORE un grand merci à toi ...

                            Je vais commencer tout de suite la statue à ton nom ;)

                            -
                            Edité par Pitchounvivi 23 janvier 2020 à 14:14:48

                            • Partager sur Facebook
                            • Partager sur Twitter
                              23 janvier 2020 à 12:01:42

                              Bonjour. Ah, c'est super, félicitations :soleil:. Un dernier truc, il ne faut pas oublier de remettre la class "hide" à chaque fois que ton input perd le focus (donc juste avant la requête AJAX). Sinon si quelqu'un saisit un nom déjà pris, quitte le champ puis reviens saisir un nom libre et quitte de nouveau le champ, le message sera toujours affiché, tu vois?

                              $('#messages-card').addClass("hide");
                              $.ajax({
                                 ...
                              });
                              • Partager sur Facebook
                              • Partager sur Twitter
                                23 janvier 2020 à 14:36:55

                                Je comprends l'idée, mais ayant modifié l'ajax pour qu'il affiche soit le message d'erreur, soit le message ok.

                                J'ai désormais toujours un message d'affiché, du moment qu'on a testé le nom.

                                Par contre je viens de faire un test, ça ne marche pas cette ligne 

                                $('#messages-card').addClass("hide");
                                mise avant l'ajax.
                                Mais ca peut certainement se gérer avec un setTimeout.

                                -
                                Edité par Pitchounvivi 23 janvier 2020 à 14:38:44

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  23 janvier 2020 à 15:59:55

                                  Pitchounvivi a écrit:

                                  Je comprends l'idée, mais ayant modifié l'ajax pour qu'il affiche soit le message d'erreur, soit le message ok.

                                  J'ai désormais toujours un message d'affiché, du moment qu'on a testé le nom

                                  Ok tant mieux si ça marche.

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  [Ajax] Garder la valeur du champ après une requête

                                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                  • Editeur
                                  • Markdown