Newsgroup: it.comp.lang.javascript
Titolo: Selezionare tutti gli input di un form e monitorare i cambiamenti

Salve!
Sto mettendo all'opera le mie arti distruttive su un povero file HTML
di prova :-)
L'esigenza del progetto è: quando si modifica un form e si cerca di
passare ad un'altra pagina, il browser deve fermarti e dire "scolta
bello, o salvi le modifiche o le annulli" :-)
Il progetto usa prototype(non so in che versione :-P) io ho scaricato
la 1.6.0.3 dal sito e sto facendo le mie prove con quella.
La parte di Html/JS interessata è questa:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "
http://www.w3.org/TR/html4/loose.dtd
">
<html>
  <head>
  			<title>Test document</title>
				<script language="JavaScript" type="text/javascript" src="/script/
prototype-1.6.0.3.js"></script>
				<script language="JavaScript" type="text/javascript">
          <!--
          		var FormChanged = false;
							function _FormChanged()
							{
							  if ( !FormChanged )
								  FormChanged = true;
							}
							function InitScript()
							{
  							var Frm = $('test');
  							var Inputs;
  							if (Frm != null )
								{
  							  Inputs =  Frm.getInputs();
									Inputs.observe( "change",_FormChanged() );
								}
  							else
  							  window.alert( "Form is null!" );
							}
							function SubmitFrmCheck()
							{
							   if ( FormChanged == true )
								    window.alert( "Form modificata!" );
									return true
							}
          //-->
        </script>
  </head>
  <body onload="InitScript()">
  			<form id="test" name="test" onSubmit = "return SubmitFrmCheck
();">
							<input type="text" name ="TextTest"/>
							<input type="submit" />
				</form>
  </body>
</html>
L'idea di fondo è semplice: prendo tutti gli input della form ed
osservo il loro onChange.
Se viene richiamato vuol dire che la form è stata modificata e quindi
segnalo la cosa.
Purtroppo però prototype non sembra molto d'accordo nel farmelo
fare :-)
Poiché la mia conoscenza della libreria è limitata a ciò che abbiamo
usato nel progetto, adesso mi trovo nella necessità di utilizzare
questa struttura dinamica perché nel progetto finale ogni form è
dinamicamente generata in un DIV(usiamo AJAX.Updater ed AJAX.Request
per la comunicazione C/S).
In buona sostanza, io devo prendere un qualsiasi form, enumerare gli
input ed assegnare ad ogni input un observe sull'onChange.
Credo di essere molto vicino alla scrittura giusta ma non riesco a
capire come farla correttamente.
Guardando sul sito di prototype ho preso l'idea della var Inputs e
dell'assegnamento, però l'errore risultante è che "observe is not a
function"(!?!).
Qualche suggerimento? Dove sbaglio?
Grazie in anticipo,
Andrea

 ();">
Qua ovviamente dovrai metterlo prima della chiamata alla function (o dopo,
vedi te ... )
es. onsubmit="return confirm(...) && SubmitFrmCheck()"
(oppure puoi sfruttare onclick del tasto submit, se return false non esegue
il submit)
-- 
"La realtà è un'illusione causata dall'assenza di alcool."
									      A.

Ciao Cristiano,
Anzitutto grazie del tempo dedicatomi :-)
Al momento, il mio interesse primario è riuscire a capire se è stato
modificato qualche dato.
Quando avrò ottenuto questa cosa, il mio secondo scopo sarà quello di
lasciar proseguire o fermare l'utente(questo è facile, basta usare il
return nell'onSubmit...).
Il "piano" che ho organizzato è piuttosto semplice: io vorrei mettere
tutto il codice comune nel javascript principale del sito, quando poi
viene scatenato l'onLoad enumero le forms(sempre nel JS principale...)
ed aggancio gli observe.
Così facendo, le uniche modifiche necessarie saranno quelle
sull'onSubmit per la singola form, mantenendo tutto il resto
inalterato.
Idealmente, vorrei poter intervenire anche su quello, mettendo una
alert tipo "Gentile utente, ti rendi conto che hai fatto delle
modifiche che non hai salvato? Vuoi salvarle?" e poi facendolo
proseguire con il suo handler standard(ogni form ha una function nel
submit per via di Ajax).
Ciò che non riesco a fare è questa parte qua:
function InitScript()
{
  var Frm = $('test');
  var Inputs;
  if (Frm != null )
  {
     Inputs =  Frm.getInputs();
     Inputs.observe( "change",_FormChanged() );
  }
  else window.alert( "Form is null!" );
}
Firefox mi dice "observe is not a function" il che è ovviamente falso,
nel senso che E' una function di prototype e presumo che non la
veda perché per qualche motivo sbaglio nel chiamarla.
Quale può essere il problema con il mio codice?
Vorrei evitare il JavaScript liscio per due motivi fondamentali:
1) Perché dovrei comunque replicare parte di prototype per non
impazzire, a quel punto tanto vale usarla direttamente :-)
2) Perché sono certo che dal cliente ci sono skill in questa
direzione, quindi sarebbe buona cosa usarla :-)
Hai una pallida idea di cosa sto sbagliando?
Andrea

WOOOOOOOOOOOOO HOOOOOOOOOOOOOOOOOOOOOO!!!
Così funziona :-)
function InitScript()
							{
  							var Frm = $('test');
  							var Inputs;
  							if (Frm != null )
								{
  							  Inputs =  Frm.getInputs();
									Inputs.each( function(item){item.observe('change',_FormChanged
())} );
								}
  							else
  							  window.alert( "Form is null!" );
							}
							function SubmitFrmCheck()
							{
							   if ( FormChanged == true )
								 {
								    return confirm( "Vuoi abbandonare la pagina senza salvare
i dati?");
									}
									else return true
							}
Adesso la seconda parte in un nuovo thread :-)
Andrea

 item.observe('change',_FormChanged());
Non assegna "_FormChanged" all'event-handler "onchange" bensì il
suo risultato. Quindi significa che la funzione invece che esser
eseguita all'onchange dell'elemento, viene eseguita appena viene
assegnata. Per poter associare il riferimento a funzione invece,
basta evitare di "invocarla". Ovvero, rimuovendo le parentesi:
	item.observe('change', _FormChanged);
-- 
"When you have eliminated the impossible, whatever remains, however
improbable, must be the truth."

         item.observe('change', _FormChanged);
Ehm... sarà che sono pignolo ed ho provato secondo il tuo suggerimento
ma sia FireFox che Internet Exploder
sembrano non essere d'accordo con te.
Quando ho tolto le parentesi, magicamente non funzionava più.
Questo può voler dire due cose:
1) Andava bene prima
2) C'è qualcosa di sottilmente sbagliato da qualche parte che è
sfuggito a tutti e due.
Poiché non penso di possedere la verità assoluta, sono apertissimo ad
entrambe le opzioni :-)
Qualche idea?
Andrea

 Qualche idea?
Non ho idea del codice che hai scritto, sta a te capire dov'è l'errore.
Ribadisco ammesso che ci sia. Se "_FormChanged" restituisce a sua volta
una funzione, allora usare le parentesi è corretto... anche se andrebbe
visto se è giusto da un punto di vista logico. Se non lo fa, allora hai
indubbiamente un errore da qualche parte.
Se nonostante il codice di cui sopra hai ancora qualche dubbio sul come
funzioni la cosa, puoi sempre pubblicare anche la funzione _FormChanged
che lo dissipiamo insieme.
