web-dev-qa-db-fra.com

Persistance des variables entre les chargements de page

J'essaie de capturer le bouton d'envoi de mon formulaire et si celui-ci est soumis, la page est actualisée et quelques champs cachés s'affichent. J'aimerais savoir si le formulaire a été soumis auparavant ou non et s'il est soumis lors du rechargement, j'aimerais afficher les champs cachés. J'essayais d'utiliser une variable globale pour y parvenir, mais j'étais incapable de la faire fonctionner correctement.

Voici ce que j'ai essayé:

  var clicked = false;

  $(document).ready(function() {

    $("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch'; clicked = true;  return true;");

    if (clicked == true) {
      // show hidden fields
    } else {
      // don't show hidden fields
    }
  });

Des suggestions sur ce qui ne va pas avec ce code?

78
Neophile

Comme HTTP est sans état, chaque fois que vous chargez la page, il utilisera les valeurs initiales de tout ce que vous définissez dans JavaScript. Vous ne pouvez pas définir une variable globale dans JS et faire en sorte que cette valeur reste après le chargement de la page.

Vous pouvez stocker la valeur à un autre endroit de différentes manières afin de l'initialiser au chargement à l'aide de JavaScript.


Chaîne de requête

Lors de la soumission d'un formulaire à l'aide de la méthode GET, l'URL est mise à jour avec une chaîne de requête (?parameter=value&something=42). Vous pouvez utiliser ceci en définissant un champ de saisie du formulaire avec une certaine valeur. Ce serait l'exemple le plus simple:

<form method="GET">
    <input type="hidden" name="clicked" value="true" />
    <input type="submit" />
</form>

Lors du chargement initial de la page, aucune chaîne de requête n'est définie. Lorsque vous soumettez ce formulaire, les combinaisons name et value de l’entrée sont passées dans la chaîne de requête sous la forme clicked=true. Ainsi, lorsque la page se charge à nouveau avec cette chaîne de requête, vous pouvez vérifier si le bouton a été cliqué.

Pour lire ces données, vous pouvez utiliser le script suivant lors du chargement de la page:

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

var clicked = getParameterByName('clicked');

( Source )

La possibilité de l'utiliser dépend de la façon dont votre formulaire fonctionne actuellement. Si vous utilisez déjà un POST, cela pourrait poser problème).

En outre, pour les grands ensembles de données, cela n’est pas optimal. Passer une chaîne n'est pas un problème, mais pour les tableaux et les objets de données, vous devriez probablement utiliser Web Storage ou des cookies. Bien que les détails diffèrent un peu d’un navigateur à l’autre, la limite pratique pour la longueur de l’URI est d’environ 2000 caractères


Stockage Web

Avec l'introduction de HTML5, nous avons également obtenu le stockage Web, qui vous permet d'enregistrer des informations dans le navigateur lors du chargement de pages. Il existe localStorage qui peut enregistrer des données pendant une période plus longue (tant que l'utilisateur ne l'efface pas manuellement) et sessionStorage qui enregistre les données uniquement pendant votre session de navigation en cours. Ce dernier est utile pour vous ici, car vous ne voulez pas garder "cliqué" sur true lorsque l'utilisateur revient plus tard.

Ici, je mets le stockage sur l'événement click du bouton, mais vous pouvez également le lier pour soumettre un formulaire ou autre chose.

$('input[type="submit"][value="Search"]').click(function() {
    sessionStorage.setItem('clicked', 'true');
});

Ensuite, lorsque vous chargez la page, vous pouvez vérifier si elle est définie en utilisant ceci:

var clicked = sessionStorage.getItem('clicked');

Bien que cette valeur ne soit enregistrée que pendant cette session de navigation, il est possible que vous souhaitiez la réinitialiser plus tôt. Pour ce faire, utilisez:

sessionStorage.removeItem('clicked');

Si vous souhaitez enregistrer un objet ou un tableau JS, vous devez le convertir en chaîne. Selon les spécifications, il devrait être possible de sauvegarder d'autres types de données, mais cela n'a pas encore été correctement implémenté sur les navigateurs.

//set
localStorage.setItem('myObject', JSON.stringify(myObject));

//get
var myObject = JSON.parse(localStorage.getItem('myObject'));

Le support des navigateurs est très bien , vous devriez donc pouvoir l'utiliser en toute sécurité, sauf si vous devez prendre en charge des navigateurs très anciens/obscurs. Le stockage Web est l'avenir.


Cookies

Une alternative au stockage Web consiste à enregistrer les données dans un cookie. Les cookies sont principalement conçus pour lire des données côté serveur, mais peuvent également être utilisés pour des données purement client.

Vous utilisez déjà jQuery, ce qui facilite l'installation de cookies. Encore une fois, j'utilise l'événement click ici mais je pourrais l'utiliser n'importe où.

$('input[type="submit"][value="Search"]').click(function() {
    $.cookie('clicked', 'true', {expires: 1}); // expires in 1 day
});

Ensuite, au chargement de la page, vous pouvez lire le cookie comme ceci:

var clicked = $.cookie('clicked');

Comme les cookies persistent entre les sessions dans votre cas, vous devrez les désélectionner dès que vous aurez fait ce que vous avez à faire. Vous ne voudriez pas que l'utilisateur revienne un jour plus tard et que clicked soit toujours défini sur true.

if(clicked === "true") {
    //doYourStuff();
    $.cookie('clicked', null);
}

(un moyen non jQuery de définir/lire les cookies peut être trouvé ici )

Personnellement, je ne voudrais pas utiliser un cookie pour quelque chose de simple comme se souvenir d'un état cliqué, mais si la chaîne de requête n'est pas une option et que vous devez prendre en charge les très vieux navigateurs qui ne prennent pas en charge sessionStorage, cela fonctionnera. Vous devez d'abord implémenter cela avec une vérification de sessionStorage, et uniquement si cela échoue, utilisez la méthode cookie.


window.name

Bien que cela me semble être un piratage qui date probablement d’avant LocalStorage/sessionStorage, vous pouvez stocker des informations dans le fichier window.name propriété:

window.name = "my value"

Il ne peut stocker que des chaînes. Par conséquent, si vous souhaitez enregistrer un objet, vous devez le hiérarchiser comme dans l'exemple ci-dessus localStorage:

window.name = JSON.stringify({ clicked: true });

La principale différence est que ces informations sont conservées non seulement lors de l'actualisation de la page, mais également dans différents domaines. Cependant, il est limité à l'onglet actuel dans lequel vous vous trouvez.

Cela signifie que vous pouvez enregistrer des informations sur votre page et tant que l'utilisateur reste dans cet onglet, vous pouvez accéder à ces mêmes informations même s'il navigue sur un autre site Web, et vice-versa. En général, je vous déconseille de l'utiliser sauf si vous devez stocker des informations inter-domaines au cours d'une seule session de navigation.

164
Stephan Muller

Essayez d’utiliser $.holdReady() , history

<script src="jquery.js" type="text/javascript"></script>
</head>
<body>
<form method="POST">
    <input type="text" name="name" value="" />
    <input type="submit" value="Search" />
    <input type="hidden" />
    <input type="hidden" />
</form>
<script type="text/javascript">
function show() {
  return $("form input[type=hidden]")
          .replaceWith(function(i, el) {
            return "<input type=text>"
          });
}

$.holdReady(true);
    if (history.state !== null && history.state.clicked === true) {
       // show hidden fields
       // if `history.state.clicked === true` ,
       // replace `input type=hidden` with `input type=text`
       show();
       console.log(history);

    } else {
        // don't show hidden fields
        console.log(history);
    }
$.holdReady(false);

  $(document).ready(function() {

    $("input[type=submit][value=Search]")
    .on("click", function(e) {
        e.preventDefault();
        if (history.state === null) {
          // do stuff
          history.pushState({"clicked":true});
          // replace `input type=hidden` with `input type=text`
          show();
          console.log(history);
        } else {
          // do other stuff
        };
    });

  });
</script>
</body>
5
guest271314

Utiliser localeStorage ou sessionStorage semble être le meilleur choix.

Au lieu de sauvegarder la variable clicked dans la portée globale, stockez-la ainsi:

if(localeStorage.getItem("clicked") === null)
    localeStorage.setItem("clicked", "FALSE"); // for the first time

$(document).ready(function() {

    $("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch';return true;");

    var clicked = localeStorage.getItem("clicked") == "FALSE" ? "TRUE" : "FALSE";

    localeStorage.setItem("clicked", clicked);

    if (clicked == "TRUE") {
      // show hidden fields
    } else {
      // don't show hidden fields
    }

});
1
me_digvijay