« Creating Knockout User Experiences in SharePoint with JavaScript and REST services | Main | Pretty up SharePoint 2010 mysite with showModalDialog (updated) »
Sunday
Feb052012

InfoPath how to copy a repeating section using rules

For years, we all thought this was impossible.  You had to use code.  I somehow woke up with an idea on how to do this, and set about testing and to my surprise, found a solution.  Here it is!

 

The form set up

image

  • Two repeating sections, Foo's and Bar's
  • One additional integer field i to control which row to copy

Put the elements on the form:

image

 

 

The copy rule

Create a rule on the integer field i

  1. We will use the normal action, then tweak it. 
    Give this rule the name "Copy"
    Start by defining a set field value rule.
    image
  2. Set /my:myFields/my:Foos/my:Foo/my:F1 to /my:myFields/my:Bars/my:Bar/my:B1
    image

    There are a few issues so far with the default Set Field Value action related to a repeating section.
    • For the Field (target), it will set ALL the matching nodes.
    • For the Value, it will get the First matching node.
  3. Let's fix the second value - we can do this in InfoPath designer.
    image

    The expression is:
    ../my:Bars/my:Bar[number(../../my:i)]/my:B1

    This expression lets us copy a different row.

    image

    So we can now copy value from any row - depending on what the number i is.
  4. To fix the Field Target is a bit more difficult.  InfoPath designer doesn't give us a way to modify the XPath of the field.

  5. Save the form.  We're about to do unsupported stuff. 
  6. Publish the form to Source Files. 
    image

    I publish to C:\Temp\CopyForm\
  7. Close InfoPath designer.  Open the file C:\Temp\CopyForm\manifest.xsf file using NotePad or your favourite XML editor.
  8. The "Copy" rule is hiding in this XML file, it looks like this:
  9. <xsf:rule caption="Copy">
        <xsf:assignmentAction targetField="../my:Foos/my:Foo/my:F1" expression="../my:Bars/my:Bar[number(../../my:i)]/my:B1"></xsf:assignmentAction>
    </xsf:rule>

  10. Change it to:
  11. <xsf:rule caption="Copy">
    <xsf:assignmentAction targetField="../my:Foos/my:Foo[number(../../my:i)]/my:F1" expression="../my:Bars/my:Bar[number(../../my:i)]/my:B1"></xsf:assignmentAction>
    </xsf:rule>
  12. Save, and close Notepad.  Re-open manifest.xsf file using InfoPath Designer
  13. Let's check our rule.
    image
  14. Are you thinking what I'm thinking?  We're nearly there.

The loop

  1. This rule is set on the number i, and runs once whenever the number i changes.
  2. Lets set it up to increment.
    image
  3. Add a condition to stop incrementing when we've run out of rows
    image

    image
  4. And to start the whole thing, remember we have a button.

    image

    To start the process, set i to 1.  XML index starts from 1 to n.  Does not start at 0.

 

Result - InfoPath Filler


image
Starting...

image

Press "Copy"

Result - Form Server:

image

Starting Browser Form

image

Copy.

 

Note - InfoPath "Infinite Loop" limitation:

InfoPath is hard coded to only execute 16 rules before throwing the "Infinite Loop" error.

image

An error occurred in the form's rules or code. The number of rule actions or the number of calls to the OnAfterChange event for a single update in the data exceeded the maximum limit.

The rules or code may be causing an infinite loop. To prevent this, ensure that the rule action or event handler does not update the data which causes the same rule action or event handler to execute.

 

There is no solution for hard coded 16 rules.  So your i can not go over 16.

Download

References (1)

References allow you to track sources for this article, as well as articles that were written in response to this article.
  • Response
    Response: mira hair oil
    John Liu .NET - Blog - InfoPath how to copy a repeating section using rules

Reader Comments (6)

Hi I'm a relative noob with InfoPath so please excuse any dumbness here but...

... Am I right in thinking this won't work in browser based form due to lack of support for referencing repeating sections by index number?

Some great info here btw, thanks.

March 20, 2012 | Unregistered CommenterGareth

This works fine in browser forms :-)
See my screen shots above under Result- Form Server

March 22, 2012 | Registered CommenterJohnLiu.NET

This is a great post!

I used this concept to solve a problem that I had and it worked great. I didn't need to edit manifest.xsf because what I was doing was executing a rule (a data connection query) for each row of a repeating table, so my 'set a fields value' target was always the same field. But I did have a bit of trouble specifying the index field in the square brackets ... when I picked the field it put a dot in there, and it would not work. I replaced it with the full relative xpath (../../group/group/field) and it worked.

Thanks much for posting this.

August 1, 2012 | Unregistered CommenterSteve

This is very cool and works very well when both repeating tables have the same number of rows, but how do you add addtional rows to the target table if it doesn't have as many rows?

December 22, 2012 | Unregistered CommenterScott T.

Bad news Scott,

We can't add new rows without using code.
Try adding more default rows in your target repeating section?

January 8, 2013 | Registered CommenterJohnLiu.NET

I feel like i'm close, but I can't get i to increment. I'm using InfoPath 2007. Will this work in InfoPath 2007? Also, I'm trying to trigger the loop when the form opens, by adding a rule on the Form --> Options screen. Do you see any reason why triggering the increment will not work from this entry point?

January 19, 2013 | Unregistered CommenterKen G

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>