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.