Estoy tratando de capturar la pulsación del botón de envío 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 se envió antes o no y si se envió al recargar, 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 probé:
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
}
});
¿Alguna sugerencia sobre lo que está mal con este código?
preventDefault
en elsubmit
evento (en lugar delclick
que está usando).Respuestas:
Como HTTP no tiene estado, cada vez que cargue la página, usará los valores iniciales de lo que establezca en JavaScript. No puede establecer una variable global en JS y simplemente hacer que ese valor permanezca después de cargar la página nuevamente.
Hay un par de formas en que puede almacenar el valor en otro lugar para que pueda inicializarlo en la carga usando JavaScript
Cadena de consulta
Al enviar un formulario utilizando el
GET
método, la URL se actualiza con una cadena de consulta (?parameter=value&something=42
). Puede utilizar esto configurando un campo de entrada en el formulario con un valor determinado. 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
yvalue
de la entrada se pasa en la cadena de consulta comoclicked=true
. Entonces, cuando la página se cargue nuevamente con esa cadena de consulta, puede verificar si se hizo clic en el botón.Para leer estos datos, puede utilizar el siguiente script al cargar la página:
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');
( Fuente )
La capacidad de usar esto depende de cómo funcione su formulario actualmente, si ya usa un POST, esto podría ser problemático.
Además, para conjuntos de datos más grandes, esto no es óptimo. Pasar una cadena no es un gran problema, pero para las matrices y los 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 obtuvimos almacenamiento web, que le permite guardar información en el navegador a través de cargas de página. Existe la
localStorage
que puede guardar datos durante un período más largo (siempre que el usuario no los borre manualmente) y lasessionStorage
que guarda datos solo durante su sesión de navegación actual. Este último es útil para usted aquí, porque no desea mantener "clic" establecido en verdadero cuando el usuario regrese más tarde.Aquí configuro el almacenamiento en el evento de clic de botón, pero también puede vincularlo al envío de formulario 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 hacerlo, use:
sessionStorage.removeItem('clicked');
Si desea guardar un objeto o matriz JS, debe convertirlo en una cadena. Según la especificación, 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 usarlo a menos que necesite ser compatible con navegadores realmente antiguos / oscuros. Web Storage es el futuro.
Galletas
Una alternativa al almacenamiento web es guardar los datos en una cookie. Las cookies están diseñadas principalmente para leer datos del lado del servidor, pero también se pueden utilizar para datos puramente del lado del cliente.
Ya usas jQuery, lo que facilita la configuración de cookies. Nuevamente, utilizo el
click
evento 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 a lo largo de las sesiones en su caso, deberá desactivarlas tan pronto como haya hecho lo que sea necesario para hacer con ellas. No querrá que el usuario regrese un día después y aún así se haya
clicked
configurado como verdadero.if(clicked === "true") { //doYourStuff(); $.cookie('clicked', null); }
(una forma no jQuery para configurar / leer cookies se puede encontrar aquí )
Personalmente, no usaría una cookie para algo tan simple como recordar un estado en el que se hizo clic, pero si la cadena de consulta no es una opción y necesita ser compatible con navegadores realmente antiguos que no admiten sessionStorage, esto funcionará. Primero debe implementar eso con una verificación de sessionStorage, y solo si eso falla, use el método de cookies.
window.name
Aunque esto me parece un truco que probablemente se originó antes de localStorage / sessionStorage, podría almacenar información en la
window.name
propiedad:window.name = "my value"
Solo puede almacenar cadenas, por lo que si desea guardar un objeto, deberá clasificarlo como en el
localStorage
ejemplo anterior :window.name = JSON.stringify({ clicked: true });
La principal diferencia es que esta información se conserva no solo en las actualizaciones de página, sino también en diferentes dominios. Sin embargo, está restringido a la pestaña actual en la que se encuentra.
Esto significa que puede guardar cierta información en su página y, siempre que el usuario permanezca en esa pestaña, puede acceder a esa misma información incluso si navega a otro sitio web y regresa. En general, aconsejaría no usar esto a menos que realmente necesite almacenar información entre dominios durante una sola sesión de navegación.
fuente
window.name
). Puede que haga exactamente lo que necesita sin usar cookies / localStorage.Intente utilizar
$.holdReady()
,history
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 src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form method="POST"> <input type="text" name="name" value="" /> <input type="submit" value="Search" /> <input type="hidden" /> <input type="hidden" /> </form>
fuente
Usar
localeStorage
osessionStorage
parece ser la mejor opción.En lugar de guardar la
clicked
variable en el alcance globle, guárdelo de esta manera: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 } });
fuente
Puedes probar esto:
$("input[type='submit'][value='Search']").click(function(){ form.act.value='detailSearch'; clicked = true; return true; });
fuente