[JS] Variabele wordt behandeld als string ipv integer

Pagina: 1
Acties:

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
In onderstaande code zie je dat het basisproduct (fruitmand) 19 euro kost. Optioneel kunnen klanten daar modules (fruit, wijn, etc) bij aanschaffen. Elke module heeft een prijs. De totaalprijs moet automatisch berekend worden als een klant een module aan- of uitklikt:


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<form onload="calculate()">
<table border="1">
 <tr>
   <td>&nbsp;</td><td>Beginprijs</td><td>19</td>
 </tr>
 <tr>
   <td><input name="module" value="100" type="checkbox" onchange="calculate()"></td>
   <td>Module A</td>
   <td>100</td>
 </tr>
 <tr>
   <td><input name="module" value="150" type="checkbox" onchange="calculate()"></td>
   <td>Module B</td>
   <td>150</td>
 </tr>
 <tr>
   <td>&nbsp;</td>
   <td>Prijs</td>
   <td><input name="price" type="text" size="10"></td>
 </tr>
</table>
</form>

<script>
function calculate() {
  var modules = document.forms[0].module;
  var options = 19;

  for (var i = 0; i < modules.length; i++) {
    if (modules[i].checked) {
      options += modules[i].value;
    }
  }

  document.forms[0].price.value = options;
}
</script>

In de variabele "options" wordt de totaalprijs uitgerekend. Standaard is deze dus 19 euro. In regel 31 wordt de waarde van de aangevinkte checkboxes hierbij opgeteld. Alleen: "options" wordt als een string behandeld en wordt bijvoorbeeld 19150 in plaats van (19 + 150 =) 169. Hoe los ik dit op?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


  • frickY
  • Registratie: Juli 2001
  • Laatst online: 24-04 11:26
De makkelijkste manier in Javasvript om een string in een integer om te zetten, is door de string met 1 te vermenigvuldigen, of er 0 bij op te tellen, etc..

Je regel 31 zou dus moeten zijn;
options += (modules[i].value * 1);

[ Voor 27% gewijzigd door frickY op 28-09-2005 16:10 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:47

crisp

Devver

Pixelated

Maar de methods die ervoor bedoelt zijn zijn uiteraard parseInt en parseFloat ;)

Intentionally left blank


  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ik ben nu zover. In FF werkt het allemaal perfect, maar als ik in IE een module selecteer, wordt het bedrag in de "price" en "license" inputs, niet aangepast. Waar ligt dit nu aan? Crisp heeft natuurlijk gelijk, maar ik moet zeggen dat vermenigvuldigen met 1 (en later, 0.65) wel lekker werkt. Het is allemaal wat korter...

Overigens excuses voor de ontzettende berg HTML meuk, maar het hoort nu eenmaal bij dit scriptje :). Het werkelijke probleem zit hem ergens in de javascript, onderaan...

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<form>
<table border="1">
 <tr><td colspan="4">Algemeen</td></tr>
 <tr>
   <td>&nbsp;</td><td>Standaard CMS</td><td>1699</td>
 </tr>
 <tr><td colspan="4">Modules</td></tr>
 <tr>
   <td><input name="module" value="100" type="checkbox" onchange="calculate()"></td>
   <td>Module A</td>
   <td>100</td>
 </tr>
 <tr>
   <td><input name="module" value="150" type="checkbox" onchange="calculate()"></td>
   <td>Module B</td>
   <td>150</td>
 </tr>
 <tr><td colspan="4">Hosting</td></tr>
 <tr>
   <td><input name="hosting" type="checkbox" value="5" onclick="check(0); calculate()"></td>
   <td>Pakket A</td>
   <td>5</td>
 </tr>
 <tr>
   <td><input name="hosting" type="checkbox" value="10" onclick="check(1); calculate()"></td>
   <td>Pakket B</td>
   <td>10</td>
 </tr>
 <tr>
   <td><input name="hosting" type="checkbox" value="15" onclick="check(2); calculate()"></td>
   <td>Pakket C</td>
   <td>15</td>
 </tr>
 <tr><td colspan="4">U betaalt</td></tr>
 <tr>
   <td>&nbsp;</td>
   <td>Eenmalig</td>
   <td><input name="price" type="text" size="4" value="1699"></td>
 </tr>
 <tr>
   <td>&nbsp;</td>
   <td>Maandelijks</td>
   <td><input name="monthly" type="text" size="4" value="0"></td>
 </tr>
 <tr>
   <td>&nbsp;</td>
   <td>Licentie</td>
   <td><input name="license" type="text" size="4" value="1099"></td>
 </tr>
</table>
</form>

<script>
// Er kan hooguit 1 hosting-checkbox aangevinkt worden
function check(i) {
  for (j = 0; j < 3; j++) {
    if (eval("document.forms[0].hosting[" + j + "].checked") == true) {
      document.forms[0].hosting[j].checked = false;
      if (j == i) {
        document.forms[0].hosting[j].checked = true;
      }
    }
  }
}

function calculate() {
  var price   = 1699;
  var license = 1099;
  var monthly = 0;

  var modules = document.forms[0].module;
  for (var i = 0; i < modules.length; i++) {
    if (modules[i].checked) {
      price   += (modules[i].value * 1.00);
      license += (modules[i].value * 0.65);
    }
  }

  var hosting = document.forms[0].hosting;
  for (var i = 0; i < hosting.length; i++) {
    if (hosting[i].checked) {
      monthly += (hosting[i].value * 1.00);
    }
  }

  document.forms[0].license.value = Math.ceil(license);
  document.forms[0].price.value   = price;
  document.forms[0].monthly.value = monthly;
}
</script>

[ Voor 50% gewijzigd door Reveller op 29-09-2005 18:08 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Verwijderd

document.forms[0].price.value

document.forms[0].elements['price'].value

Nooit de "korte" notatie gebruiken.
En verder is een setje checkboxen waarvan er maar 1 aangevinkt mag worden nogal belachelijk. Gebruik daarvoor een radiobutton.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:47

crisp

Devver

Pixelated

en er zit natuurlijk verschil tussen 'onchange' en 'onclick' ;)

hier alvast een beetje netter qua JS (this keyword rulez, eval zuigt):
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<form action="#">
<table border="1">
 <tr><td colspan="4">Algemeen</td></tr>
 <tr>
   <td> </td><td>Standaard CMS</td><td>1699</td>
 </tr>
 <tr><td colspan="4">Modules</td></tr>
 <tr>
   <td><input name="module" value="100" type="checkbox" onclick="calculate(this.form)"></td>
   <td>Module A</td>
   <td>100</td>
 </tr>
 <tr>
   <td><input name="module" value="150" type="checkbox" onclick="calculate(this.form)"></td>
   <td>Module B</td>
   <td>150</td>
 </tr>
 <tr><td colspan="4">Hosting</td></tr>
 <tr>
   <td><input name="hosting" type="checkbox" value="5" onclick="check(this); calculate(this.form)"></td>
   <td>Pakket A</td>
   <td>5</td>
 </tr>
 <tr>
   <td><input name="hosting" type="checkbox" value="10" onclick="check(this); calculate(this.form)"></td>
   <td>Pakket B</td>
   <td>10</td>
 </tr>
 <tr>
   <td><input name="hosting" type="checkbox" value="15" onclick="check(this); calculate(this.form)"></td>
   <td>Pakket C</td>
   <td>15</td>
 </tr>
 <tr><td colspan="4">U betaalt</td></tr>
 <tr>
   <td> </td>
   <td>Eenmalig</td>
   <td><input name="price" type="text" size="4" value="1699"></td>
 </tr>
 <tr>
   <td> </td>
   <td>Maandelijks</td>
   <td><input name="monthly" type="text" size="4" value="0"></td>
 </tr>
 <tr>
   <td> </td>
   <td>Licentie</td>
   <td><input name="license" type="text" size="4" value="1099"></td>
 </tr>
</table>
</form>

<script>
// Er kan hooguit 1 hosting-checkbox aangevinkt worden
function check(checkbox)
{
    var checkboxes = checkbox.form.elements[checkbox.name], i = checkboxes.length;
    while (i--)
        checkboxes[i].checked = (checkboxes[i] == checkbox);
}

function calculate(form)
{
    var price   = 1699;
    var license = 1099;
    var monthly = 0;

    var modules = form.elements['module'], i = modules.length;
    while (i--)
    {
        if (modules[i].checked)
        {
            price   += modules[i].value * 1.00;
            license += modules[i].value * 0.65;
        }
    }

    var hosting = form.elements['hosting']; i = hosting.length;
    while (i--)
    {
        if (hosting[i].checked)
        {
            monthly   += hosting[i].value * 1.00;
        }
    }

    form.elements['license'].value = Math.ceil(license);
    form.elements['price'].value   = price;
    form.elements['monthly'].value = monthly;
}
</script>

Intentionally left blank


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:47

crisp

Devver

Pixelated

En hoewel ik me aansluit verder bij de opmerking van Cheatah kan ik me wel situaties voorstellen waarbij je meer dan 1, maar toch een beperkt aantal keuzes kan maken uit meerdere, en dat een stukje script daar dan best behulpzaam in kan zijn ;)

Intentionally left blank


  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Maar met jouw code kan ik het hosting pakket niet meer deselecteren ... de 3 hosting checkboxes gedragen zich nu als een radiogroup (die ook niet meer te deselecteren valt nadat je een optie hebt aangeklikt) en dat was nu juist niet de bedoeling :))
Verwijderd schreef op donderdag 29 september 2005 @ 18:15:
Nooit de "korte" notatie gebruiken.
En verder is een setje checkboxen waarvan er maar 1 aangevinkt mag worden nogal belachelijk. Gebruik daarvoor een radiobutton.
Ik neem je eerste opmerking ter harte, en zal mijn code aanpassen. Je tweede opmerking klopt alleen niet, want het nadeel van een radiogroup is dat hij niet meer te deselecteren is als je eenmaal een optie aangeklikt hebt ... of je moet een extra radiobutton "geen hosting" maken, maar dat vind ik onzin. De bedoeling van mijn code is juist dat je een checkbox-group zich gedraagt als een radiogroup, maar dat je die group ook weer kan un-vinken zeg maar...dat is juist de feature die ik erin wilde :) Crisps code is veel mooier dan de mijne, maar daarin is met die optie geen rekening gehouden (was ook niet duidelijk dat dat een feature moest zijn). Daar ga ik nu aan werken. Als iemand suggesties heeft hoor ik dat graag :)

[ Voor 57% gewijzigd door Reveller op 29-09-2005 18:42 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:47

crisp

Devver

Pixelated

zo dan:
JavaScript:
1
2
3
4
5
6
7
8
9
function check(checkbox)
{
    if (checkbox.checked)
    {
        var checkboxes = checkbox.form.elements[checkbox.name], i = checkboxes.length;
        while (i--)
            checkboxes[i].checked = (checkboxes[i] == checkbox);
    }
}

;)

Intentionally left blank


Verwijderd

Je hebt 4 opties. Hostingpakket 1, 2, 3 of géén pakket. Combinaties zijn niet mogelijk, en het betreft allemaal hetzelfde onderwerp. Een groepje radiobuttons dus. Of een selectbox.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

code:
1
var checkboxes = checkbox.form.elements[checkbox.name], i = checkboxes.length;
Hm... strict genomen mag je er niet van uit gaan dat checkboxes voor i wordt geinitialiseerd ;)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:47

crisp

Devver

Pixelated

drm schreef op donderdag 29 september 2005 @ 19:10:
[...]
Hm... strict genomen mag je er niet van uit gaan dat checkboxes voor i wordt geinitialiseerd ;)
Toch wel; expressies worden doorgaans left-to-right geevalueerd en een , (komma) operator heeft een lagere precedence dan een assignment operator.
Het is zelfs zo dat de waarde van de laatste operand gereturned wordt:
JavaScript:
1
2
var i, j;
var k = (i = 2, j = 3); // 3


In de ECMA specificatie (pagina 60) is het als volgt omschreven:
Syntax:
Expression :
    AssignmentExpression
    Expression , AssignmentExpression

The production Expression : Expression , AssignmentExpression is evaluated as follows:

1. Evaluate Expression.
2. Call GetValue(Result(1)).
3. Evaluate AssignmentExpression.
4. Call GetValue(Result(3)).
5. Return Result(4).
;)

[ Voor 52% gewijzigd door crisp op 29-09-2005 20:43 ]

Intentionally left blank


  • Annie
  • Registratie: Juni 1999
  • Laatst online: 25-11-2021

Annie

amateur megalomaan

Betweter ;)
Ik vind het overigens minder leesbaar dan de twee statements op losse regels. Ik gebruik het doorgaans alleen bij zeer korte assignments, bijv: var a = 1, b = 2;

Today's subliminal thought is:


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

crisp:
Toch wel; expressies worden doorgaans left-to-right geevalueerd en een , (komma) operator heeft een lagere precedence dan een assignment operator.
Het is zelfs zo dat de waarde van de laatste operand gereturned wordt:
JavaScript:
1
2
var i, j;
var k = (i = 2, j = 3); // 3


In de ECMA specificatie (pagina 60) is het als volgt omschreven:

[...]

;)
Whehe, ik hoopte stiekem al dat jij het op ging zoeken, want ik had er geen zin in :D :Y)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz

Pagina: 1