Wednesday, May 1, 2013

InfoPath Master/Detail with SharePoint List Sources

I picked up some InfoPath requirements after one of our consultants had to leave so this one had to be done after dusting off the InfoPath brain cells.  I’m still not convinced this is the best way to get this done so please leave a comment if there’s a better way.
The InfoPath form needs to connect to two different SharePoint lists.  The first list is a list of Orders and the second is a list of Versions that apply to an Order.  There can be multiple Versions for each Order.  The goal was to create a master/detail type action where a user selects an order from a drop down, which then reloads the form with all of the version(s) and version details for that order displayed in a repeating table.  Doesn’t sound too hard, but I ran into some road blocks and had to resort to code.
Both roadblocks had to do with SharePoint lists as a source.  I don’t know if this is specific to SharePoint sources or just external sources in general, but you can’t use a SharePoint source in a master/detail relationship.  After dragging it onto the form, right click on the repeating table and view the properties.  The master/detail section is grayed out.  The second thing I ran into was trying to filter the SharePoint connection.  No luck there either, it’s not available.
After some searching, I found a post on implementing master/detail for a web based formwhich detailed some steps to pull in SharePoint data using a different method.  Instead of using the SharePoint List option when creating the connection, you use the XML option and point it to a URL which outputs the list data in XML format.  I won’t cover the details of that here as he covers it his post very well, but it’s using owssvr.dll.  That post solved my issues completely, but it was using code for InfoPath 2007.  I needed to convert that to be 2003 compatible. 
Since the 2003 compatible code is probably the only useful part of this post, here it is:


   1: public void OrderName_OnAfterChange(DataDOMEvent e)
   2: {
   3:     //Capture the new value for Order so we can filter the data just for that order
   4:     string newOrder = e.NewValue.ToString();
   5:  
   6:     //Get a reference to the Card Version Adapter
   7:     XMLFileAdapterObject cardVersion = thisXDocument.DataAdapters["Card Version owssvr"] as XMLFileAdapterObject;
   8:  
   9:     //Modify the Card Version adapter URL to append the filter
  10:     cardVersion.FileURL = cardVersion.FileURL + "&FilterField1=Order_x0020_Name&FilterValue1=" + newOrder;
  11:     
  12:     //Re-query
  13:     cardVersion.Query();
  14:  
  15:     if (e.IsUndoRedo)
  16:     {
  17:         // An undo or redo operation has occurred and the DOM is read-only.
  18:         return;
  19:     }
  20:  
  21:     // A field change has occurred and the DOM is writable.
  22:     // Write your code here.
  23: }



Pretty simple, but it took some SDK searching to find the right classes.  I’m using the XMLFileAdapterObject to grab the “Card Version owssvr” data connection, then I change the URL using FileURL similar to how Ishai modified the FileLocation property of the FileQueryConnection object.  Like I said, nothing fancy, but I thought it may come in handy for folks looking for a solution similar to Ishai’s, but who can’t use InfoPath 2007.

No comments:

Post a Comment