domenica, maggio 06, 2007

[JavaScript] Approssimazione intelligente e formattazione nel formato italiano dei numeri

Questa è una funzione JavaScript che ho scritto per approssimare in modo intelligente e formattare nel formato italiano dei prezzi inseriti in una applicazione web che ho creato.

Con "approssimazione intelligente" intendo in realtà una non approssimazione. In pratica questa funzione non tronca i decimali, ma solo quando necessario aggiunge gli zeri.
Cercherò di chiarire meglio le cose con un esempio che riguarda dei prezzi:
- se il prezzo inserito è 100 questo viene trasformato in 100,00
- mentre se il prezzo inserito è 0,045678 questo non viene approssimato a 0,04 ma rimane 0,045678 (1.000.000 x 0,04 = 40.000,00 mentre 1.000.000 x 0,045678 = 45.678,00 => una bella differenza soprattutto visto che sono euro).

Con "formattare nel formato italiano" intendo formattare un numero usando la >,< (virgola) come separatore dei decimali ed il >.< (punto) come separatore delle migliaia.

Ecco la funzione all'interno di una pagina html d'esempio:
<?xml version="1.0"?>
<!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>Approssimo intelligentemente</title>
<script type="text/javascript">
<!--

// Approssima intelligentemente e formatta nel formato it un numero
function approssima(numero, tipo, dec) {
if(tipo == "it") {
// gli tolgo i punti delle migliaia e gli eventuali zeri iniziali
// e lo divido in parte intera e parte non intera
valore = numero.replace(/\.|^0*/g, '').split(',');
}
else {
// gli tolgo le virgole delle migliaia e gli eventuali zeri iniziali
// e lo divido in parte intera e parte non intera
valore = numero.replace(/\,|^0*/g, '').split('.');
}

// nella parte intera metto il punto tra le migliaia
if(valore[0] == '') valore_int = 0;
else {
valore_int = valore[0];
l = valore_int.length;
if(l > 3) {
i = l % 3;
if(i == 0) i = 3;
a = valore_int.substr(0, i);
while(i < l) {
a += '.' + valore_int.substr(i, 3);
i += 3;
}
valore_int = a;
}
}

// formatto e approssimo la parte decimale
if(valore[1] == undefined || valore[1] == '') {
if(dec == 0) valore_dec = '';
else for(i = 0, valore_dec = ","; i < dec; i++) valore_dec += "0";
}
else {
h = valore[1].length;
if(h == dec) valore_dec = "," + valore[1];
else {
if(dec > h) for(i = 0, valore_dec = "," + valore[1]; i < (dec - h); i++) valore_dec += "0";
else {
valore_dec = "".concat(valore[1].substr(0, dec), valore[1].substr(dec).replace(/[0]*$/, ''));
if(valore_dec != '') valore_dec = "," + valore_dec;
}
}
}

document.getElementById('risultato').innerHTML = valore_int + valore_dec;
}

-->
</script>
</head>
<body>

<h3>Approssimo intelligentemente</h3>

<table border="1" cellspacing="1" cellpadding="1">
<tr>
<td>Numero da approssimare: </td>
<td><input id="numero" type="text" size="20" /></td>
</tr>
<tr>
<td>Tipo numero: </td>
<td>
<select id="tipo">
<option value="it">Italiano</option>
<option value="en">Inglese</option>
</select>
</td>
</tr>
<tr>
<td>Numero minimo di decimali: </td>
<td><input id="decimali" type="text" size="4" /></td>
</tr>
<tr>
<th colspan="2"><input type="submit" value="Approssima e Formatta" onclick="approssima(document.getElementById('numero').value, document.getElementById('tipo').value, document.getElementById('decimali').value);" /></th>
</tr>
</table>

<h1 id="risultato">----</h1>

</body>
</html>


Ho usato delle strutture if-else per cercare di velocizzare la funzione visto che, in una versione semplificata (visto che mysql mi restituisce numeri "puliti"), la uso per formattare i dati di una tabella popolata (tramite il framework xajax) da un database mysql.
Purtroppo, nonostante tutto, questa funzione si è rilevata troppo lenta in Firefox, e mi dispiace ammetterlo, molto più veloce in IE.

Sicuramente, visto che non sono un "guru" del JavaScript, questa funzione può essere di sicuro migliorata.
Se avete qualche consiglio per aumentarne la velocità, non esiti a dirmelo !!!

1 commento:

Anonimo ha detto...

... e a che serve?
Già tutti i computer lavorano con "l'approssimazione" che viene qui proposta!