Geeks With Blogs
Adrian Hara Working through the .NET maze

When you want to pass data from a Sharepoint workflow to a task InfoPath form, the recommended method (in fact I don't know of any other one) is using a "receive data" data source, defined by the ItemMetadata.xml file. The structure of this file is documented in various places around the net, for simple data types (like, say TextBox-es or CheckBox-es). Unfortunately, when it comes to passing data to complex controls like the drop-down list , it seems there just is a void of information, although people are in need of such a functionality. Several posts on the MSDN forums debate the issue, like this one or this one, but, although they pointed me in the right direction, they failed to give a complete and conclusive example of how to do it. So after going through the pain of getting the stuff to work, here's a step by step walkthrough that should, hopefully, spare you the "research" involved:

The overview, before going into details, is this: create some fields in the main data source to which the drop-down list will be bound, then populate these fields dinamically at runtime with data from the secondary (ItemMetadata) data source.

You might be surprised to hear that the drop-down list will read its data from the main data source (I know I was), since the first idea would be to have it get its data from the "receive data" data source (defined by the ItemMetadata.xml file). Unfortunately it sems that the ItemMetadata.xml file can't contain "complex data" (here's that word again...), just simple "rowset" data, so it's no good for populating a drop-down list (whose fields are defined by two attributes, Name and Value). So what we have to do is basically receive the data for the list in a (ONE) field of the secondary data source, then "copy" this data into the fields of the main data source.  I say "copy" because since we're putting "complex" (three times now...) data into one field, there might be multiple ways to do it. I took the approach where the field will store the exact xml needed by the main data source fields, and then just replace it at form load. So without further ado, here's what you have to...umm...do:

  1. In the InfoPath designer, goto Data Sources and:
    • add a group, let's call it "Teachers"
    • in this group add a repeating field, called "Teacher"
    • under Teacher add two fields, say "Name" and "DomainAccount" (these will be the display text and value of the drop-down list entries)
  2. In your drop-down list properties select "look up values in the form's data source" and:
    • for "entries" choose the Teacher field
    • for "value" choose "DomainAccount"
    • for "display name" choose "Name"
  3. Open your ItemMetadata.xml file in some editor (Notepad?) and add a new field, for example ows_TeachersData. Be sure to update your secondary data source with the new schema, by specifying the .xml file again.
  4. At this point the drop-down list is set up to get its data, and its data will come in the ows_TeachersData field in the secondary data source. What we still need to do is move this data from the ows_TeachersData field to the Teachers group fields in the main data source. For this you need to have VSTA installed (you can install it from your MOSS dvd). In the form menu goto Tools -> Programming -> Loading event. This will launch VSTA and create an event handler for the form's loading event.
  5. In the FormEvents_Loading method, write the following code:
public void FormEvents_Loading(object sender, LoadingEventArgs e)
               {
                   if (this.DataSources == null)
                  {
                      return;
                  }
 
                 XPathNavigator xmlSource = this.DataSources["ItemMetadata"].CreateNavigator();
           
                XPathNavigator teachers = this.MainDataSource.CreateNavigator().SelectSingleNode("/my:TeachersForm/my:Teachers", NamespaceManager);
                teachers.InnerXml = xmlSource.SelectSingleNode("/z:row/@ows_TeachersData", NamespaceManager).InnerXml;
             }
 

  All that's left to do at this point is, in your workflow code, to build and populate the TeachersData field. In won't go into details as it's explained elsewhere, but the data itself should look something like: "<my:Teacher my:Name="blah" my:DomainAccount="blablah"></my:Teacher><my:Teacher my:Name="blah1" my:DomainAccount="blablah1"></my:Teacher>...etc"

As a final tip, if you first want to test your code before deploying it (which you should do, as testing it directly in Sharepoint is a pain, because of the needed iisresets and such), you can just press F5 in VSTA to debug. An essential condition here is that the form security is set to "Full Trust", as opposed to "Domain" which should be set when deploying to Sharepoint, otherwise you'll get an error when opening the form.

Posted on Sunday, September 16, 2007 5:15 PM | Back to top


Comments on this post: Howto: populate a drop-down list of an InfoPath form, in MOSS + WF

# re: Howto: populate a drop-down list of an InfoPath form, in MOSS + WF
Requesting Gravatar...
thank you very much!
Left by soungcha on Aug 14, 2008 11:45 AM

# re: Howto: populate a drop-down list of an InfoPath form, in MOSS + WF
Requesting Gravatar...
How do you store that xml in the ItemMetadata.xml file? I was trying to pre-populate the ItemMetadata.xml file so that I could test my code and make sure it works.

How will the ItemMetadata field be updated with xml data through the workflow?
Left by Bart on Nov 08, 2008 4:08 AM

# re: Howto: populate a drop-down list of an InfoPath form, in MOSS + WF
Requesting Gravatar...
Well, I don't think you can store the data in the file directly. What I did was set the value of the corresponding field in the SPWorkflowTaskProperties.ExtendedProperties at runtime, like so:

taskProperties.ExtendedProperties["TeachersData"] = CreateTheTeachersDataXml();

The CreateTheTeachersDataXml method would create the xml as outlined in the post and that xml string would then be available to the codebehind of the InfoPath form to copy to the appropriate field in the main data source.
Left by Adrian Hara on Nov 12, 2008 4:11 PM

# re: Howto: populate a drop-down list of an InfoPath form, in MOSS + WF
Requesting Gravatar...
Hello,

This is fab, just to be clear, ItemMetadata.xml is like a middle man between your source, and the infopath code behind, right?

Quick question - the example you're giving comes from tasks, which as you say in your last comment, you would "inform" the ItemMetadata.xml of the properties by using SPWorkflowTaskProperties.ExtentedProperties. What if I'm using this infopath form as an instantiation form for a Visual Studio workflow which is kicked off manually from an item in a list? So... I basically want the selections from the "Product" and "Category" drop downs to be transposed to the "Product" and "Category" drop downs in the infopath form when it loads when the workflow is kicked off.

Does that make sense? If so, any ideas how i pass the "Product" and "Cateogry" values into the itemmetadata.xml file so that the infopath form can access them?

Thank you!
Left by Ben on Nov 03, 2010 7:05 AM

# re: Howto: populate a drop-down list of an InfoPath form, in MOSS + WF
Requesting Gravatar...
You're right about the middle-man thing.

Regarding sending data to the instantiation form I'm sorry to say I have absolutely no clue. I haven't worked with SharePoint in the last years so I'm quite disconnected. I wouldn't be surprised if there actually weren't any way to do it :)

In any case, if you ever find out, please add a comment to let us know.

Thanks!
Left by Adrian Hara on Nov 03, 2010 7:41 AM

Your comment:
 (will show your gravatar)


Copyright © Adrian Hara | Powered by: GeeksWithBlogs.net