[JS] Afrondingsprobleem in textveld

Pagina: 1
Acties:

  • Martine
  • Registratie: Mei 2002
  • Niet online
Momenteel ben ik bezig om een donatie pagina te maken, het minimaal te doneren bedrag is 1,00 euro. Het maximale bedrag 10.000,00 euro. Dit wordt gecontroleerd in php nadat je het formulier submit.

Het probleem;
Als ik met de onderstaande scriptje een bedrag van 10.50 invul, dan wordt hier 1.050,00 van gemaakt.
Als ik 4500.00 invoer, dan wordt hier 450.000,00 van gemaakt, leuk maar het is veel te veel.

Als ik de eerste in de functie (getal.replace) verwijder en voer ik 4500.00 in, wordt er 4.500,00 van gemaakt wat ook de bedoeling is. Als ik dan naast het invoerveld klik er er vervolgens weer op wordt het bedrag (4.500,00) gewijzigd in 4,50.

Hoe moet ik dit oplossen?


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    function FormatPrice(getal) {
        getal = getal.replace(".","");
        getal = getal.replace(",",".");
        getal = parseFloat(getal);
        getal = parseFloat(getal).toFixed(2);
        getal = getal.replace(".",",")
        var nr = getal + "";
        var part = nr.substr(nr.length%3);
        part = (nr.substr(0, nr.length%3) + part.replace(/([0-9]{3})/gi, ".$1"));
        if(part.charAt(0)==".")
            getal = part.substr(1,part.length);
        else
            getal = part;
        
        if (getal == 'NaN')
            getal = '1,00';
        
        return getal;
    }

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Het enige wat je wil checken is volgens mij of er een regex: [\.\,][0-9]{1-2}
in zit. Zo ja, dan zijn dat je centen, zo nee, dan staan er alleen hele euro's in het invoerveld.
Nadat je dit weet kun je makkelijk de rest opmaken lijkt me :)

oprecht vertrouwen wordt nooit geschaad


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10 13:03
Atgast schreef op vrijdag 05 januari 2007 @ 15:00:
Het enige wat je wil checken is volgens mij of er een regex: [\.\,][0-9]{1-2}
in zit. Zo ja, dan zijn dat je centen, zo nee, dan staan er alleen hele euro's in het invoerveld.
Nadat je dit weet kun je makkelijk de rest opmaken lijkt me :)
Volgens mij klopt je redenering niet: in E 1.050 (duizendvijftig) zit een punt, maar het zijn geen centen.

Ik zou voor de optie 'verbiedt punten in het invoerveld' gaan.

Hier nog een voorbeeld voor het matchen van floating point getallen:
http://www.regular-expressions.info/floatingpoint.html

[ Voor 10% gewijzigd door Rekcor op 05-01-2007 15:11 ]


  • Martine
  • Registratie: Mei 2002
  • Niet online
Agghh,, ik zie nu net dat ik de titel niet heb ingevuld behalve [JS] 8)7
Naja, ik heb dit scriptje gevonden en een beetje aangepast, ben niet zo'n javascript held...

Dat zou natuurlijk ook nog een mogelijkheid zijn Rekcor, het staat wel stoer 4.500,00 en het is volgens mij iets duidelijker.

[ Voor 29% gewijzigd door Martine op 05-01-2007 15:14 . Reden: Na een tip van Rekcor regeltje onleesbaar gemaakt de moderators ]


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10 13:03
[b][message=27244777,noline]
Naja, ik heb dit scriptje gevonden en een beetje aangepast, ben niet zo'n javascript held...
Uh oh, pas op dat de moderators dit niet lezen.

Die zijn errug allergisch voor script-requests ;)

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Rekcor schreef op vrijdag 05 januari 2007 @ 15:09:
[...]


Volgens mij klopt je redenering niet: in E 1.050 (duizendvijftig) zit een punt, maar het zijn geen centen.
mijn vorige regex klopte idd niet helemaal, dit is de verbeterde versie:
code:
1
[,\.][0-9]{1,2}$


check of die erin zit, zo ja, parse alles behalve dit als euro's en parse de match zelf als centen.
als er geen match is kun je natuurlijk alles als euro's parsen :)

het probleem was dat de vorige 1.000 ook goed vond, terwijl hij alleen maar 1 of 2 decimalen mocht vinden :)

[ Voor 39% gewijzigd door Arjan op 05-01-2007 15:18 ]

oprecht vertrouwen wordt nooit geschaad


  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Even wat anders.

Zo zou ik het NIET oplossen, los het op in PHP zelf, want wat als iemand Javascript af heeft staan? Dan donneert hij nog zo een ongelofelijk groot bedrag (niet dat dat erg is ;) )

Verder denk ik misschien aan dit: gewoon '.' (punten dus) gewoon verbieden dmv PHP, problem solved :*)

[ Voor 21% gewijzigd door Snake op 05-01-2007 15:22 ]

Going for adventure, lots of sun and a convertible! | GMT-8


  • Martine
  • Registratie: Mei 2002
  • Niet online
Ik check het bedrag te alle tijde in php, het gaat erom als het er mooi uitziet in het invoer veld.

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Snakiej schreef op vrijdag 05 januari 2007 @ 15:18:
Even wat anders.

Zo zou ik het NIET oplossen, los het op in PHP zelf, want wat als iemand Javascript af heeft staan? Dan donneert hij nog zo een ongelofelijk groot bedrag (niet dat dat erg is ;) )

Verder denk ik misschien aan dit: gewoon '.' (punten dus) gewoon verbieden dmv PHP, problem solved :*)
Vanuit Interaction Design standpunt moet je nooit consessies doen aan de 'user experience'.
Zeker niet voor een dergelijk simpel technisch probleem :)
Martine schreef op vrijdag 05 januari 2007 @ 15:24:
Ik check het bedrag te alle tijde in php, het gaat erom als het er mooi uitziet in het invoer veld.
zo hoort het ook :)


JavaScript:
1
2
3
4
5
6
7
8
9
10
var input = "1.234,56";

// zoek centen volgens regex:
var centen = input.match(/[,\.][0-9]{1,2}$/);
// euro's zijn hele bedrag - centen
var euro = input.replace(centen, "");

// ruim dingen als komma's en punten op
euro = euro.replace(/[,\.]/,"");
centen = centen.replace(/[,\.]/,"");

[ Voor 16% gewijzigd door Arjan op 05-01-2007 15:33 ]

oprecht vertrouwen wordt nooit geschaad


  • Martine
  • Registratie: Mei 2002
  • Niet online
Bedankt voor het voorbeeld Atgast.

Nu komt dat ding steeds te jammeren met de fout 'deze eigenschap of methode wordt niet ondersteund door dit object.'

Laat maar zitten, ben er klaar mee. Ben al er veel te lang mee bezig, ik gebruik de functie wel welke is al had. Dan maar een paar fouten erin... Iedereen bedankt voor jullie inzet!

JavaScript:
1
2
3
4
5
6
7
8
9
10
    function FormatPrice(input) {
        // zoek centen volgens regex:
        var centen = input.match(/[,\.][0-9]{1,2}$/);
        // euro's zijn hele bedrag - centen
        var euro = input.replace(centen, "");
        
        // ruim dingen als komma's en punten op
        euro = euro.replace(/[,\.]/,"");
        centen = centen.replace(/[,\.]/,"");
}

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10 13:03
JavaScript:
1
2
3
4
5
6
7
8
9
10
var input = "1.234,56";

// zoek centen volgens regex:
var centen = input.match(/[,\.][0-9]{1,2}$/);
// euro's zijn hele bedrag - centen
var euro = input.replace(centen, "");

// ruim dingen als komma's en punten op
euro = euro.replace(/[,\.]/,"");
centen = centen.replace(/[,\.]/,"");
Als ik 1.121.234,56 zou willen doneren, is dat volgens jouw script 1121.234,56

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Martine schreef op vrijdag 05 januari 2007 @ 15:49:
Bedankt voor het voorbeeld Atgast.

Nu komt dat ding steeds te jammeren met de fout 'deze eigenschap of methode wordt niet ondersteund door dit object.'

Laat maar zitten, ben er klaar mee. Ben al er veel te lang mee bezig, ik gebruik de functie wel welke is al had. Dan maar een paar fouten erin... Iedereen bedankt voor jullie inzet!
dat komt doordat het kan voorkomen dat centen null is, een probleem makkelijk opgelost in de onderstaande code.
Rekcor schreef op vrijdag 05 januari 2007 @ 15:55:
[...]

Als ik 1.121.234,56 zou willen doneren, is dat volgens jouw script 1121.234,56
klopt, domme fout, makkelijk op te lossen:
JavaScript:
1
2
3
// ruim dingen als komma's en punten op
euro = String(euro).replace(/[,\.]/g,"");
centen = String(centen).replace(/[,\.]/g,""); 

door te 'g' toe te voegen aan de regex zoekt hij naar alle instanties van de te vinden regex :)
Door de String( ) toe te voegen 'cast' javascript als het ware alles tussen de haakjes naar een string. Inplaats van een replace op een undefined object wordt het dus een replace in een lege string.

[ Voor 17% gewijzigd door Arjan op 05-01-2007 16:03 ]

oprecht vertrouwen wordt nooit geschaad


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10 13:03
Laat maar zitten, ben er klaar mee. Ben al er veel te lang mee bezig, ik gebruik de functie wel welke is al had. Dan maar een paar fouten erin... Iedereen bedankt voor jullie inzet!
Ja hoor eens, zo zijn we natuurlijk niet getrouwd. Wij steken tijd/energie in een goede oplossing. Dan moet je niet opeens zeggen: laat maar zitten. Had dan de vraag niet gesteld. Bovendien is het toch veel leuker om een echt goed werkend script te hebben?

  • Martine
  • Registratie: Mei 2002
  • Niet online
Daar kan ik je geen ongelijk in geven, maar ik kom er zelf gewoon niet uit.

Misschien heeft het er mee te maken hoe ik de functie aanroep, ik doe het nu op deze manier onBlur="this.value=FormatPrice(this.value);"

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Martine schreef op vrijdag 05 januari 2007 @ 16:18:
Daar kan ik je geen ongelijk in geven, maar ik kom er zelf gewoon niet uit.

Misschien heeft het er mee te maken hoe ik de functie aanroep, ik doe het nu op deze manier onBlur="this.value=FormatPrice(this.value);"
het probleem is dat jouw scriptje voor eenmalig gebruik bedoeld is.
Het script past de data aan, ook als deze al in het goede formaat in het veld staat.

oprecht vertrouwen wordt nooit geschaad


  • IntToStr
  • Registratie: December 2003
  • Laatst online: 16:58
Aanroepen met onBlur="FormatPrice(this);" is misschien beter/netter.

Het lijkt me ook nog een probleem dat je niet weet of de bezoeker een . of , gebruikt om decimalen, dus centen, aan te geven. Je zou kunnen checken of het twee-na-laatste (of zelfs ook een-na-laatste voor domme invoer) een . of , is. Dit gebruiken om het aantal cent te bepalen en voor de rest alle punten en kommas eruit gooien en zelf het resulterende getal formatten. (Als het uiteraard al een getal is...)

En zie ook hierboven, als het al in een goed format is, niets doen :)

[ Voor 7% gewijzigd door IntToStr op 05-01-2007 16:31 ]


  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Volgens mij is deze redelijk idiot proof ;)

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function FormatPrice(input) {
    input = String(input).replace(/[^0-9,\.]/g,"");
    var centen = String(input).match(/[,\.][0-9]{1,2}$/);
    var euro = String(input).replace(centen, "");

    euro = String(euro).replace(/[,\.]/g,"");
    centen = String(centen).replace(/[,\.]/g,"");

    var output = "";
    for(var i=0; i<euro.length; i++) {
        output += euro[i];
        if((euro.length-1-i)%3 == 0 && i != euro.length-1) output += ".";
    }
    
    if(!parseInt(output)) output = "1";

    if(parseInt(centen)) {
        output += "," + centen;
    } else {
        output += ",00";
    }
    return output;
}


hier kun je nog ellende als 1.24ditisnasty2.324,123.98.51 in gooien ;)

oprecht vertrouwen wordt nooit geschaad


  • Martine
  • Registratie: Mei 2002
  • Niet online
Zo heb ik het nu opgelost, het werkt prima. Als je nu 10500.50 invoert maakt hij er 10500,50 en als je 15.1 invoert dan maakt hij er 15,10 van.

Dan maar geen 10.500,50, het is prima zo, ik ben super vrolijk!

Als ik hem met onBlur="FormatPrice(this);" of onBlur="FormatPrice(this.value);" aanroep gebeurd er helemaal niets,... met onBlur="this.value=FormatPrice(this.value);" werkt het prima.

Atgast, de laatste idiotproof code werkt helaas niet om een bij mij onbekende reden. |:(

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    function FormatPrice(input) {
        
        // zoek centen volgens regex:
        var centen = input.match(/[,\.][0-9]{1,2}$/);
        // euro's zijn hele bedrag - centen
        var euro = input.replace(centen, "");
        
        // ruim dingen als komma's en punten op
        euro = String(euro).replace(/[,\.]/g,"");
        centen = String(centen).replace(/[,\.]/g,"");
        
        if (centen == 'null')
            centen = '00';
        
        if (centen.length == 1)
            centen = centen + '0';
        
        return euro + ',' + centen;
    }

[ Voor 4% gewijzigd door Martine op 05-01-2007 16:47 ]


  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Martine schreef op vrijdag 05 januari 2007 @ 16:46:
Zo heb ik het nu opgelost, het werkt prima. Als je nu 10500.50 invoert maakt hij er 10500,50 en als je 15.1 invoert dan maakt hij er 15,10 van.

Dan maar geen 10.500,50, het is prima zo, ik ben super vrolijk!

Als ik hem met onBlur="FormatPrice(this);" of onBlur="FormatPrice(this.value);" aanroep gebeurd er helemaal niets,... met onBlur="this.value=FormatPrice(this.value);" werkt het prima.

Atgast, de laatste idiotproof code werkt helaas niet om een bij mij onbekende reden. |:(
[...]
Ik zie het al... Ik had de code alleen in FireFox getest, IE heeft nog wat probleempjes ja.

Mijn code mist inderdaad ook nog de check op dubbele getallen, die jij er correct bij had gezet.

Ik zal even kijken of ik IE kan overtuigen van m'n script ;)

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function FormatPrice(input) {
    input = String(input).replace(/[^0-9,\.]/g,"");
    var centen = String(input).match(/[,\.][0-9]{1,2}$/);
    var euro = String(input).replace(centen, "");

    euro = String(euro).replace(/[,\.]/g,"");
    centen = String(centen).replace(/[,\.]/g,"");

    var output = "";
    for(var i=0; i<euro.length; i++) {
        output += euro.substr(i,1);
        if((euro.length-1-i)%3 == 0 && i != euro.length-1) output += ".";
    }
    
    if(!parseInt(output)) output = "1";
    if(parseInt(centen)) {
        while(String(centen).length < 2) centen += "0";
        output += "," + centen;
    } else {
        output += ",00";
    }
    return output;
}

als dit niet genoeg is...

[ Voor 30% gewijzigd door Arjan op 05-01-2007 16:59 ]

oprecht vertrouwen wordt nooit geschaad


  • IntToStr
  • Registratie: December 2003
  • Laatst online: 16:58
Martine schreef op vrijdag 05 januari 2007 @ 16:46:
Als ik hem met onBlur="FormatPrice(this);" of onBlur="FormatPrice(this.value);" aanroep gebeurd er helemaal niets,... met onBlur="this.value=FormatPrice(this.value);" werkt het prima.
Uiteraard is die "this" een object zodat je in je functie (even aangenomen dat de parameter obj heet) obj.value = output; kunt zetten.

Als je toch al 1000,50 en kunt maken lijkt het me eenvoudig om er dan ook nog maar even 1.000,50 van te maken :)
Het getal voor de , pakken en telkens 3 terugtellen en er een . neergooien.

  • Martine
  • Registratie: Mei 2002
  • Niet online
Wow! Mr. Atgast uw code werkt als een zonnetje! Ik hoop dat ik het scriptje nog vaak ga gebruiken want dit is gewoon SUPER!(!!!!!!) _/-\o_

Ook de tip van de onblur van IntToStr werkt!

Nogmaals; iedereen bedankt!

[ Voor 3% gewijzigd door Martine op 05-01-2007 17:10 ]

Pagina: 1