Alec Pojidaev's InfoPath Blog
Stuff published for no reason (cool codeless infopath solutions mostly)

Accessing rows in repeating group for browser enabled forms

There are not so many differences in versions of XPath between regular forms and web enabled ones. But inability to reference rows in web enabled forms by the index is one of the most annoying. Here are several XPath formulas useful when interacting with repeating tables:

1. The current row index expression:
count(preceding-sibling::*[local-name() = “MyRepeatingGroup”])
As you can see that formula successfully substitutes the position() function not available in web forms.

2. Accesing value of the previous row:
preceding-sibling::my:MyRepeatingGroup[count(preceding-sibling::my:MyRepeatingGroup) = count(current()/preceding-sibling::my:MyRepeatingGroup) – 1]/my:FieldToAccess

3. Implementation of the last() function:
my:MyRepeatingGroup[count(following-sibling::*[local-name() = “MyRepeatingGroup”]) = 0]/my:FieldToAccess

4. Count all rows that have duplicates:
count(my:MyRepeatingGroup[following-sibling::*/my:FieldToAccess = my:FieldToAccess])

Form to try.

5. The other technique demonstrates idea of how to wright into repeating group by providing index of the row and a value:
Form to try.

Happy codeless programming!

46 Responses to “Accessing rows in repeating group for browser enabled forms”

  1. Can you use a similar trick in the following scenario:

    You have two repeating groups of, say, users and groups. You have one ContactSelector control. You enter all contacts in the control linked to Group1 and then your rule copies all groups to Group2 and removes them (code only?) from Group1.

    Thanks for sharing.

    • It’s possible to delete rows with rules only (see one of my posts). But it’s looks like your problem not what InfoPath is capable to do but rather design you trying to implement. What exactly you trying to achieve?

      • Whoa, this one: a nasty boy you are! looks like ages old sytem date/time cheat for pirate software ;-)

        I’m trying to let users fill in ONE ContactSelector and then split the values into a couple of groups for further processing by other tools. For example to assign item-level permissions (decision makers / readers) on the form files.

      • Any special reason why you trying to limit amount of CS controls to just one?

      • It’s not the number of controls, rather the validity of data therein. The user may enter whatever they want in two controls as well, but the system should sort out who belongs where and separate them correctly. Aside from manipulating children of groups, other goals of the form seem to be attainable without custom .NET coding.

      • What criteria system gonna use to separate one user from another?

      • Two criteria: AccountType=’User’ or not (‘DistributionList’, ‘Group’) and AccountId present in an external datasource or not.

      • So far I can’t see why you need to copy things. What I would do is creating second control related to the same group and apply conditional formating so in first control instance you will see all accounts with “User” type and the other control will show you the rest. It’s also not a big deal to apply additional conditions allowing to take into account data from other sources.

      • So it’s not ‘remove all’ that I need here but rather ‘add one to the existing instances’, ‘move one of a kind’, ‘modify one of a kind leaving others intact’, ‘remove one of a kind’.

  2. Hi –

    i’m trying to implement this but I’m unsure of what I’m doing. I need to update approximately 40 fields in this way. I think I’ve figured out how to structure the second action (step 3) for all my fields, but how do I use the index for multiple groups? Or groups within groups? Do I need an index field for each group? Do I have to create a rule as in step 2 for each group? How would I do it for the nested groups?

    For instance, I have the following groups:

    gpCommonFields > gpRequesterInfo
    gpCommonFields > gpApplicationInfo

    Any help woule be REALLY appreciated. I’m at my wits end and in the office on a Saturday so I can complete this by a deadline coming on Tuesday. Not fun….


    • First of all what are you trying to achieve by aplying this method?

      • Hey – thanks for the reply! OK, I have a list with a lot of fields – 130ish. Our requesters currently use an infopath form that opens in the IP client and displays around 40 of the list fields to submit right up to our sharepoint list and it works fine. From there, another group edits the items from the list itself. However the company I work for just acquired another company and all their workstations do not have the InfoPath client installed on them so we need to be able to render the existing form in the browser. Does that help or are you looking for different information?

    • I still don’t have clear picture of what is going on on submit event. It’s important because if you trying to access all 40 fields on submit event the method in my blog wont work. There is a 16 assigments limitation in Infopath.

      • OK, I think I see. On the submit event, in the form that does NOT render in the browser window, I use rules to submit up to the list incrementing by 1 by modifying the manifest file. So for instance the rules look something like this:

        If there’s a limit of 16 fields, then I guess I need to redo the form to only submit 16 fields? Can you give me more informaiton on this limitation? Maybe I can revamp the form…make it into multiple forms or something that appear as if they’re one form or something like that.

        BTW – it’s very cool that you’re so responsive. I appreciate it greatly.

      • >If there’s a limit of 16 fields, then
        >I guess I need to redo the form to only submit 16 fields?

        Its probably wont be enough. Moving data from repeating section to the promoted field takes 2 actions (assign to the “index” and final assignment). That means you can process only 8 fields per single event. So if 8 fields is not an option I would look into more aggressive redesign.

      • Oops….it looks like the example I pasted in there didn’t work. Let me try it this way:

        The submit option rules look like this:
        set a fields value: Field [1] =
        Set a fields value: Field [2] =
        It iterates through the 40 fields this way and the final action is to submit using a data connection which uses the lists.asmx web service UpdateListItems operation.

        Hope that provides more clarity.

  3. I was just trying to filter my repeating table to keep it to page size. I’ve always done this with position before and came unstuck an my first forms services project. Using
    count(preceding-sibling::*[local-name() = “MyRepeatingGroup”])

    with the name of my repeaitng group saved the day. Alec thanks very much you are a star

  4. Hi – I have tried implementing your solution into a form I am building where I am trying to track the value of the most recent field in a repeating section. The issue I run into is when I use the max function (i.e., max(MaxIndex) + 1). I have downloaded the sample form you provided above and made Max Index a visible field. On your form, it displays as 0 (then increments as I add new sections). On my form, it displays as NaN and never changes as I add new sections. I have modified my form to exactly reflect your form, but for some reason, I still get NaN on my form even though it is exactly the same. Any help would be greatly appreciated! -Clay

    • > even though it is exactly the same.
      To Clay:
      Sorry, in that case I can’t help. If everything on a form is “exactly the same” that means something wrong not in infopath but on your computer (i.e. installation files are corrupted, registry keys are misplaced, bad blocks on harddrive or other things alike)

  5. Hi Alec,
    I’m back. First of all, thank you so much. I already got the job where I took my on-the-job training.
    Now I’m faced with new problem but a simple one for you I’m sure. Using the method you presented here, is it possible to autonumber every section using expression box without adding additional fields like the “NewValue” and “index” fields in your sample? either way can you give me a sample? or atleast the formula?
    for example my repeating section contains a text “Section” followed by expression box which will hold the number. Every section added will then show:
    Section 1
    Section 2
    Section 3
    I successfully used position() function for this but it doesn’t work for web-enabled forms.
    I have been tweaking your formula but can’t get it to work :(
    Hope to hear from you soon. Thanks!

    • There is formula for autonumbering that uses max() function. Just google for autonumbering infopath

      • Thanks for the quick response.
        I’ve been googling for days trying different formula but can’t get it to work.
        Your form does work when I added an expression box in the repeating section beside the text “Field To Set” using the formula
        1 + number(substring-before(substring-after(concat(/my:myFields/my:index = count(../preceding-sibling::*[local-name() = “RepeatingGroup”]), /my:myFields/my:NewValue, “true”, ., “true”), “ue”), “true”))
        but this depends on 3 fields (NewValue, index and source4Dropdown)
        I just thought that since my requierment is simpler than your sample here, we can get away with less additional fields or none at all.
        I have just googled the max() function but it’s used to autonumber forms and not the repeating sections.

  6. Hi,

    I think your blog is going to help me, but being fairly new to Infopath and programming I’m hoping you might be able to help.

    I have a repeating section for “Client” that users fill in, I want to create a button to allow the user to copy the values of the address fields from the first instance of the client repeating section to the one the they’ve just created. There could be quite a few clients in one form so I’m not sure of the best way to do this, but I’m happy to limit it to copying the value from the first instance to the value of the latest instance added.

    Therefore, I’d just have one button outside the repeating section and when they add a second client, to repeat the address info, they click the button.

    I’ve got an understanding of XPathNavigator etc, but I’ve not yet used any of the functions with it, and have been unable to find a nice simple resource telling me what they are and what they do. It is a browser enabled form.

    In the meantime, I’ll get back to searching, thanks in advance.

    • I suggest you should seek some help on specialized InfoPath forums designed to be place where skiled people can help others. This site is not designed nor have enouth means to serve people in the way that specialized InfoPath forums can do.

  7. I am into a mess and see some response from you as the last option. I need to get all the managers selected for the users in the contact selector. The form is a browser enabled. I wrote C# code to get it but there seems to problem in my sharepoint environment and I can’t publish it to the central admin. The only option left with me is to try and get the managers without the code. The example given by you I tried but it does not concatinate properly. When I pick say ABC and XYZ it always conacatinates the email or ABC twice. Please give some ideas. Thanks in advance

  8. Regarding example 2 – can this be automatically populated? That is, when the user adds a new row, it automatically populates a field with another field from the previous row?

    Also, thanks for your no-code solutions!

  9. I like the last comment about repeating the last row entered. So I am trying to replicate your form. I ran into an issue. I cant replicate it. source4Dropdown is a counter. I created a repeating table and tried to add the formula count(Counter) – 1, but IP is returning count(.) – 1 and this fiedl value does not change. when I modified your fornula it went from
    count(source4Dropdown) – 1 to count(.) – 1 and it also failed. so how did you enter the formula so it would work.

  10. Hey Alex, I am sure you are busy. I think I figured out what was going on. I am using IP 2010, and this is where I am having an issue. I find in the client this works perfectly, once published out to the browser form the data entered into the fields delete when I change fields. I was able to make one of your other solutions work where you had a button with rules. I think this may work, if we can skip the first row. Is there a way to use this formula starting on the second row?

    • I can’t reproduce your issue. Everything is working as expected in SP2010

      • My apoligies. It was this option that actually worked. I had found a similar solution that did not use a button, but similar rules, and it caused an issue in the browser. Great job, thanks

  11. I have 2 questions, not really an issue with your script. I can replicate your form, publish it out and it works. When I add it to my my form I get a script error in the core.js, but it works perfectly in the client. Have you experienced this before?
    My xpath for the field to copy is

    the fx used:

    preceding-sibling::my:Product[count(preceding-sibling::my:Product) = count(current()/preceding-sibling::my:Product) – 1]/my:Location

    Am I missing something?

    question 2. is there a way to use this functionality to copy a repeating table. I have a repeating section with a nested repeating table, when I click the button to copy a field in the section I would like to copy the repeating table also. Can this be done?


    • I’ve tested them and there was no any single problem related to this form in both 2007 and 2010 versions.

      • I understand. I know your form and code works. I was able to replicate it. I was just curious if you heard of anything similar. Maybe related to a setting or version.

        How about the second question? Is there a way to copy the repeating table from on row to another?

        thanks for your time

  12. So, I don’t know any of the fancy language… When I use preceding-sibling::my:MyRepeatingGroup[count(preceding-sibling::my:MyRepeatingGroup) = count(current()/preceding-sibling::my:MyRepeatingGroup) – 1]/my:FieldToAccess
    to populate a field it works just fine when it is opened in infopath. When it opens in the browser the first instance in the table goes to zero…. what am I doing incorrectly???

  13. Hi Alec,

    I have a form with two repeating tables based on the same repeating group. The first table shows only Type A items (conditional formatting), and the second table shows only Type B items. There are 4 check boxes for rating, where multiselect is possible but only neighboring boxes. With Rules the other boxes are cleaned.
    When published as browser form, the check boxes in ALL rows in both tables are cleaned instead of only in the current row.
    Is there a way with XPath to keep the scope of the action to the current row only?
    I want to include the form here, how can I do that?

  14. I have followed your work for some time now, always impressive. I am trying to identify a row number in a repeating table that is setup with multiple default rows. I know I can set a field value, but I dont want to do this on every form it can be time consuming. What happens with your example all the rows have the same value, usually the lowest. is there a codeless way to achieve this?

  15. Hi Alec, thanks a lot for this post. Saved me from writing code.

    Question: what’s the purpose of “true”, ., “true”? Don’t you just need one true? Why add the . and the other true – within the concat?

  16. Hi Alec, thanks for this. I have found out tyhat whenever I use this rule on any of my fields, I get “Could not verify the form template on the specified server” error. Any idea wjy it is so? Removing it pass the design checker tests.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: