PDA

View Full Version : Calling a function from a table cell



MaDmiX
Sep 20th, 2012, 05:03 PM
Hi All,

I wrote a simple function to calculate the difference between two times within a 24 hour period.


function calculateTime(time1,time2) {
var hours1 = parseInt(time1.slice(0,2),10);
var mins1 = parseInt(time1.slice(3,5),10);
var secs1 = parseInt(time1.slice(6,8),10);

var hours2 = parseInt(time2.slice(0,2),10);
var mins2 = parseInt(time2.slice(3,5),10);
var secs2 = parseInt(time2.slice(6,8),10);

if (hours1>hours2) {
hours2=hours2+24;
}

var startTime = (hours1 * 3600) + (mins1 * 60) + (secs1);
var endTime = (hours2 * 3600) + (mins2 * 60) + (secs2);
var totalSecs = endTime-startTime;

var sumHours = parseInt(totalSecs / 3600, 10);
var sumMins = parseInt((totalSecs - sumHours * 3600) / 60, 10);
var sumSecs = totalSecs - sumHours * 3600 - sumMins * 60;

var i;
var sumTime = Array();
sumTime[0] = sumHours;
sumTime[1] = sumMins;
sumTime[2] = sumSecs;

for (i=0;i<sumTime.length;i++) {
if(sumTime[i] < 10) {
sumTime[i] = "0" + sumTime[i];
}
}
return sumTime.join(':');
}


This works great but I can't figure out how to call the function. I want to create a table where users will enter their start and end times into text boxes in a <tr> and have the result displayed in a cell on the same row.

Any ideas? This one seems simple but I seem to be at a loss. I thought about using window.onLoad but not sure that's the best (if even possible) approach.

Thanks in advance for you guidance here.

Kind regards,

Ken

xelawho
Sep 20th, 2012, 05:26 PM
the problem with text boxes is that they have an onchange event, but it is called when the text box loses focus, which is kind of counter-intuitive to some users. I would suggest having a "calculate time" button in the same row that the users clicks once both boxes are filled out. From there it is a simple matter of finding the two textboxes in the DOM, grabbing their values and feeding them to your function.

For example, if your table looked like this:


<table border="1">
<tr>
<td><input type="text" </td>
<td><input type="text" </td>
<td><input type="button" value="get time" onclick="getTimes(this)"/></td>
<td width="200px"></td>
</tr>
<tr>
<td><input type="text" </td>
<td><input type="text" </td>
<td><input type="button" value="get time" onclick="getTimes(this)"/></td>
<td width="200px"></td>
</tr>
</table>


then you could use a function like this:



function getTimes(btn){
var start=btn.parentNode.parentNode.cells[0].children[0].value;
var end=btn.parentNode.parentNode.cells[1].children[0].value;
btn.parentNode.parentNode.cells[3].innerHTML=calculateTime(start,end);
}

MaDmiX
Sep 20th, 2012, 06:09 PM
Hi xelawho,

Thanks for your reply. Unfortunately I don't have the luxury of a button. Actually I was just informed that I have to set up a "confirmation" page that will display the start and end times entered from a form on another page, so this just became a little more complicated.

I can echo the entered values to my table cells using PHP but I am still unsure how I will get the result:



<table>
<tr>
<th>Start time:</th>
<th>End time:</th>
<th>Total time:</th>
</tr>
<tr>
<td><?php echo $row_rstAffectedProg['StartTime']; ?></td>
<td><?php echo $row_rstAffectedProg['EndTime']; ?></td>
<td> NOT SURE WHAT TO DO HERE :( </TD>
</tr>
</table>


Thanks,

Ken

xelawho
Sep 20th, 2012, 06:26 PM
hmm. I think the last event you can listen for is the window.onload, and if you are lucky this happens after the php has been echoed in. I really don't know about the order of things there.

If it is true and you can give your table an id of "tab" you could try this:



window.onload=function (){
var rows=document.getElementById("tab").getElementsByTagName("tr");
for (var x = 1; x < rows.length; x++) { //start at 1 to skip the header cells
var start=rows[x].cells[0].children[0].value;
var end=rows[x].cells[1].children[0].value;
rows[x].cells[2].innerHTML=calculateTime(start,end);
}
}
</script>


but are you sure that the start and end times will be displayed in text boxes? because if they just get displayed as text you would have to do:


var start=rows[x].cells[0].innerHTML;
var end=rows[x].cells[1].innerHTML;


give it a go, anyway...

xelawho
Sep 20th, 2012, 06:32 PM
but (again flaunting my ignorance of php) if these figures are coming from the server, can't you do the calculations server side and just echo in all the results?

MaDmiX
Sep 20th, 2012, 07:51 PM
but (again flaunting my ignorance of php) if these figures are coming from the server, can't you do the calculations server side and just echo in all the results?

I am more comfortable with javascript and I like the idea that the calculations will be performed client side. BTW your function worked nicely. Big thanks :-)

Ken

xelawho
Sep 20th, 2012, 08:18 PM
you're welcome. In future, you might consider using js's date object to make time calculations:



function calculateTime(time1,time2) {
var startDate = new Date(2000, 0, 1, time1.split(":")[0], time1.split(":")[1], time1.split(":")[2]);
var endDate = new Date(2000, 0, 1, time2.split(":")[0], time2.split(":")[1], time2.split(":")[2]);

var milliSecs = endDate-startDate;
var msSecs = 1000;
var msMins = (msSecs * 60)
var msHours = (msMins * 60)
var numHours = Math.floor(milliSecs/msHours)
var numMins = Math.floor((milliSecs - (numHours * msHours)) / msMins)
var numSecs = Math.floor((milliSecs - (numHours * msHours) - (numMins * msMins))/ msSecs)

numSecs =(numSecs < 10)?"0" + numSecs:numSecs;
numMins =(numMins < 10)?"0" + numMins:numMins;

return numHours + ":" + numMins + ":" + numSecs;
}


or if you wanted to be really lazy...



function calculateTime(time1,time2) {
var startDate = new Date(2000, 0, 1, time1.split(":")[0], time1.split(":")[1], time1.split(":")[2]);
var endDate = new Date(2000, 0, 1, time2.split(":")[0], time2.split(":")[1], time2.split(":")[2]);

var milliSecs = endDate-startDate;
d=new Date(2000,0,1,0,0,0);
d.setMilliseconds(d.getMilliseconds()+milliSecs);

return d.toTimeString().slice(0,8);
}

MaDmiX
Sep 21st, 2012, 01:02 AM
Cool. I did not know about that function. I am learning so much but there is still sooo much I don't yet know.

Best regards,

Ken