Variables persistentes entre cargas de página


Estoy tratando de capturar la pulsación del botón enviar de mi formulario y si se envía el formulario, la página se actualiza y muestro algunos campos ocultos. Me gustaría capturar si el formulario ha sido enviado antes o no y si es presentado en cargar, me gustaría mostrar los campos ocultos. Estaba tratando de usar una variable global para lograr esto, sin embargo, no pude hacer que funcionara correctamente.

Esto es lo que intenté:

  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
    }
  });

Cualquier sugerencia sobre lo que está mal con esto código?

Author: kryger, 2015-05-01

4 answers

Como HTTP es sin estado, cada vez que cargue la página utilizará los valores iniciales de lo que haya establecido en JavaScript. No puedes establecer una variable global en JS y simplemente hacer que ese valor permanezca después de cargar la página de nuevo.

Hay un par de maneras en que podría almacenar el valor en otro lugar para que pueda inicializarlo en carga utilizando JavaScript


Cadena de Consulta

Al enviar un formulario utilizando el método GET, la url se actualiza con un cadena de consulta (?parameter=value&something=42). Puede utilizar esto estableciendo un campo de entrada en el formulario a un cierto valor. Este sería el ejemplo más simple:

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

En la carga inicial de la página, no se establece ninguna cadena de consulta. Cuando envía este formulario, la combinación name y value de la entrada se pasa en la cadena de consulta como clicked=true. Por lo tanto, cuando la página se carga de nuevo con esa cadena de consulta, puede verificar si se hizo clic en el botón.

Para leer estos datos, puede usar el siguiente script en la página carga:

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 capacidad de usar esto depende de cómo funciona tu formulario actualmente, si ya usas una publicación, esto podría ser problemático.

Además, para conjuntos de datos más grandes esto es menos que óptimo. Pasar una cadena no es un gran problema, pero para matrices y objetos de datos, probablemente debería usar almacenamiento web o cookies. Si bien los detalles difieren un poco entre los navegadores, el límite práctico para la longitud de URI es de alrededor de 2000 caracteres


Almacenamiento web

Con la introducción de HTML5 también tenemos Almacenamiento web, que le permite guardar información en el navegador a través de cargas de página. Existe localStorage que puede guardar datos durante un período más largo (siempre y cuando el usuario no los borre manualmente) y sessionStorage que guarda datos solo durante su sesión de navegación actual. Este último es útil para usted aquí, porque no desea mantener" clicked " establecido en true cuando el usuario regresa tarde.

Aquí establezco el almacenamiento en el evento de clic en el botón, pero también podría vincularlo a form submit o cualquier otra cosa.

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

Luego, cuando cargue la página, puede verificar si está configurada usando esto:

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

Aunque este valor solo se guarda durante esta sesión de navegación, es posible que desee restablecerlo antes. Para ello, utilice:

sessionStorage.removeItem('clicked');

Si desea guardar un objeto o matriz JS, debe convertirlo en una cadena. De acuerdo con las especificaciones debería ser posible guardar otros tipos de datos, pero esto aún no se ha implementado correctamente en los navegadores.

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

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

El soporte del navegador es bastante bueno por lo que debería estar seguro de usar esto a menos que necesite soporte para navegadores realmente antiguos/oscuros. El almacenamiento web es el futuro.


Cookies

Una alternativa al almacenamiento web es guardar los datos en una cookie. Las cookies se hacen principalmente para leer datos del lado del servidor, pero se pueden usar para datos puramente del lado del cliente como bien.

Ya utiliza jQuery, lo que hace que la configuración de cookies sea bastante fácil. De nuevo, utilizo el evento click aquí, pero podría usarse en cualquier lugar.

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

Luego, al cargar la página, puede leer la cookie de esta manera:

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

Como las cookies persisten en las sesiones en su caso, tendrá que desactivarlas tan pronto como haya hecho lo que tenga que hacer con ellas. No querrá que el usuario regrese un día después y aún tenga clicked establecido en true.

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

(una forma que no es jQuery para configurar / leer las cookies se puede encontrar aquí )

Personalmente no usaría una cookie para algo simple como recordar un estado clickeado, pero si la cadena de consulta no es una opción y necesita admitir navegadores realmente antiguos que no admiten sessionStorage, esto funcionará. Debe implementar eso con una comprobación para sessionStorage primero, y solo si falla, use el método cookie.


Window.name

Aunque esto me parece un truco que probablemente se originó antes de localStorage / sessionStorage, podría almacenar información en la propiedad window.name:

window.name = "my value"

Solo puede almacenar cadenas, por lo que si desea guardar un objeto tendrá que stringificarlo al igual que el ejemplo anterior localStorage:

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

La principal diferencia es que esta información se conserva no solo en las actualizaciones de páginas, sino también en diferentes dominios. Sin embargo, está restringido a la pestaña actual en la que estás.

Esto significa que usted podría ahorrar alguna información en su página y mientras el usuario permanezca en esa pestaña, podría acceder a esa misma información incluso si navegó a otro sitio web y viceversa. En general, desaconsejaría usar esto a menos que necesite almacenar información entre dominios durante una sola sesión de navegación.

 140
Author: Stephan Muller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:33:13

Pruebe utilizando $.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
Author: guest271314,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-09 19:52:17

Con localeStorage o sessionStorage parece ser la mejor apuesta.

Intead of saving the clicked variable in the globle scope store it this way:

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
Author: me_digvijay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-06 10:13:12

Puedes probar esto:

 $("input[type='submit'][value='Search']").click(function(){
     form.act.value='detailSearch'; 
     clicked = true;  
     return true;
});
 -3
Author: renakre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-09 16:09:56