Infopath is a great tool for rapidly developing an application which
gathers information from the user. Many times these applications uses
start time and end time as their fields. Infopath has a “Time”
datatype. We can directly assign this datatype to the fields. You can
compare two fields of this datatype but substraction of fields is not
handled. You have to manually parse the field value, subtract the
values and change the appropriate fields. Here is the proposed solution
of this problem.
This solution contains 3 functions
- UpdateHours()
- convertJScriptNumberToXML()
- roundFloat()
Lets see all these functions one by one.
function UpdateHours(){
var TimeIn = XDocument.DOM.selectSingleNode("/my:Time/my:StartTime").text;
var TimeOut = XDocument.DOM.selectSingleNode("/my:Time/my:EndTime").text;
var index1 = TimeIn.indexOf(":");
var hi = TimeIn.substring(0,index1);
var index2 = TimeIn.indexOf(":", index1+1);
var mi = TimeIn.substring(index1+1, index2);
index1 = TimeOut.indexOf(":");
var ho = TimeOut.substring(0,index1);
index2 = TimeOut.indexOf(":", index1+1);
var mo = TimeOut.substring(index1+1, index2);
var ti = parseFloat(hi) + (mi/60);
var to = parseFloat(ho) + (mo/60);
var tt = to - ti;
var node = XDocument.DOM.selectSingleNode("/my:Time/my:TotalHours");
if (tt != "" && node.getAttribute("xsi:nil"))
node.removeAttribute("xsi:nil");
node.nodeTypedValue = convertJScriptNumberToXML(tt);
}
As
the name suggests, this function updates the value of “TotalHours”
field. First of all, it will get the value of “StartTime” and “EndTime”
field. The value will be in the format of HH:MM:SS. So the value will
be parsed according to the position of “:”. Both the values will be
converted inot the float representation. Now value will be sutracted
and the result will be stored in “TotalHours” field.
function convertJScriptNumberToXML(value){
var retVal;
switch (value) {
case Number.NEGATIVE_INFINITY:
retVal = "-INF";
break;
case Number.POSITIVE_INFINITY:
retVal = "INF";
break;
case value:
retVal = roundFloat(value,2);
break;
default:
retVal = "NaN";
}
return retVal;
}
This function converts the actual number into text based value. Here he number will be rounded upto 2 digits.
function roundFloat(value, decimalPlaces){
if (value < -1E15 || 1E15 < value)
{
return value;
}
else
{
var nPowerToRound = Math.pow(10, decimalPlaces);
return Math.round(value*nPowerToRound)/nPowerToRound;
}
}
This
function actually rounds the float value to the required decimal place.
To apply this code to your application, copy/paste these three
functions into the script file. In the “OnAfterChange” event of start
time and end time field, call the function “UpdateHours”.
Note: Please put the downloaded code in C:\