dvir zeev
dvir zeev

Reputation: 13

loop javascript function for each row after add new row

I have a row in a table that can be duplicated by javascript. In the first row I have a javascript code that makes a calculation.

After duplicating a new row the calc javascript is not working for the new row..

What i do wrong?

table row:

<table class="Parameter" id="new">
    <form action="ProjectParameterNewRecord.php" method="post">
        <tr>
            <td>
                <input type="text" id="Parameters" name="TypeOfOut" />
            </td>
            <td>
                <?php include "ExchangeRates.php"?>
            </td>
            </td>
            <td>
                <input id="Cost" type="number" value="" class="ee105" name="Cost" onchange="changeCost()">
            </td>
            <td>
                <input id="Amount" type="number" value="" class="ee105" name="Amount" onchange="changeAmount()">
            </td>
            <td><span id="minisum" name="minisum" onchange="changeminisum()"></span>
            </td>
            <td id="system">
                <input type="hidden" id="ParameterID" name="ParameterID"></input>
            </td>
            <td id="system">
                <input type="hidden" id="ProjectID" name="ProjectID" value="3"></input>
            </td>
            <td>
                <input type="submit" value="Submit">
            </td>

    </form>
    </tr>
</table>

code to create a new row:

        <script>
    var counter = 1;
    jQuery('img.add-author').click(function(event){
        event.preventDefault();
        counter++;
        var newRow = jQuery(' <tr class="Parameters" id="AA"><td><input type="text" id="Parameters" name="TypeOfOut"/></td><td><select id="Unit" type="text" value=" " class="ee105" name="Unit" onchange="changeUnit(this.value)"><option value="2">KM</option><option value="4">euro</option><option value="3">$</option><option value="25">WorkHour</option><option value="3">dollar</option><option value="25">WorkHour</option> </select</td></td><td><input id="Cost" type="number" value="" class="ee105" name="Cost" onchange="changeCost()"></td><td><input id="Amount" type="number" value="" class="ee105"  name="Amount" onchange="changeAmount()"></td><td><span id="minisum" name="minisum" onchange="changeminisum()"></span></td><td id="system"><input type="hidden" id="ParameterID" name="ParameterID' + counter +'"></input></td><td id="system"><input type="hidden" id="ProjectID" name="ProjectID" value="3"></input></td><td><input type="submit" value="Submit"></td></tr>');

        jQuery('table.Parameter#new').append(newRow);
    });


    </script>   

javascript code to calculate:

function CalcUnitValue() {
    var U = document.getElementById("Unit").value;
    var SUM = -1 * ((((($('#Amount').val())) * (((($('#Cost').val())) * (($('#Unit').val())))))));
    document.getElementById("minisum").innerHTML = SUM;
    document.getElementById("minisum").readOnly = true;
}

function changeCost() {
    var C = document.getElementById("Cost").value;
    var SUM = -1 * ((((($('#Amount').val())) * (((($('#Cost').val())) * (($('#Unit').val())))))));
    document.getElementById("minisum").innerHTML = SUM;
    document.getElementById("minisum").readOnly = true;
}

function changeAmount() {
    var C = document.getElementById("Amount").value;
    var SUM = -1 * ((((($('#Amount').val())) * (((($('#Cost').val())) * (($('#Unit').val())))))));
    document.getElementById("minisum").innerHTML = SUM;
    document.getElementById("minisum").readOnly = true;

}

function changeUnit() {
    var C = document.getElementById("Amount").value;
    var SUM = -1 * ((((($('#Amount').val())) * (((($('#Cost').val())) * (($('#Unit').val())))))));
    document.getElementById("minisum").innerHTML = SUM;
    document.getElementById("minisum").readOnly = true;

}

function minisum() {
    var SUM = -1 * ((((($('#Amount').val())) * (((($('#Cost').val())) * (($('#Unit').val())))))));
    return alert(document.getElementById('minisuminput').innerHTML);

thank you :)

Upvotes: 1

Views: 1053

Answers (2)

Danny Harding
Danny Harding

Reputation: 1745

It looks like your problem is coming from having duplicate ids. When there are duplicate ids, the behavior of document.getElementById() is undefined. Each browser will try to do something reasonable, but there's no way to know which element will be returned (though it's usually the first element).

One option is to change the duplicated ids to class, and then when creating a new row, give the row it's own unique id using your counter:

var newRow = jQuery(' <tr class="Parameters" id="' + counter + '"><td>.....</td></tr> ');

This will allow you to access whichever row you want for calculation, as well as it's children using jquery:

Instead of $('#Cost') or document.getElementById("minisum"), use
$('#' + [number of rowid]).find('.Cost'); or $('#' + [number of rowid]).find('.minisum');


A couple of other tips:

  • To get the value of an <input> into your functions, simply pass it as a parameter like so: onchange="changeCost(value)". Now you can delete 3 of your 4 identical functions as well as remove the first line of the remaining one.
  • You don't need closing </input> tags (see here)
  • There are two </td> tags on your second column
  • Make sure you have correct tag nesting on your </tr> and </form> tags

Upvotes: 1

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93561

  • Your HTML is invalid. You have an extra closing </td> in the middle. You also need to put the form outside the table.
  • You can't have duplicate IDs in a HTML page and expect to reference anything except the first one. Use classes instead.
  • Don't use inline event handlers with jQuery. Use delegated jQuery handlers if you have dynamically added elements.
  • Use an element hidden in the page to hold your template. If you store it in the HTML, and not code, you would have noticed your </select> was missing and replaced by an extra </td>.
  • You mix JavaScript selectors with jQuery. Just stick to jQuery selectors. They are shorter.
  • None of the extra parenthesis are required for a * b * c * d equations.
  • inputs and img elements are meant to be self-closing, not have end tags.
  • All your calculations are exactly the same, so reuse the code.
  • Get into the habit on using consistent case (upper/lower/mixed) for variables and classes.

Use delegated event handlers like this:

$(document).on('change', '.cost,.amount,.unit,.parameters', function() {
    var $tr = $(this).closest('tr');
    var sum = -1 * $('.Amount', $tr).val() * $('.cost', $tr).val() * $('.Unit', $tr).val();
    $(".minisum", $tr).html(sum);
}

Re templating: you can store your template row in a dummy script block, with unknown type (I use text/template) and it will be ignored by the browser.

e.g.

<script id="template" type="text/template">
<tr class="Parameters" id="AA">
  <td>
    <input type="text" class="Parameters" name="TypeOfOut" />
  </td>
  <td>
    <select class="Unit ee105" type="text" value=" " name="Unit">
      <option value="2">KM</option>
      <option value="4">euro</option>
      <option value="3">$</option>
      <option value="25">WorkHour</option>
      <option value="3">dollar</option>
      <option value="25">WorkHour</option>
    </select>
  </td>
  <td>
    <input class="cost" type="number" value="" name="Cost">
  </td>
  <td>
    <input class="amount ee105" type="number" value="" name="Amount">
  </td>
  <td><span class="minisum" name="minisum"></span></td>
  <td class="system">
    <input type="hidden" class="ParameterID" name="ParameterID{counter}" />
  </td>
  <td class="system">
    <input type="hidden" class="ProjectID" name="ProjectID" value="3" />
  </td>
  <td>
    <input type="submit" value="Submit">
  </td>
</tr>
</script>

You will note a {counter} placeholder where you wanted to insert a new value. Use it as the HTML source to create new rows.

e.g.

$('table.Parameter#new').append($('#template').html().replace('{counter}', counter));

JSFiddle to play with ( most of this functional): https://jsfiddle.net/TrueBlueAussie/33e9ptgu/

Upvotes: 1

Related Questions