Let's say you have a field in a repeating group that you'd like to set to the value of another field in your form. Pretty straight-forward, right? Set a rule on the field with the desired value, and when you change that value, all the instances of the repeating field get set to that value.
What? That wasn't your desired result? You only wanted to set some of those fields to the new value? All I have to say is we should be very grateful to Jimmy Rishe, who has posted an ingenious solution to this problem!
I thought it was worth a walkthrough, with a sample and some screenshots, so that's what we are going to do today.
Here is the sample form we are going to use (without the hack -- you get to do that part yourself). Right click the link and select Save Target As... to save the file locally. Once you've done that, right click the .xsn file and select Design to open the form in design mode.
A big shout out to Toby for the data structure inspiration, which looks like:
I've set up our sample form with some default values so that when you preview it, it will look like this:
I'm using a button for our rule to give us more control over when the values change. Currently, the button doesn't have any rules associated with it yet, so it won't do anything. You can click it though, if you like. It does say 'Click Me', after all.
Our goal is to set any baseCost nodes to the value in the newValue field ... but only if the itemType is equal to 'Labor'. The first step is to add a rule to the 'Click Me' button. Double-click the button to open the Button Properties window (unless you are working in Visual Studio, at which point you've just added a 'Clicked' event to your button -- one of those behavior inconsistencies that makes me mildly daffy).
Click the Rules button to open the Rules dialog and click Add to add a new rule:
Give your new rule a meaningful name:
And click Add Action and select Set a field's value for your action:
Select the baseCost field for the target field:
And click the fx button, then use the Insert field or group button to set the value to the newValue field:
Now that our base rule is in place, I want you to preview the form again. The defaults are set with $12.60 as the baseCost for the items that have 'Labor' as the itemType. Other items have different costs associated with them. Before we click the button, our data looks like:
Put a new value in the newValue field and click the 'Click Me' button. All the values in the baseCost fields get changed:
While this is exactly what we'd expect, it isn't what we want. But before we modify the manifest.xsf file, we have one more important step: SAVE YOUR FORM. When working with form files, there is always the chance you may make a change that will prevent you from being able to open your form ever again, in design mode or to fill out. It is never worth the risk. Always save a copy before saving as source files.
Next, from the File menu, select Save As Source Files... and save the files someplace you can find them. If you are using InfoPath 2003, I believe the command is Export to Source Files, but it has been long enough that I can't really remember. (As an aside, if you are still using 2003, I encourage you to upgrade, if for nothing else than the ability to copy the xpath of a field from the Data Source Task Pane. It is invaluable. You can still design forms for 2003 -- the rest of your organization doesn't have to upgrade, but if you are doing very much design work, I think 2007 will save you time and headaches.)
Open the manifest.xsf with your favorite text editor. (Another aside: I really really really love Notepad2. It has parenthetical highlighting. If you have a formula that is giving you errors, you can paste it into Notepad2 and quickly find your missing parenthesis. It also has syntax highlighting for a variety of file types.) Since the form is very simple, our rule will be easy to find -- it is at the bottom of the file. If your form is more complex, you can search on your rule name to find it in the manifest.
Our rule looks like this:
<xsf:rule caption="Set Base Cost for Labor Items">
<xsf:assignmentAction targetField="my:items/my:baseCost" expression="my:newValue"></xsf:assignmentAction>
Next, we add an XPath filter to the targetField attribute of the assignmentAction element to specify that this action should only apply to our items with an itemType of 'Labor':
<xsf:assignmentAction targetField="my:items/my:baseCost[../my:itemType='Labor']" expression="my:newValue"></xsf:assignmentAction>
Save your changes and close manifest.xsf. Right click the file and select Designto re-open the form in design mode. If it doesn't open, you've done something bad and either have to figure it out and fix it, or go find your saved version and start again.
Check your rule. If your XPath is valid, you'll see the expression underlined in the rule action:
Preview your form, and enter a new value in the newValue field. Click 'Click Me', and voilà!
To repack it all up, close the preview and select Save As from the File menu. Have fun, amaze your friends and co-workers with your new code-free magic and don't forget to thank Jimmy!