PacaMama
PacaMama

Reputation: 23

Javascript -- Why does one document.getElementById() work and not the other?

I am creating an interactive invoice and I am very new to programming but so far so good. I can find most of what I what on the various sites this one being the best.

In HTML I have various tables with 40 or so different input fields such as these:

<tr>
<td><input type="text" id="idDescLine15" name="fDescLine15" size="50">  </td>
<td><input type="number" id="idQTY15" name="nQTY15" size="5">   </td>
<td><input type="number" id="idPrice15" name="nPrice15" size="5">   </td>
<td class="Checkbox"><input type="checkbox" id="idTax15" name="nTax1">  </td>
<td class="TotalCol"><p class="TotalLine" id="idTotalLine15">0.00</p>   </td>
</tr>

I have the following function that calculates the row total (quantity * price) for each row. This above HTML code is for row 15. All others are setup the same.

<script>
function Calculate()
{
    var vSTotalTax = 0;
    for (var i=1;i<16;i++)
    {
        var vbuildQTY = 'idQTY' + i;
        var vbuildPrice = 'idPrice' + i;
        var vbuildTotalLine = 'idTotalLine' + i;
        var vQTY=document.getElementById(vbuildQTY).value;
        var vPrice=document.getElementById(vbuildPrice).value;
        var vTotalLine = (vQTY * vPrice);
        document.getElementById(vbuildTotalLine).innerHTML = parseFloat(Math.round(vTotalLine * 100) / 100).toFixed(2);
        vSTotalTax = vSTotalTax + vTotalLine;
    }           
    document.getElementById(idSTotalTax).innerHTML = parseFloat(Math.round(vSTotalTax * 100) / 100).toFixed(2);
}
</script>

The first "document.getElementById(vbuildTotalLine)" that is inside the loop works just fine and returns a total for each of the rows.

The second one "document.getElementById(idSTotalTax) does not. It is set up just the same in the HTML:

<tr>
<td><p class="TotalLabel">Sous-total taxable:</p></td>
<td class="TotalCol"><p class="TotalLine" id="idSTotalTax">0.00</p></td>
</tr>

When I click the Calculate button I get an error on the page that says the document.getElementById on line 238 is null or not an object. The only difference between the two is the location in the HTML where it is in a different table. I tried using one of the 'idTotalLine' field that already worked but I continue with the same error.

Help. Thanks.

Upvotes: 0

Views: 694

Answers (3)

cocco
cocco

Reputation: 16706

here is a solution witch let's you don't bother of the id's.

var tr=document.getElementsByTagName('tr'),trl=tr.length,total=0;

while(trl--){
 var td=tr[trl].getElementsByTagName('td'),
 v=td[1].firstChild.value*td[2].firstChild.value;
 td[4].firstChild.textContent=v.toFixed(2);
 total+=v;
}
totalBox=total.toFixed(2);

Note: by using firstChild there have to be no spaces between the <td> and the <input>

so you can just write something like that:

<tr>
<td><input type="text" name="desc[]" size="50"></td>
<td><input type="number" name="qty[]" size="5"></td>
<td><input type="number" name="price[]" size="5"></td>
<td class="Checkbox"><input type="checkbox" name="tax[]"></td>
<td class="TotalCol"><p></p></td>
</tr>

if you post this form

you will get an array like this:

$_POST={
 desc:[
   item1,//item1
   item2 //item2
  ]
 qty:[
   1,//item1
   2//item2
  ]
 price:[
   20,//item1
   25//item2
  ]
 tax:[
   true,//item1
   false//item2
  ]
}

and you can add the calculate function on the form itself.

so:

document.forms[0].addEventListener('keyup',calculate,false);

Example

http://jsfiddle.net/gwtmM/

Upvotes: 0

Mark Reed
Mark Reed

Reputation: 95252

The working call getElementById(vbuildTotalLine) looks for the element whose id is the string value of the variable vbuildTotalLine. In this case, that would be "idTotalLineN" for some value of N between 1 and 15, inclusive. You can see in the HTML that there is no element with id="vbuildTotalLine".

The non-working call getElementById(idSTotalTax), similarly, looks for the element whose id is the string value of the variable idSTotalTax, but I see no variable idSTotalTax anywhere in your code. If you want to look up the document whose id is the literal string "idSTotalTax", then you need to pass that value as a string, not the name of a variable you don't even declare or assign. You can do that with code like this:

getElementById('idSTotalTax')

or perhaps, in keeping with the first part,

var vbuildTotalTax = 'idSTotalTax';
...
getElementById(vbuildTotalTax);

Upvotes: 0

Jay Harris
Jay Harris

Reputation: 10055

You have idSTotalTax already the DOM element. Instead, you mean to use it as a string, passing it to getElementById. Wrap it in quotes. Otherwise you are passing the DOM element into document.getElementById.

document.getElementById("idSTotalTax").innerHTML

-- Thanks to Felix & Pointy for pointing out an earlier issue.

Upvotes: 2

Related Questions