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 subtraction 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 into the float representation. Now value will be subtracted 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 up to 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:\
Leave a Reply