2009-11-12 14 views
17

Ho un modulo con una matrice di campi di testo. L'utente (tramite javascript) può aggiungere un numero arbitrario di campi di testo al modulo. Dopo aver inviato il modulo e premuto il pulsante Indietro, il modulo viene visualizzato solo con i campi presenti nel modulo originale al momento del primo rendering (eventuali campi di testo aggiunti vengono persi). Qual è il modo migliore per consentire al pulsante Indietro di rendere il modulo nello stato quando l'utente lo ha inviato? Tutte le idee sono benvenute, alcune cose che ho provato sono:Pulsante Indietro Gestisce un modulo dinamico

  • Mettere i dati del modulo in un cookie (questo non funziona grande per un paio ragioni, ma il più grande assassino per me è che i cookie sono limitata a 4K in dimensioni)
  • Mettere i dati del modulo in una sessione
  • Inviare il modulo tramite la tecnologia AJAX e quindi gestire la storia

Grazie per l'aiuto. Ho pubblicato un modulo di test sul mio sito web al http://fishtale.org/formtest/f1.php. Anche qui è una forma semplice esibendo il comportamento che ho citato:

<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> 

Questo è simile a una domanda che ho postato qualche tempo fa, Best Way For Back Button To Leave Form Data, tuttavia, gli elementi di questa forma sono modificabili dall'utente.

+0

Ehi Brian, sei contrario a utilizzare un cookie temporaneo per memorizzare i valori. Quanti campi aggiungerebbero in genere i tuoi utenti? Fornirò il codice se questo suona anche lontanamente come una buona soluzione. –

+0

Hey Doug, Gli utenti stanno creando una tabella di marcia, quindi possono aggiungere alcuni elementi dell'ordine di 100. Non sono sicuro se sono contrario ai cookie temporanei, se funzionano sono tutti per loro . Penso che potrebbero causare problemi per gli altri cookie se la dimensione totale dei cookie supera il limite massimo di 4K. Grazie. –

risposta

11

Non riesco a trovare una libreria già scritta per questo, ma sono sicuro che è stata risolta prima. Se dovessi io stesso vorrei prendere questo approccio:

  1. Utilizzare il command pattern in modo che ogni metodo che modifica dell'interfaccia utente della pagina con l'aggiunta di controlli invoca anche un metodo AJAX per spingere il metodo richiamato (testuali Javascript rappresentazione) su una coda memorizzata nella sessione del server.

  2. Dopo il completamento del body onLoad, utilizzare un metodo AJAX per interrogare la sessione del server per una coda comandi per la pagina su cui si trova l'utente. Se ne viene recuperato uno, è sufficiente che eval ciascun membro della coda ricostruisca l'interfaccia utente della pagina nello stesso ordine in cui l'utente lo ha eseguito.

Tenere a mente con questo approccio si registrano non solo le aggiunte di controlli, ma anche le rimozioni. Saranno necessari titolari di stati separati per i controlli di input dell'utente, come le caselle di testo (è anche probabile che sia necessaria una sessione lato server con accesso al metodo AJAX).

+0

Sembra interessante, farò un tentativo. Si parla di "titolari di stati separati per i controlli di input dell'utente" cosa intendi con questo? Grazie. –

+1

Se un clic del pulsante aggiunge una casella di testo ("testo2"), il metodo spingerà un 'addTextBox ("text2");' Comando JavaScript per il tuo servizio AJAX. Va tutto bene e bene. Il problema è che l'utente digiterà il testo in detta casella di testo. Avrai bisogno di queste caselle di testo (o di altri controlli) per ritrasmettere tali dati al server, così quando ricreerai l'interfaccia utente, ricreerai anche i valori immessi dall'utente nei controlli. È possibile utilizzare lo schema di comando anche per risolvere questo problema, premendo le funzioni JavaScript per impostare i valori nella coda comandi. – cfeduke

+0

Là * ha * di essere una libreria là fuori per fare proprio questo, sfortunatamente googling per "record e replay Javascript" non mi indica esattamente. – cfeduke

-3

È possibile creare il proprio pulsante indietro nella parte superiore della pagina Web e renderlo più grande e più grazioso del pulsante Indietro del browser Web standard.

Sotto il cofano il tuo codice potrebbe sapere qual era lo stato precedente e ripristinarlo o se non ci fosse stato precedente puoi chiamare la funzione di back del browser?

+0

Grazie per l'idea, in realtà lo faccio già, tuttavia, alcuni utenti continuano a fare clic sull'altro pulsante indietro (incluso me stesso a volte). –

+1

Fare il tuo pulsante di ritorno è un'idea orribile :) –

+0

Sì, hai ragione. Questa è una cattiva idea. –

12

Come creare un <input type="hidden"> (senza name o al di fuori del modulo in modo che non venga inviato) in cui si memorizza un elenco codificato di campi aggiuntivi da aggiungere e i relativi valori? Mentre il browser non ricorda i campi aggiunti di recente su "indietro", lo sarà ricordare i valori dei campi nascosti che erano nel modulo dall'inizio.

Ecco un esempio che salva i campi extra documento scarico e li recupera il pronto:

<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> 

Note:

  • È possibile utilizzare form.onsubmit invece window.onbeforeunload se solo avete bisogno di ricorda i valori su una sottomissione. onunload non funziona poiché alcuni browser hanno già memorizzato i vecchi valori del modulo prima che si verifichi tale evento.

  • In Firefox la posizione dell'input nascosto è importante. Per qualche ragione, se lo metti sotto i campi aggiunti dinamicamente, Firefox si confonde su quale input è e non riesce a ricordare il valore.

  • Questo esempio non funziona in Opera. Può essere fatto funzionare in Opera, ma è un dolore. La chiamata di Opera degli eventi di caricamento e scaricamento non è coerente, pertanto è necessario utilizzare onsubmit o impostare il campo nascosto in un intervallo di polling o qualcosa del genere. Peggio ancora, quando Opera ricorda i precedenti valori dei campi di forma, in realtà non li riempie fino al dopo che l'onload è stato licenziato! Ciò causa già molti, molti problemi di scripting di moduli. Puoi aggirare il problema inserendo un piccolo timeout nel tuo onload per attendere che i valori del modulo siano entrati se hai bisogno della compatibilità di Opera.

+0

Puoi inciampare su questo: http://stackoverflow.com/questions/1274138/jquery-issue-with-live-events-a-form-and-the-back-button –

+1

Questo è assolutamente geniale! Non c'è bisogno di sessioni, AJAX, biscotti e tutto il resto! Grande! – Uooo

-3

Blocca l'uso del pulsante Indietro. Quando si preme il pulsante Indietro, si esegue il rerender della pagina precedente per l'utente con i nuovi campi inclusi, sia visivamente se ciò ha un senso, o nascosto. In questo modo l'utente è in grado di utilizzare normalmente il pulsante Indietro e ha il pieno controllo sull'aspetto della pagina '' precedente ''.

Nel tuo caso d'uso specifico, devi solo rendere la pagina con tutti i campi visibili e riempiti con i valori che sono stati inviati.

Questo è un buon schema da seguire per qualsiasi tipo di procedura guidata in cui si fornisce una sequenza di moduli che l'utente può compilare e può scegliere di tornare a un modulo precedente.

Per rendere perfettamente chiaro, sto suggerendo che si utilizza per attivare this advice on capturing the onUnload event modulo di presentazione (in modo da ottenere i valori inseriti) e rerender la pagina precedente che "indietro" avrebbe mostrato (senza i valori). L'unica alternativa è usare Ajax per inviare i valori immessi ogni volta che l'utente lascia un campo, e quindi avere ogni pagina di controllo con il server tramite AJAX per recuperare ulteriori valori da visualizzare.

Ecco alcune pagine aggiuntive che discutere prendendo il controllo sulla funzione del pulsante indietro e che utilizzano l'evento unload a persistere forme di dati:

+0

La domanda qui è .. come rerender la pagina precedente con i valori inviati dall'utente. E non dimenticare che l'utente può modificare i valori e inviare di nuovo. Possono persino cancellare alcuni valori. – Nirmal

+0

Strano commento. L'applicazione sul server ha i valori inviati dall'utente e deve sapere come eseguire il riesecuzione della pagina precedente (che viene anche sottoposta a rendering) utilizzando i valori aggiuntivi inviati dall'utente. O cancellato dall'utente. Il punto è che dopo aver fatto clic su submit, lo stato esiste nel server e se vuole mantenere quello stato nella pagina che l'utente visualizza, può rendere la pagina con quello stato incluso in modo che lo stato sia ora sul client. –

7

In buono stato I filer puoi far funzionare perfettamente semplicemente il senza romperlo.

Firefox 1.5 utilizza il caching in memoria per intere pagine Web, inclusi i relativi stati JavaScript, per una singola sessione del browser. Andare avanti e indietro tra le pagine visitate non richiede il caricamento della pagina e gli stati JavaScript sono preservati. source

Questo è supportato in Opera e WebKit troppo. Tuttavia cache di DOM è possibile solo in si tiene fede alle regole:

  1. non utilizzare onunload, onbeforeunload.
  2. Non utilizzare Cache-control: no-store o must-revalidate.
    In PHP è necessario modificare session.cache_limiter da patently_ridiculous (penso che lo si scrive nocache) a none.

    session_cache_limiter('none'); 
    
  3. Purtroppo anche HTTPS è disponibile.

Se non si forza il browser a ricaricare la pagina, non lo faranno. Manterranno il DOM e i suoi valori invariati, esattamente come RFC 2616 suggests.


Tuttavia, se siete in cerca di posto per riporre i dati, non c'è trucco incredibilmente intelligente - window.name can store megabytes of data. Non viene inviato al server e non è condiviso tra le finestre.

Ci sono anche i cookie Flash e HTML 5 localStorage è implementata in IE8 e Safari 4.

+1

Nel mio esempio i campi aggiunti dinamicamente da javascript non vengono ricreati quando premo il pulsante Indietro in FF3.5, Chrome o IE 8. Credo che le mie intestazioni http siano impostate correttamente. Ho anche provato ad usare session_cache_limiter ('none'), ma nessuna modifica. C'è qualcosa che mi manca? –

+4

jQuery utilizza onunload per collegare perdite di memoria IE e onunload interruzioni nella memorizzazione nella cache: http://groups.google.com/group/jquery-dev/browse_thread/thread/67abd50cd3ef0fc8 – Kornel

+0

Un altro argomento su jQuery che infrange questo: http: // friendfeed. com/Paul/2b7ddce5/jquery da-lega-1-3-break-bfcache-perché- –

0

Fase 2: Lo script l'elaborazione del modulo mette i valori inseriti in un array e negozi che array in una variabile di sessione (o testo/db/qualsiasi cosa tu ritenga appropriato).

Passo 1: lo script che emette il modulo aggiunge un javascript (che a sua volta compila il modulo) se viene trovata quella variabile di sessione (e cancella anche la variabile di sessione).

Problemi correlati