Code sample to change depth of recurring fields
TRICK: Changing the Depth of Recurring Fields
Applies to: Microsoft Office InfoPath 2003 SP1
Summary
You can use the following script for promotion and demotion of recurring nodes in single depth recurrences. (This does not work in the case of a*/b/a*…). To work in your code, simply change the names of the parameters at the top and attach this code to events in your form code.
SP1 Feature Usage
Schema recurrence
Form Code
The following form code is written in JScript.
// **** PARAMETERS ****
// Change these parameters to work with your XSD
// The name of the recurring node
var g_fRecurringNodeName = "my:section";
// The name of the non-recurring node immediately after the recurring node (if none, set to null)
var g_fNextNonRecurringNodeName = "my:HwsComments";
// **** FUNCTIONS ****
// Promotes the node up a level.
// if fAdoptRightSiblings is true, oNode's succeeding recurring siblings become its children.
// else these siblings stay with their parent (they reorganize in the view)
function PromoteNode(oNode, fAdoptRightSiblings)
{
if(!IsRecurringNode(oNode))
{
alert("Promote Section - the argument is not a recurring node.");
return;
}
// do not promote if parent is not a recurring node
if (GetDepth(oNode) == 0)
{
alert("Cannot promote - this is already at the top level.");
return;
}
// if adopting, move the succeeding siblings to be the children of oNode
if (fAdoptRightSiblings)
{
while (oNode.nextSibling && IsRecurringNode(oNode.nextSibling))
{
var oBefore = (g_fNextNonRecurringNodeName) ?
oNode.selectNodes(g_fNextNonRecurringNodeName) : null;
oBefore = (oBefore) ? oBefore[0] : null;
if (!oBefore)
{
oNode.appendChild(oNode.nextSibling.cloneNode(true));
}
else
{
oNode.insertBefore(oNode.nextSibling.cloneNode(true), oBefore);
}
oNode.parentNode.removeChild(oNode.nextSibling);
}
}
// Move oNode up a level
if (oNode.parentNode.nextSibling)
{
// has siblings
oNode.parentNode.parentNode.insertBefore(oNode.cloneNode(true), oNode.parentNode.nextSibling);
oNode.parentNode.removeChild(oNode);
}
else
{
// no siblings
oNode.parentNode.parentNode.appendChild(oNode.cloneNode(true));
oNode.parentNode.removeChild(oNode);
}
}
// Demotes the node down a level
function DemoteNode(oNode)
{
if(!IsRecurringNode(oNode))
{
alert("Demote Section - the argument is not a recurring node.");
return;
}
var oPrevious = GetPreviousRecurringNodeSibling(oNode);
if (!IsRecurringNode(oPrevious))
{
alert("Cannot demote - this recurring node does not have a previous sibling recurring node.");
return;
}
// move the node down a level
// ...by making it the last recurring child of the previous sibling
var oBefore = (g_fNextNonRecurringNodeName) ?
oPrevious.selectNodes(g_fNextNonRecurringNodeName) : null;
oBefore = (oBefore) ? oBefore[0] : null;
if (oBefore)
{
oPrevious.insertBefore(oNode.cloneNode(true), oBefore);
}
else
{
oPrevious.appendChild(oNode.cloneNode(true));
}
oNode.parentNode.removeChild(oNode);
}
//Returns the depth of the recurrence as an integer. If this is the top level, returns 0.
function GetDepth(oNode)
{
if (!IsRecurringNode(oNode))
{
alert("GetDepth - the argument is not a recurring node");
return;
}
var nCount = 0 ;
while (IsRecurringNode(oNode.parentNode))
{
nCount++;
oNode = oNode.parentNode;
}
return nCount;
}
// Is the particular node a Recurring Node?
function IsRecurringNode(oNode)
{
if (!oNode) return false;
return (oNode.nodeName == g_fRecurringNodeName);
}
// Finds the first preceding sibling that is a recurring node.
// This function is for choices and mixed content.
Comments
- Anonymous
March 23, 2004
See http://blogs.msdn.com/infopath/archive/2004/03/23/94981.aspx for a download that demonstrates this code.