Rafraichir la page parente à la fermeture de la page fille

Derrière ce titre alambiqué se cache un besoin particulier que j’ai cherché (et réussi) à résoudre dernièrement. La situation est la suivante : un utilisateur arrive sur une page, celle-ci effectue un appel ajax afin de connaître l’état d’un paramètre utilisateur. Pour illustrer, nous dirons donc que la page interroge une api pour répondre à la question : l’utilisateur a-t-il une image de profil enregistrée ?

Si l’utilisateur possède une image enregistrée, on la lui affiche ainsi qu’un message pour lui permettre de la supprimer. Si aucune image n’est présente, l’utilisateur peut choisir d’en ajouter une. L’acquisition de l’image s’effectue dans une page dédiée, que nous appellerons la page fille. Cette acquisition est réalisée à l’aide de la bibliothèque Cropper.js.

Une fois l’image acquise, l’utilisateur valide la sélection via un bouton. Au niveau de la page fille, un appel est donc réalisé vers une api pour sauvegarder l’image. Si l’appel est une réussite, nous fermons la page fille. À ce stade, l’utilisateur se retrouve sur la page parente qui lui propose toujours d’ajouter une image, ce qu’il vient de faire, nous allons donc recharger la page parente à la fermeture de la page fille.

J’illustre ce processus dans le code HTML en fin de page. Lorsque la page parente est chargée, celle-ci affiche en alert(), le message « Page chargée ! » afin de matérialiser le rechargement de la page. En cliquant sur le lien, une nouvelle page s’ouvre. Lorsqu’on clique sur le bouton de cette page, on va déclencher la fermeture de la page courante (la page fille) et le rechargement de la page parente. De plus, afin de matérialiser l’action de la page fille dans la page parente, de rendre l’exemple plus intéressant et de matérialiser ce qui correspondrait dans mon cas pratique à la mise à jour de l’information par le premier appel ajax (celui sur la page parente), le texte saisi dans le formulaire sur la page fille est transféré à la page parente et affiché par un alert().

Par ailleurs, le test du booléen pageFille.fermeture dans la fonction de l’événement unload de la page fille permet de s’assurer que la page parente ne sera rechargée que si le traitement est réussi sur la page fille où window.fermeture vaudra alors true. En effet, si on enlève le test du booléen, on constate qu’un événement unload a lieux dès l’ouverture de la page fille, ce qui aurait donc pour effet de recharger immédiatement la page parente. Le test du booléen permet de palier à ce « problème ».

Page Parente (pageParente.html)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <p>
      <a href="javascript:ouvrirPageFille();">cliquez ici</a>
    </p>

    <script>
      function ouvrirPageFille() {
        var pageFille = window.open('pageFille.html', 'Titre', 'top=42,left=42,height=800,width=600,scrollbars=yes,status=no,toolbar=yes');
        //Recharge la page parente à la fermeture de la page fille 
        pageFille.onunload = function() {
          if(pageFille.fermeture) {
            alert(pageFille.message);
            //Rechargement
            location.reload();
          }
        }
      }

      window.onload = alert('Page chargée !');
    </script>
  </body>
</html>

Page Fille (pageFille.html)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <form>
      <label for="message">Message :</label>
      <input id="message" type="text" name="message">
      <input type="submit" value="Valider et quitter" onclick="quitterPage();">
    </form>

    <script>
      function quitterPage() {
        window.message = document.getElementById('message').value;
        window.fermeture = true;
        window.close();
      }
    </script>
  </body>
</html>

Voilà pour l’exemple. Il reste maintenant quelques limitations à préciser pour finir cet article. Si l’utilisateur ferme la fenêtre du navigateur via le bouton prévu à cet effet (la croix rouge généralement en haut à droite), la page parente n’est pas rechargée. Dans mon cas pratique, cela fait sens car l’utilisateur n’aura alors pas soumit d’image; il n’y a donc aucun raison de rafraîchir la page. Autre point, si l’utilisateur rafraîchit la page fille, cela a pour effet de casser la liaison existante entre les deux pages et le rechargement de la page parente n’aura pas lieux.

Voici donc une manière de rafraîchir une page parente à la fermeture de sa page fille en restant dans les fonctionnalités de base du navigateur et des langages. D’autres façons de faire sont très certainement possibles (avec des événements) et certains framework js seraient à même de simplifier le problème, en permettant de ne mettre à jour dynamiquement qu’une partie de l’interface.