I'm new to Infopath and have built a form so that we can keep track of current jobs we are working on. This form has a repeating table to create categories and in that table, another repeating table to list the jobs in that category.
My problem is...when i go to sort the jobs by the ones completed (used to Asset Tracking sample for code) the only category that sorts is the first one. When I try to sort the jobs in the second category it also just sorts category 1.
The code I used is below. Does anyone know a way to sort only the current category you are in (button to sort is in a column header).
//<namespacesDefinition>
XDocument.DOM.setProperty("SelectionNamespaces", 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2007-01-06T19:05:06" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003"');
//</namespacesDefinition>
// Counter used to create a unique key for each Asset.
var g_iCounter = 1;
// The relative XPath from <asset> to the element used for comparison.
// It has value only when the sort is in progress.
var g_xpathSortBy = "";
// The nodes of double type should be compared as numbers, not as text.
var g_parseAsNumber = false;
/*==============================================================================
Private functions
==============================================================================*/
function getValue(xmlNode)
{
if (g_parseAsNumber && !isInvalidOrEmpty(xmlNode))
{
var value = convertXMLNumberToJScript(xmlNode.nodeTypedValue);
if (!isNaN(value))
return value;
}
return xmlNode.text.toLowerCase();
}
function compareAssets(xmlAssetLeft, xmlAssetRight)
{
var xmlLeft = xmlAssetLeft.selectSingleNode(g_xpathSortBy);
var xmlRight = xmlAssetRight.selectSingleNode(g_xpathSortBy);
var valueLeft = getValue(xmlLeft);
var valueRight = getValue(xmlRight);
if ((valueLeft < valueRight) || (typeof(valueLeft) == "number" && typeof(valueRight) == "string"))
return -1;
else if ((valueLeft > valueRight) || (typeof(valueLeft) == "string" && typeof(valueRight) == "number"))
return 1;
else
return 0;
}
/* =============================================================================
Node value operations
============================================================================= */
/*------------------------------------------------------------------------------
isInvalidOrEmpty()
------------------------------------------------------------------------------*/
function isInvalidOrEmpty(xmlNode)
{
// If there is no value, ignore it.
if (!xmlNode || !xmlNode.text)
return true;
// The caller can pass additional error types as optional arguments.
var aErrorTypes = new Array;
if (arguments.length > 1)
{
for (var i=1; i<arguments.length; i++)
aErrorTypes.push(arguments);
}
else
{
aErrorTypes.push("SCHEMA_VALIDATION");
}
// If there is a validation error related to this node,
// then the node is invalid.
for (var i=0; i<XDocument.Errors.Count; i++)
{
var oError = XDocument.Errors(i);
if (xmlNode == oError.Node)
{
for (var j in aErrorTypes)
{
if (oError.Type == aErrorTypes[j])
return true;
}
}
}
// Is valid (no error was found).
return false;
}
/*------------------------------------------------------------------------------
getNodeValue()
------------------------------------------------------------------------------*/
function getNodeValue(xpath, defaultValue)
{
var xmlNode = getNode(xpath);
if (isInvalidOrEmpty(xmlNode))
return (arguments.length > 1) ? defaultValue : "";
else
return xmlNode.text;
}
/*------------------------------------------------------------------------------
getNode()
------------------------------------------------------------------------------*/
function getNode(xpath)
{
// Both XML node and absolute XPath are allowed.
if (typeof(xpath) == "string")
return XDocument.DOM.selectSingleNode(xpath);
else
return xpath;
}
/*------------------------------------------------------------------------------
getNodeList()
------------------------------------------------------------------------------*/
function getNodeList(xpath)
{
// Both XML node and absolute XPath are allowed.
if (typeof(xpath) == "string")
return XDocument.DOM.selectNodes(xpath);
else
return xpath;
}
/*------------------------------------------------------------------------------
count()
------------------------------------------------------------------------------*/
function count(xpath)
{
var xmlNodeList = getNodeList(xpath);
if (xmlNodeList)
return xmlNodeList.length;
else
return -1;
}
/*------------------------------------------------------------------------------
sort()
------------------------------------------------------------------------------*/
function sort(xpathParent, xpathChildren, fnCompare)
{
// Retrieve the parent node; all the children will be sorted.
var xmlOrigParent = getNode(xpathParent)
var xmlItems = xmlOrigParent.selectNodes(xpathChildren);
if (1 < count(xmlItems))
{
// Store the (pointers to) items in an array for faster access.
rgItems = new Array();
while (xmlItem = xmlItems.nextNode())
rgItems.push(xmlItem);
// Sort the array (the XML does not change).
rgItems.sort(fnCompare);
// Now that the array is sorted the DOM should be updated.
var xmlSortParent = xmlOrigParent.cloneNode(true);
var xmlClones = xmlSortParent.selectNodes(xpathChildren);
xmlClones.removeAll();
// Update the nodelist, each item is moved only once.
// (each change is causing several notifications to be fired.)
for (var i=0; i<rgItems.length; i++)
xmlSortParent.appendChild(rgItems.cloneNode(true));
xmlOrigParent.parentNode.replaceChild(xmlSortParent, xmlOrigParent);
}
}
//=======
// The following function handler is created by Microsoft Office InfoPath.
// Do not modify the name of the function, or the name and number of arguments.
//=======
function btnSortChecked::OnClick(eventObj)
{
// Avoid side effects when DOM is read only.
if (XDocument.IsDOMReadOnly)
return;
// It is used by comparison function, and to flag sort in progress.
// The generation of unique keys is suppressed while sort is in progress.
g_xpathSortBy = "my:Completed";
if (!g_xpathSortBy)
return;
sort("/my:Job_Tracker/my:Category", "my:JobList", compareAssets);
// Unblock generation of unique keys.
g_xpathSortBy = "";
}
Thanks for any help.