PDA

Visualizza versione completa : [JavaScript] una funzione che non vuol funzionare


Alhazred
02-07-2008, 21.20.26
Sto simulando una pagina HTML per l'acquisto di prodotti online, ma la funzione "totale" non mi funziona, l'avevo fatta in un altro modo ed avevo un problema con gli statement if else, ma almeno qualcosa faceva. Questa invece è come se non venisse attivata, vedete il problema?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Prova acquisto</title>

<SCRIPT TYPE="text/javascript">
<!--
var parziale = 0;
var scelti = new Array();

function arrotonda(numero,decimali)
{
var potenza = Math.pow(10,decimali);
return Math.round(numero * potenza)/potenza;
}

function totale(obj)
{
var trovato = new Boolean(false);
var posizione = 0, i = 0;

if(obj.value.length > 0) //se è stato inserito almeno un carattere
if (obj.value < 0) //se il numero inserito è negativo
{
alert("Non è consentito inserire un numero negativo");
return;
}
if(obj.value.length == 0) //se è stato cancellato lo 0 senza inserire nulla
obj.value = "0"; //riscrive lo 0

//permette solo numeri
quantita = obj.value.replace(/\D/g,"0");
obj.value = quantita;

if (scelti.length > 0) //se non ci sono elementi il controllo è inutile
while (!trovato || i <= scelti.length)
if (obj.name == scelti[i])
{
trovato = true;
posizione = i; //posizione in cui si trova il nome dell'ingrediente nell'array
i = scelti.length+1; //fa terminare il ciclo
}
else i++;

if (trovato)
scelti[posizione+1] = obj.value; //modifica la quantità (che si trova in posizione+1
else //aggiungi all'array
{
scelti.push(obj.name); //inserisce il nome nell'ultima posizione
scelti.push(obj.value); //inserisce la quantità dopo il nome
}
parziale = 0; //azzera il totale parziale per ricalcolarlo
for(i = 0; i < scelti.length; i+2) //ciclo sull'array, +2 perché controllo solo le posizioni con i nomi
{
prezzo = obj.form.elements["pr"+scelti[i]].value; //prendo il prezzo unitario dalla form
parziale = arrotonda((parziale + (prezzo*scelti[i+i])),2); //calcolo il parziale sull'ingrediente corrente e lo sommo ai precedenti
}
obj.form.prztotale.value = parziale; //aggiorno il campo totale della form
}
//-->
</SCRIPT>
</head>

<body>
<table width="877" border="0" cellpadding="0" cellspacing="0">
<!--DWLayoutTable-->
<tr>
<td width="332" height="67">&nbsp;</td>
<td width="344">&nbsp;</td>
<td width="205">&nbsp;</td>
</tr>
<tr>
<td height="197">&nbsp;</td>
<form action=""/>
<td valign="top">
<table width="341" border="1">
<!--DWLayoutTable-->
<tr>
<td width="111" height="23"><div align="center"><strong>Ingrediente</strong></div></td>
<td width="64"><div align="center"><strong>prezzo</strong></div></td>
<td width="144" valign="top"><div align="center"><strong>quantit&agrave;</strong></div></td>
</tr>
<tr>
<td height="26">Patate</td>
<td><input name="prPatate" type="hidden" value="0.50" />0,50</td>
<td valign="top"><input name="Patate" type="text" onChange="totale(this)" value="0" size="3" maxlength="3"/></td>
</tr>
<tr>
<td height="26">Uova</td>
<td><input name="prUova" type="hidden" value="0.08" />0,08</td>
<td valign="top"><input name="Uova" type="text" onchange="totale(this)" value="0" size="3" maxlength="3"/></td>
</tr>
<tr>
<td height="26">Peperoni</td>
<td><input name="prPeperoni" type="hidden" value="0.60" />0,60</td>
<td valign="top"><input name="Peperoni" type="text" onChange="totale(this)" value="0" size="3" maxlength="3"/></td>
</tr>
<tr>
<td height="26">Carciofi</td>
<td><input name="prCarciofi" type="hidden" value="3.20" />3,20</td>
<td valign="top"><input name="Carciofi" type="text" onChange="totale(this)" value="0" size="3" maxlength="3"/></td>
</tr>
<tr>
<td height="26">Spaghetti</td>
<td><input name="prSpaghetti" type="hidden" value="0.85" />0,85</td>
<td valign="top"><input name="Spaghetti" type="text" onChange="totale(this)" value="0" size="3" maxlength="3"/></td>
</tr>
<tr>
<td height="26"></td>
<td><strong>Totale</strong></td>
<td valign="top"><input name="prztotale" type="text" value="0" readonly /></td>
</tr>
</table></td>

</tr>
<tr>
<td height="186">&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</body>
</html>

shadowDK
03-07-2008, 08.43.09
<SCRIPT TYPE="text/javascript">
<!--
var parziale = 0;
var scelti = new Array();

function arrotonda(numero,decimali)
{
var potenza = Math.pow(10,decimali);
return Math.round(numero * potenza)/potenza;
}

function totale(obj)
{
var trovato = new Boolean(false);
var posizione = 0, i = 0;

if(obj.value.length > 0) //se è stato inserito almeno un carattere
if (obj.value < 0) //se il numero inserito è negativo
{
alert("Non è consentito inserire un numero negativo");
return;
}
if(obj.value.length == 0) //se è stato cancellato lo 0 senza inserire nulla
obj.value = "0"; //riscrive lo 0

//permette solo numeri
quantita = obj.value.replace(/\D/g,"0");
obj.value = quantita;

if (scelti.length > 0) //se non ci sono elementi il controllo è inutile
while (!trovato || i <= scelti.length)
if (obj.name == scelti[i])
{
trovato = true;
posizione = i; //posizione in cui si trova il nome dell'ingrediente nell'array
i = scelti.length+1; //fa terminare il ciclo
}
else i++;

if (trovato)
scelti[posizione+1] = obj.value; //modifica la quantità (che si trova in posizione+1
else //aggiungi all'array
{
scelti.push(obj.name); //inserisce il nome nell'ultima posizione
scelti.push(obj.value); //inserisce la quantità dopo il nome
}
parziale = 0; //azzera il totale parziale per ricalcolarlo
for(i = 0; i < scelti.length; i=i+2) //ciclo sull'array, +2 perché controllo solo le posizioni con i nomi
{
prezzo = obj.form.elements["pr"+scelti[i]].value; //prendo il prezzo unitario dalla form
parziale = arrotonda((parziale + (prezzo*scelti[i+i])),2); //calcolo il parziale sull'ingrediente corrente e lo sommo ai precedenti
}
obj.form.prztotale.value = parziale; //aggiorno il campo totale della form
}
//-->
</SCRIPT>


i = i + 2
nel for...

però per qualche motivo che non capisco non entra nel for...esegue fino all'istruzione prima!

Gergio
03-07-2008, 09.26.23
prova a mettere prima e dopo i vari blocchi delle stampe a video (o degli alert) con i valori delle variabili che usi e scopri dove c'e' il comportamento che non ti aspetti

Alhazred
03-07-2008, 09.52.04
Grazie per le risposte.
i = i + 2
nel for...
i = i+ 2 nel for mi serve perché con questo mi interessa trovare solo le posizioni in cui ci sono scritti i nomi dei prodotti e da come è strutturato l'array si trovano tutti in posizione pari:
0: nome prodotto 1
1: quantità prodotto 1
2: nome prodotto 2
3: quantità prodotto 2
4: nome prodotto 3
5: quantità prodotto 3
e così via...
prova a mettere prima e dopo i vari blocchi delle stampe a video (o degli alert) con i valori delle variabili che usi e scopri dove c'e' il comportamento che non ti aspetti
Ho già provato a mettere degli alert, ma non ne vengo a capo... javascript mi risulta proprio strano.

A proposito, se ho una variabile booleana come "trovato" nel mio codice di prima, scrivere if(trovato) e if(trovato == true) oppure if(!trovato) e if(trovato == false) è la stessa cosa? Perché l'altra versione di cui parlavo nel primo post non funzionava perché nelle condizioni avevo usato la forma breve, esplicitando il valore che mi aspetto della variabile booleana invece funziona correttamente.

shadowDK
03-07-2008, 09.57.44
io dicevo che tu nel for hai scritto i+2 invece di i=i+2...
mi sono permesso di scaricare il tuo codice e di testarlo con degli alert...funziona bene (perfettamente) fino al for, poi nel for entra sebbene scegli.length sia maggiore di 0...
premetto però che anche a me il javascript risulta ostico...

shadowDK
03-07-2008, 10.09.29
Trovato...mamma che fatica però...

correggivar trovato = new Boolean(false); in var trovato = false;...ora dovrebbe funzionare!
Fammi sapere!

Alhazred
03-07-2008, 10.18.28
Ah, dell'i+2 non me ne ero accorto, ho corretto.
Ho fatto anche la modifica che mi hai suggerito, ma non funziona ugualmente, come prima la funzione è come se non venisse attivata, ho messo un alert subito dopo la dichiarazione della variabile trovato... non viene eseguito :confused:

Alhazred
03-07-2008, 10.25.04
Ho copiato e incollato il codice che avevo messo nel primo post e l'ho sostituito a quello che stavo usando, ho fatto le stesse modifiche e adesso la funzione lavora, anche se non fa esattamente quello che dovrebbe.

Javascript mi fa impazzire!

shadowDK
03-07-2008, 11.00.30
ahah...è proprio comica...sono stato un po' a lavorarci sopra anch'io e, togliendo dal while la condizione !trovato, funziona! ma non so se fa quello che vuoi tu, diciamo che il totale viene giusto!

Gergio
03-07-2008, 11.19.29
ho messo un alert subito dopo la dichiarazione della variabile trovato... non viene eseguito :confused:
questo potrebbe essere perche' il tuo browser ricarica la pagina che ha nella cache ;)

Alhazred
09-07-2008, 00.16.59
Cosa ci trovate di strano in questo ciclo while? Non temina mai, mi va in loop, praticamente col debugger vedo che la variabile i cresce indefinitamente, scelti.length vale 2, controllato sempre col debugger e nello scenario che sto provando trovato vale false.

while (!trovato || i <= scelti.length)
{
if (obj.name == scelti[i])
{
trovato = true;
posizione = i; //posizione in cui si trova il nome dell'ingrediente nell'array
i = scelti.length+1; //fa terminare il ciclo
}
else i++;
}

shadowDK
09-07-2008, 08.32.43
Il tuo codice:


while (!trovato || i <= scelti.length)
{
if (obj.name == scelti[i])
{
trovato = true;
posizione = i; //posizione in cui si trova il nome dell'ingrediente nell'array
i = scelti.length+1; //fa terminare il ciclo
}
else i++;
}

diventa questo:

while (i < scelti.length)
{
if (obj.name == scelti[i])
{
trovato = true;
posizione = i; //posizione in cui si trova il nome dell'ingrediente nell'array
i = scelti.length+1; //fa terminare il ciclo
}
else i++;
}

Tu usi un doppio controllo, non ti serve trovato, usi già i = scelti.length+1 che ti fa uscire dal ciclo!!!
poi io metteri, nella condizione del while, i<scelti.length, invece di i <=...

Alhazred
09-07-2008, 09.36.05
Si, hai ragione e come dici tu effettivamente funziona, ma il doppio controllo pur essendo superfluo non mi sembra sintatticamente sbagliato, si ritroverebbe vere entrambe le condizioni... perché non funziona?

shadowDK
09-07-2008, 09.44.39
Allora, invece credo sia proprio la condizione ad essere sbagliata...a te serve che lui quando trovato è false e i < scelti.length, quando una delle due condizioni viene a mancare deve uscire...quindi
while(!trovato && i < scelti.length)

comunque, queste sono le piccole cose che uno non vede quasi mai quando ha scritto il codice...questi errori chiedendo ad un "esterno" si risolvono sempre in 3 secondi, incredibile!

Alhazred
09-07-2008, 10.57.14
Oh porcaccia miseria... hai ragione!

Il fatto è che chi scrive il codice resta convinto della condizione and oppure or che ha scelto, dando per scontato che sia giusta e si impunta solo sui valori che assumono le clausole.