2009-11-12 17 views
17

Tengo un formulario con una matriz de campos de texto. El usuario (a través de javascript) puede agregar una cantidad arbitraria de campos de texto al formulario. Después de enviar el formulario y presionar el botón Atrás, el formulario solo se muestra con los campos que estaban en el formulario original cuando se procesó por primera vez (cualquier campo de texto agregado se pierde). ¿Cuál es la mejor manera de permitir que el botón Atrás muestre el formulario en el estado cuando el usuario lo envió? Cualquier ideas son bienvenidas, algunas cosas que he probado son:Controlador de botón posterior Un formulario dinámico

  • puso a los datos del formulario en una cookie (esto no funciona grande para un par razones, pero la principal causa de muerte para mí es que las galletas son limitado a 4K en tamaño)
  • puso a los datos del formulario en una sesión
  • Envíe el formulario a través de AJAX y luego administrar la historia

Gracias por la ayuda. He publicado un formulario de prueba en mi sitio web al http://fishtale.org/formtest/f1.php. También aquí es una forma sencilla que exhibe el comportamiento que he mencionado:

<form action="f2.php" method="post"> 
<input type="text" name="text[]" id="text1"/> 
<input type="submit" name="saveaction" value="submit form" /> 
</form> 

<a href="f2.php" id="add_element">Add Form Element</a> 

<script type="text/javascript" 
     src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" ></script> 

<script type="text/javascript" > 
    $('#add_element').click(function (event) { 
     event.preventDefault(); 
     $('#text1').after('<input type="text" name="text[]" />'); 
    }); 
</script> 

Esto es similar a una pregunta que he publicado hace un tiempo, Best Way For Back Button To Leave Form Data, sin embargo, los elementos de este formulario son modificados por el usuario.

+0

Hola Brian, ¿te opones a usar una cookie temporal para almacenar los valores? ¿Cuántos campos agregarían generalmente sus usuarios? Proporcionaré código si esto incluso suena remotamente como una buena solución. –

+0

Hola Doug, Los usuarios están creando una tarjeta de tiempo, por lo que pueden estar agregando bastantes elementos del orden de 100. No estoy seguro si me opongo a las cookies temporales, si funcionan, soy todo para ellos . Creo que pueden causar problemas para las otras cookies si el tamaño total de las cookies supera el 4K máximo. Gracias. –

Respuesta

11

No puedo encontrar una biblioteca preescrita para esto, pero estoy seguro de que se ha resuelto antes. Si tuviera que yo mismo me gustaría tener este enfoque:

  1. Uso del command pattern de manera que cada método que modifica la interfaz de usuario de la página mediante la adición de controles también invoca un método AJAX para empujar el método invocado (textual Javascript representación) en una cola almacenada en la sesión del servidor.

  2. Después de completar body onLoad, use un método AJAX para consultar la sesión del servidor para una cola de comandos para la página en la que se encuentra el usuario. Si se recupera uno, solo eval cada miembro de la cola para reconstruir la IU de la página en el mismo orden en que lo hizo el usuario.

Tenga en cuenta que con este enfoque no solo está grabando adiciones de controles, sino también eliminaciones. Necesitará titulares de estado separados para los controles de entrada del usuario, como cuadros de texto (probablemente también necesitará una sesión del lado del servidor con acceso al método AJAX).

+0

Suena interesante, lo intentaré. Mencionas "titulares estatales separados para los controles de entrada del usuario", ¿qué quieres decir con esto? Gracias. –

+1

Si un clic de botón agrega un cuadro de texto ('text2'), su método insertará un 'addTextBox (' text2 ');' Comando de JavaScript para su servicio AJAX. Eso está bien y bien. El problema es que el usuario va a escribir texto en dicho cuadro de texto. Necesitará estos cuadros de texto (u otros controles) para retransmitir dichos datos al servidor, de modo que cuando vuelva a crear la interfaz de usuario, también recree los valores que el usuario ingresó en los controles. Puede usar el patrón de comando para resolver esto también presionando las funciones de JavaScript para establecer valores en la cola de comandos. – cfeduke

+0

No * tiene * que ser una biblioteca para hacer exactamente esto, lamentablemente buscar en Google "grabar y reproducir Javascript" no me parece correcto. – cfeduke

-3

Puede hacer su propio botón de retroceso en la parte superior de la página web y hacerlo más grande y más bonito que el botón de retroceso del navegador web estándar.

Debajo del capó, su código podría saber cuál era el estado anterior y volver a él o si no había estado anterior, puede llamar a la función de retorno del navegador?

+0

Gracias por la idea, de hecho ya lo hago, sin embargo, algunos usuarios aún hacen clic en el otro botón Atrás (incluyéndome a mí mismo a veces). –

+1

Hacer tu propio botón de retroceso es una idea horrible :) –

+0

Sí, tienes razón. Esa ES una mala idea. –

12

¿Qué le parece crear un <input type="hidden"> (sin name o fuera del formulario para que no se envíe) en el que almacena una lista codificada de campos adicionales para agregar y sus valores? Si bien el navegador no recordará los campos recién agregados en 'atrás', será recuerde los valores de los campos ocultos que estaban en el formulario desde el principio.

Aquí hay un ejemplo que guarda los campos adicionales sobre el documento de descarga y los recupera en la lista:

<input type="hidden" id="remembertexts" /> 

<form action="http://www.google.com/" method="get"> 
    <div id="texts"> 
     <input type="text" name="text[]" value="" /> 
    </div> 
    <div> 
     <input type="submit" /> 
     <input type="button" id="addtext" value="+" /> 
    </div> 
</form> 

<script type="text/javascript"> 

    // Add new field on button press 
    // 
    $('#addtext').click(function() { 
     addInput(''); 
    }); 

    function addInput(text) { 
     $('#texts input').eq(0).clone().val(text).appendTo('#texts'); 
    }; 

    // Store dynamic values in hidden field on leaving 
    // 
    $(window).bind('beforeunload', function() { 
     var vals= []; 
     $('#texts input').each(function() { 
      vals.push(encodeURIComponent(this.value)); 
     }); 
     $('#remembertexts').val(vals.join(';')); 
    }); 

    // Retrieve dynamic values on returning to page 
    // 
    $(function() { 
     var extratexts= $('#remembertexts').val().split(';').slice(1); 
     $.each(extratexts, function() { 
      addInput(decodeURIComponent(this)); 
     }); 
    }); 
</script> 

Notas:

  • Puede utilizar form.onsubmit en lugar de window.onbeforeunload si solamente se necesita recordar valores sobre una presentación. onunload no funciona, ya que algunos navegadores ya habrán almacenado los valores del formulario anterior antes de que ocurra ese evento.

  • En Firefox, la posición de la entrada oculta es importante. Por alguna razón, si lo coloca debajo de los campos agregados dinámicamente, Firefox se confunde sobre qué entrada es y no recuerda el valor.

  • Este ejemplo no funciona en Opera. Se puede hacer que funcione en Opera, pero es un dolor. La invocación de Opera de los eventos de carga y descarga es incoherente, por lo que debe usar OnSubmit en su lugar, o establecer el campo oculto en un intervalo de sondeo, o algo así. Peor aún, cuando Opera recuerda los valores previos del campo de formulario, en realidad no los llena hasta que se haya activado la carga de. Esto ya causa muchos problemas de creación de scripts. Puede solucionar esto poniendo un tiempo de espera pequeño en su carga para esperar hasta que los valores de forma hayan ingresado si necesita la compatibilidad de Opera.

+0

Puede tropezar con esto: http://stackoverflow.com/questions/1274138/jquery-issue-with-live-events-a-form-and-the-back-button –

+1

Esto es totalmente genial! ¡Sin necesidad de sesiones, AJAX, cookies y todo eso! ¡Estupendo! – Uooo

-3

Bloquea el uso del botón Atrás. Cuando se presiona el botón Atrás, vuelva a enviar la página anterior para el usuario con los nuevos campos incluidos, ya sea visiblemente si tiene sentido u oculto. De esta forma, el usuario puede usar el botón de retroceso normalmente y usted tiene control total sobre la apariencia de la página '' anterior ''.

En su caso de uso específico, solo tiene que mostrar la página con todos los campos visibles y rellenar con los valores que se enviaron.

Este es un buen patrón a seguir para cualquier tipo de proceso de asistente en el que proporcione una secuencia de formularios para que el usuario complete y puedan optar por volver a un formulario anterior.

Para que quede perfectamente claro, sugiero que use this advice on capturing the onUnload event para activar el envío del formulario (para que obtenga los valores ingresados) y para reenviar la página anterior que se habría mostrado "atrás" (sin los valores). La única alternativa es usar Ajax para enviar los valores ingresados ​​cada vez que el usuario abandona un campo, y luego verifique cada página con el servidor a través de AJAX para recuperar valores adicionales para mostrar.

Estas son algunas de las páginas adicionales que discuten que toman el control de la función del botón de atrás y utilizando el evento de descarga para persistir datos de formularios:

+0

La pregunta aquí es ... cómo reenviar la página anterior con los valores enviados por el usuario. Y no olvide que el usuario puede alterar los valores y enviar de nuevo. Incluso pueden eliminar algunos valores. – Nirmal

+0

Comentario extraño. La aplicación en el servidor tiene los valores enviados por el usuario y debe saber cómo reenviar la página anterior (que también se representa) utilizando los valores adicionales enviados por el usuario. O eliminado por el usuario. El punto es que después de hacer clic en enviar, el estado existe en el servidor, y si desea mantener ese estado en la página que el usuario ve, puede mostrar la página con ese estado incluido para que el estado esté ahora en el cliente. –

7

En buena b Filas puede hacer que funcione perfectamente simplemente por sin romperlo.

Firefox 1.5 utiliza el almacenamiento en memoria caché en memoria para páginas web enteras, incluidos sus estados de JavaScript, para una sola sesión de navegador. Avanzar y retroceder entre las páginas visitadas no requiere carga de página y los estados de JavaScript se conservan. source

Esto se apoya en Opera y WebKit también. Sin embargo caché DOM sólo es posible en que se adhieren a las reglas:

  1. no utilice onunload, onbeforeunload.
  2. No utilice Cache-control: no-store o must-revalidate.
    En PHP debe cambiar session.cache_limiter de patently_ridiculous (creo que lo deletrean nocache) a none.

    session_cache_limiter('none'); 
    
  3. Desafortunadamente HTTPS también está disponible.

Si no obliga a los navegadores a volver a cargar la página, no lo harán. Mantendrán el DOM y sus valores sin cambios, exactamente como RFC 2616 suggests.


Sin embargo, si usted está buscando un lugar para guardar los datos, no hay truco remate - window.name can store megabytes of data. No se envía al servidor y no se comparte entre ventanas.

También hay cookies de Flash y HTML 5 localStorage se implementa en IE8 y Safari 4.

+1

En mi ejemplo, los campos agregados dinámicamente por javascript no se vuelven a crear cuando presiono el botón Atrás en FF3.5, Chrome o IE 8. Creo que mis encabezados http están configurados correctamente. También intenté usar session_cache_limiter ('none'), pero no cambié. ¿Se me escapa algo? –

+4

jQuery usa onunload para tapar las pérdidas de memoria de IE, y onunload breaks caching: http://groups.google.com/group/jquery-dev/browse_thread/thread/67abd50cd3ef0fc8 – Kornel

+0

Otro hilo sobre jQuery rompiendo esto: http: // friendfeed. com/paul/2b7ddce5/jquery-1-3-breaks-bfcache-because-it-binds –

0

Paso 2: El script que procesa el formulario pone los valores introducidos en una matriz y tiendas de esa matriz en una variable de sesión (o text/db/lo que encuentre apropiado).

Paso 1: El script que genera el formulario agrega un javascript (que a su vez rellena el formulario) si se encuentra esa variable de sesión (y también borra la variable de sesión).

Cuestiones relacionadas