Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Time difference and summation between multiple rows on change

I am trying to write a code that can do the following :

  1. Calculates time difference (in HH:MM format) between two type="time" elements on a row.
  2. Sum the total difference (in HH:MM format) in text input.

I've managed to create a function fired by the onchange event, but my function is only considering the first values entered, meaning that when you update the timings, the difference will be recalculated and the total will be wrong.

Screenshot

Here is my JavaScript code for calculating the first line:

function CalTime0() {
    var timeOfCall = $('#timefrom0').val(),
    timeOfResponse = $('#timeto0').val(),
    hours = timeOfResponse.split(':')[0] - timeOfCall.split(':')[0],
    minutes = timeOfResponse.split(':')[1] - timeOfCall.split(':')[1],
    total = $('#tbtotal').val(),
    tothours = total.split(':')[0],
    totminutes = total.split(':')[1];               
    minutes = minutes.toString().length<2?'0'+minutes:minutes;
    totminutes = totminutes.toString().length<2?'0'+totminutes:totminutes;

    if(minutes<0) { 
        hours--;
        minutes = 60 + minutes;
    }

    hours = hours.toString().length<2?'0'+hours:hours;
    tothours = tothours.toString().length<2?'0'+tothours:tothours;
    tothours = parseInt(tothours) + parseInt(hours);
    totminutes = parseInt(totminutes) + parseInt(minutes);

    if(totminutes >= 60) { 
        tothours++;
        totminutes = totminutes - 60;
    }

    $('#total0').val(hours + ':' + minutes);    
    $('#tbtotal').val(tothours + ':' + totminutes); 
}
like image 422
Ahmed Ali Avatar asked Mar 03 '26 05:03

Ahmed Ali


1 Answers

The solution is to substract the time the #total0 field represents from the time the #tbtotal field represents. Then you calculate the new #total0 field, and add that time to #tbtotal again. This way the time displayed in #tbtotal is always correct.

The other question seemed to be how to do this for all rows, instead of just this one. You can use the this keyword to figure out what element fired the change event. From there you can figure out what the other elements would be. For this purpose I renamed the fields to timefr0 and timeto0, so they are equal length.

I took the liberty to convert all times to seconds, and manipulate them that way. The comments in the script should speak for themselfs.

function updateTotals() {
  //Get num part of the id from current set
  //Cheated a bit with the id names ;-)
  var num = $(this).attr('id').substr( 6 );

  //Get the time from each and every one of them
  var tfrom = $('#timefr' + num ).val().split(':');
  var tto = $('#timeto' + num ).val().split(':');
  var currtotal = $('#total' + num ).val().split(':');
  var grandtotal = $('#tbtotal').val().split(':');

  //Convert to seconds and do the calculations the easy way
  var diff = (tto[0] - tfrom[0]) * 3600 + (tto[1] - tfrom[1]) * 60;
  var totalsec = currtotal[0] * 3600 + currtotal[1] * 60;
  var grandtotalsec = grandtotal[0] * 3600 + grandtotal[1] * 60;

  //If the result is negative, we can't do anything sensible. Use 0 instead.
  if( diff < 0 ) {
    diff = 0;
  }

  //Substract what we calculated last time
  grandtotalsec -= totalsec;
  //Then add the current diff
  grandtotalsec += diff;

  //Convert diff (or total) into human readable form
  var hours = Math.floor( diff / 3600 );
  diff = diff % 3600;
  var minutes = Math.floor( diff / 60 );

  hours = (hours < 10) ? "0" + hours.toString() : hours.toString();
  minutes = (minutes < 10) ? "0" + minutes.toString() : minutes.toString();


  //Convert grandtotal into human readable form
  var grandtotalhours = Math.floor( grandtotalsec / 3600 );
  grandtotalsec = grandtotalsec % 3600;
  var grandtotalminutes = Math.floor( grandtotalsec / 60 );

  grandtotalhours = (grandtotalhours < 10) ? "0" + grandtotalhours.toString() : grandtotalhours.toString();
  grandtotalminutes = (grandtotalminutes < 10) ? "0" + grandtotalminutes.toString() : grandtotalminutes.toString();  

  //Put them in the fields
  $( '#total' + num ).val( hours + ":" + minutes );
  $( '#tbtotal' ).val( grandtotalhours + ":" + grandtotalminutes );
}

An example fiddle can be found here.

like image 149
Sumurai8 Avatar answered Mar 04 '26 18:03

Sumurai8



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!