Move Up/Move Down

One stumbling block for developers coming up to speed on InfoPath is that the SDK documentation leads you to the edge of the XML cliff and then goes mysteriously quiet. For web developers who have programmed applications with the MSXML SDK for manipulating XML this isn’t a problem – they brought their parachute with them and happily jump off. For others, this can be a little intimidating.

Here’s a good way to get started manipulating the XML DOM directly – let’s add “Move Up” / “Move Down” buttons to a Repeating Table so you can re-order the items.

First off, let’s build the view:

  1. Fire up InfoPath 2003 and start a new blank form
  2. Insert a Repeating Table from the Controls task pane
  3. Delete the text box in the last column, and add two buttons in that cell instead
  4. Pull up the properties on first button and give it the label “5” and the ID “MoveUp”
  5. Pull up the properties on second button and give it the label “6” and the ID “MoveDown”

 At this point, you’re thinking “5 and 6???”

  1. Select both buttons (Click the first, and Ctrl+Click the second)
  2. On the Font drop-down on the toolbar, select Marlett. Then take a look at the buttons.

(Sneaky, huh? Glyphs from this font are used by Windows to render all sorts of UI elements like the Minimize/Maximize Window buttons. This is a handy way to avoid having to use images for simple things like arrows.)

Now that we have it looking pretty, let’s add the event handlers for the buttons. We’ll build on the logic from this blog entry to figure out which instance of the buttons was clicked.

  1. Pull up the properties on the first button and click Edit Code – paste the following into the editor:

Sub MoveUp_OnClick(eventObj)

' Write your code here

 

   Dim oItem, oParent, oPrevious

  

   Set oItem = eventObj.Source

   Set oParent = oItem.parentNode

   Set oPrevious = oItem.previousSibling

  

   If Not ( oPrevious Is Nothing ) Then

         

          oParent.removeChild oItem

         

          oParent.insertBefore oItem, oPrevious

         

   End If

 

End Sub

The logic here is straightforward:

  • Grab the context node of the button (the row of the table, in our case)
  • If there is another item before the context node, remove the context node from the tree and re-insert it before the previous node
  1. Pull up the properties on the second button and click Edit Code – paste the following into the editor:

Sub MoveDown_OnClick(eventObj)

' Write your code here

 

   Dim oItem, oParent, oNext

  

   Set oItem = eventObj.Source

   Set oParent = oItem.parentNode

   Set oNext = oItem.nextSibling

  

   If Not ( oNext Is Nothing ) Then

         

          oParent.removeChild oNext

         

          oParent.insertBefore oNext, oItem

         

   End If

 

 

End Sub

The logic here is similar:

  • Grab the context node of the button (the row of the table, in our case)
  • If there is another node after the context node, remove the it and re-insert it before the context node

Almost done – let’s just use a little Conditional Formatting to disable the buttons when the item is the first or last in the list:

  1. Add a conditional for the first button which reads:

    if “The expression” “position() = 1” then Disable this control
     

  2. Add a conditional for the second button which reads:

    if “The expression” “position() = last()” then Disable this control

Now try it out.

As an aside, this was the author’s first foray into VBScript. Although I cut my teeth in Applesoft BASIC I’ve done most of my programming in C-style languages (C, C++, C#, Perl, Java). Did I do anything silly?