NulisDefo
NulisDefo

Reputation: 335

how to get average of certain column values in table

I'm a beginner so I'm not sure whats wrong here. What im trying to achieve is to check if certain cells in a table (column) has numerical values in them and if they do include them in calculating the average value upon losing focus (blur) so that it would kind of be real time.

I'm not sure if calculation function is wrong itself, or if I'm addressing wrong column maybe or trying to insert calculated value in the wrong way. help would be appreciated.

Here is JSfiddle and the code excerpts: https://jsfiddle.net/NulisDefo/03rn7ew1/5/

table

<table id="myTable" class="table table-inverse">
    <thead id = "headings" class = "thead-default">
      <tr>
        <th>Tabelio Nr.</th>
        <th>Vardas</th>
        <th>Pavardė</th>
        <th>Pareigos</th>
        <th>Bazinė alga, €</th>
        <th>Valandinis atlyginimas, €</th>
        <th>Veiksmai</th>
      </tr>
    </thead>
    <tfoot class = "thead-default">
      <tr>
        <td colspan = "4">Vidurkis</td>
        <!-- <td></td>
        <td></td>
        <td></td> -->
        <td id = "alga">0</td>
        <td id = "valandinis" colspan = "2">0</td>
        <!-- <td></td> -->
      </tr>
    </tfoot>
    <tbody>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
        <td>1000</td>
        <td><input type="button" value="Delete" onclick="deleteRow(this)"></td>
        <td>
          <p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
          <p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
        </td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
        <td>2000</td>
        <td>blum</td>
        <td>
          <p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
          <p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
        </td>
      </tr>
      <tr class = "testas">
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
        <td>5000</td>
        <td>blum</td>
        <td>
          <p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
          <p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
        </td>
      </tr>
    </tbody>
  </table>

script for calculating and trigger

$("table").on("blur", "td", function(){
calculate();
} );

function calculate() {
  var sum = 0;
  var counter = 0 //daliklis
  $('#myTable tbody tr td:nth-child(5)').each(function() {
  // $("table tbody tr td:eq(4)").each(function(){
    if (!isNaN(this.value))
    {
      sum += parseFloat($(this).text());
      counter += 1;
    }
    });
    $("#alga").textContent(sum/counter);
};

I should probably mention, that prior existing entries can be edited only after pressing edit button.

EDIT: Ok, so apparently all of the solutions work, but the problem is, that if cell is empty, instead of excluding that part from calculation the returned result is NaN

Upvotes: 0

Views: 1171

Answers (3)

Prashant Shirke
Prashant Shirke

Reputation: 1423

You can use focusout event.

$("table").on("focusout", "tr", function(){ 
 calculate();
});

I have updated the code like following.

  1. Changed event to focusout for tr. (Because this event listens change made to the contenteditable and in your case tr has contenteditable not the td.
  2. Added class avg in the footer td which will tell that these columns needs average to calculate.
  3. Considered avg class in calculation and also updated the logic a bit.
  4. Used jquery's text() method to set and get the text of td.

Check updated fiddle

Upvotes: 1

Amar Singh
Amar Singh

Reputation: 5622

Your loop was not proper. Checkout the jsFiddle Demo .Now you just need to decide when to trigger calculate function which I think you can handle

 function calculate() {
      var sum = 0;
      var counter = 0 //daliklis
      $('#myTable tbody tr').each(function() {
      // $("table tbody tr td:eq(4)").each(function(){
        var a = $(this).children('td:nth-child(5)');
        if (!isNaN(a.text()))
        {
          sum += parseFloat(a.html()); console.log(sum);
          counter += 1;
        }
        });
        $("#alga").text(sum/counter);
    }

jsFiddle Demo

Upvotes: 1

phil
phil

Reputation: 456

function deleteRow(r) {
    var i = r.parentNode.parentNode.rowIndex;
    document.getElementById("myTable").deleteRow(i);
    };


$("#pridet").on("click", function() {
  $("<tr contenteditable><td></td><td></td><td></td><td></td><td></td><td></td></tr>").prependTo("table tbody");
  $("table tbody tr td").last().clone().appendTo("table tbody tr:first");
});


$(".editbtn").click(function () {
          var currentTD = $(this).parents("tr").find("td");

              $.each(currentTD, function () {
                  $(this).prop("contenteditable", true)
              });
      });


$("table").on("blur", "td", function(){
  calculate();
} );


function calculate() {
  var sum = 0;
  var counter = 0 //daliklis
  $('#myTable tbody tr td:nth-child(5)').each(function() {
  // $("table tbody tr td:eq(4)").each(function(){
    if (!isNaN($(this).text()))
    {
      sum += parseFloat($(this).text());
      counter += 1;
    }
    });
    $("#alga").text(sum/counter);
}
calculate();
.btn {
  width:10%;
  padding-bottom:0;
  margin-bottom:0;
  border-bottom:0
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
    <div class="container">
      <button id = "pridet">add</button>
      <table id="myTable" class="table table-inverse">
        <thead id = "headings" class = "thead-default">
          <tr>
            <th>Tabelio Nr.</th>
            <th>Vardas</th>
            <th>Pavardė</th>
            <th>Pareigos</th>
            <th>Bazinė alga, €</th>
            <th>Valandinis atlyginimas, €</th>
            <th>Veiksmai</th>
          </tr>
        </thead>
        <tfoot class = "thead-default">
          <tr>
            <td colspan = "4">Average</td>
            <!-- <td></td>
            <td></td>
            <td></td> -->
            <td id = "alga">0</td>
            <td id = "valandinis" colspan = "2">0</td>
            <!-- <td></td> -->
          </tr>
        </tfoot>
        <tbody>
          <tr>
            <td>1</td>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
            <td>1000</td>
            <td>15.3</td>
            <td>
              <p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
              <p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
            </td>
          </tr>
          <tr>
            <td>2</td>
            <td>Jacob</td>
            <td>Thornton</td>
            <td>@fat</td>
            <td>2000</td>
            <td>16.8</td>
            <td>
              <p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
              <p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
            </td>
          </tr>
          <tr class = "testas">
            <td>3</td>
            <td>Larry</td>
            <td>the Bird</td>
            <td>@twitter</td>
            <td>5000</td>
            <td>10.2</td>
            <td>
              <p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
              <p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
            </td>
          </tr>
        </tbody>
      </table>
      </div>
      </body>

$("#alga").text(sum/counter); instead of $("#alga").textContent(sum/counter);

textContent is not a function. Use $.fn.text instead.

Plus you use this.value. Which should be $(this).text() and you should initially call the calculate() function once:

Upvotes: 1

Related Questions