Creating A Multiple Selection List Box in A Browser Enabled InfoPath Form
Creating A Multiple Selection List Box in A Browser Enabled InfoPath Form
Reader Assumptions:
Reader is familiar with Infopath
Reader has basic understanding of code
Reader is familiar with SharePoint administration
Prerequisites:
You must have the following installed on your machine:
InfoPath 2007
.Net Programmability Support for Microsoft Office InfoPath
Overview
Multiple selection list boxes are supported in client-based InfoPath forms, but they are not supported in
browser-based forms. This document explains how to work around the limitation using code-behind in
Infopath, the owssvr.dll service call, and publishing an administrative template in SharePoint.
In this example, we will be using the following information. Please substitute the information with the
information germane to your environment:
Checkbox Description
c. Your data source should look similar to this:
2. Add the repeating table on your form. Add as a repeating table:
3. Format your table to your preference.
Before you use the owssvr.dll server, you will need the GUID of the list. If you are also going to
reference a view of the list, you will also need the GUID of the view.
1. In the View drop-down field, select the view you would like to use.
2. In the View drop-down field, select Modify this View
The GUID will appear in the URL in the View query string parameter.
Do the following with the GUID:
Once you have the GUIDs, you are able to set up the data connections.
In our example, we’re only interested in using the List, so the parameter that we will use is List.
Here is the example URL that we will be using:
http://moss2007-dev:8318/_vti_bin/owssvr.dll?Cmd=Display&List={356671C3-DB57-4385-8F0E-
0A3B991A6457}&XMLDATA=TRUE
If you would like further reading on this, please view the appendix at the end of the documents.
3. Select Access the data from the specified location. Do not check Store a copy of the data for
offline use.
4. Enter a user friendly name for the connection and click Finish. Make sure that Automatically
retrieve data when form is opened is checked.
Step 3: Write code-behind to automatically populate the checkboxes
Before you begin, you may want to configure the form to determine:
VB
Public Sub FormEvents_Loading(sender As Object, e As LoadingEventArgs)
Try
Me.Errors.DeleteAll()
If
Me.MainDataSource.CreateNavigator().[Select]("/my:myFields/my:Mul
tiSelectOptions", Me.NamespaceManager).Count <= 1 Then
Me.LoadMultiSelectListBox()
End If
((FileQueryConnection)this.DataConnections["Locations"]).Execute();
foreach (XPathNavigator navigator2 in
this.DataSources["Locations"].CreateNavigator().SelectSingleNode("//rs:
data", this.NamespaceManager).Select("//z:row", this.NamespaceManager))
{
this.AddMultiSelectReasons(navigator2);
}
if
(this.GetCurrentXPathNav("/my:myFields/my:MultiSelectOptions[1]") !=
null)
{
this.GetCurrentXPathNav("/my:myFields/my:MultiSelectOptions[1]").Delete
Self();
}
}
catch (Exception exception)
{
}
}
VB
Private Sub LoadMultiSelectListBox()
Try
Me.Errors.DeleteAll()
DirectCast(Me.DataConnections("Locations"),
FileQueryConnection).Execute()
For Each navigator2 As XPathNavigator In
Me.DataSources("Locations").CreateNavigator().SelectSingleNode("//rs:da
ta", Me.NamespaceManager).[Select]("//z:row", Me.NamespaceManager)
Me.AddMultiSelectReasons(navigator2)
Next
If
Me.GetCurrentXPathNav("/my:myFields/my:MultiSelectOptions[1]") IsNot
Nothing Then
Me.GetCurrentXPathNav("/my:myFields/my:MultiSelectOptions[1]").D
eleteSelf()
End If
Catch exception As Exception
End Try
End Sub
NOTE:
Substitute /my:myFields/my:MultiSelectOptions with the XPath of the
MultiSelectedOptions on your document.
Substitute the “Locations” for the name of your data connection
navigator3.SetValue(item.GetAttribute("ows_LinkTitle",
string.Empty));
currentXPathNav.InsertAfter(newSibling);
newSibling = null;
}
catch (Exception exception)
{
}
}
VB
Private Sub AddMultiSelectReasons(item As XPathNavigator)
Try
Me.Errors.DeleteAll()
Dim currentXPathNav As XPathNavigator =
Me.GetCurrentXPathNav("/my:myFields/my:MultiSelectOptions")
Dim newSibling As XPathNavigator = Nothing
If currentXPathNav IsNot Nothing Then
newSibling = currentXPathNav.Clone()
End If
Dim navigator3 As XPathNavigator =
newSibling.SelectSingleNode("/my:myFields/my:MultiSelectOptions/my:opti
onDescription", Me.NamespaceManager)
navigator3.SetValue(item.GetAttribute("ows_LinkTitle",
String.Empty))
currentXPathNav.InsertAfter(newSibling)
newSibling = Nothing
VB
Public Function GetCurrentXPathNav(XPath As String) As
XPathNavigator
Return
Me.MainDataSource.CreateNavigator().SelectSingleNode(XPath,
Me.NamespaceManager)
End Function
10. To test the code, click the debug run button in Visual Studio.
Neat trick to get the correct XPath:
1. In the data source, right-click on the item and select Copy XPath.
1. Create an element off the root item to store the values. In my example, I will be calling it
selectedItems:
VB
EventManager.XmlEvents("/my:myFields/my:MultiSelectOptions/my:selectedO
ption").Changed += New XmlChangedEventHandler(selectedOption_Changed)
VB
Public Sub selectedOption_Changed(sender As Object, e As XmlEventArgs)
SaveMultiSelectListItems()
End Sub
builder.Append(iterator.Current.SelectSingleNode("my:optionDescription"
, this.NamespaceManager).Value);
}
else
{
builder.Append("; " +
iterator.Current.SelectSingleNode("my:optionDescription",
this.NamespaceManager).Value);
}
num++;
}
str = string.Empty;
}
this.GetCurrentXPathNav("/my:myFields/my:selectedItems").SetValue(build
er.ToString());
}
catch (Exception exception)
{
}
}
VB
Private Sub SaveMultiSelectListItems()
Try
Me.Errors.DeleteAll()
Dim iterator As XPathNodeIterator =
Me.MainDataSource.CreateNavigator().[Select]("/my:myFields/my:Mul
tiSelectOptions", Me.NamespaceManager)
Dim str As String = String.Empty
Dim builder As New
System.Text.StringBuilder(String.Empty)
Dim num As Integer = 0
While iterator.MoveNext()
If
Boolean.Parse(iterator.Current.SelectSingleNode("my:selectedOptio
n", Me.NamespaceManager).Value) Then
If num = 0 Then
builder.Append(iterator.Current.SelectSingleNode("my:option
Description", Me.NamespaceManager).Value)
Else
builder.Append("; " +
iterator.Current.SelectSingleNode("my:optionDescription",
Me.NamespaceManager).Value)
End If
num += 1
End If
str = String.Empty
End While
Me.GetCurrentXPathNav("/my:myFields/my:selectedItems").SetV
alue(builder.ToString())
6. Once the template is uploaded, hover over the file until you see the drop-down
7. From the drop-down, select Activate to a Site Collection
8. In the Activation Location, select the site and click OK after the site has been selected.
Step 6: Implementing the form on a SharePoint form library
1. Select the form library to use this form. In our example, the form library will be called Inventory.
2. From the form library, select Settings - Form Library Settings
3. Under General Settings, select Advanced Settings
,
4. For the Content Types field, select Yes for Allow management of content types and click OK.
Before clicking OK, you may want to set Browser-enabled Documents, select Display as a Web
page.
5. Under the Content Types section, select Add from existing site types
6. From the Available Site Content Types, select your new type and click Add. Then click OK
7. Under Content Types, select Change new button order and default content type
8. For the Form type, uncheck the Visible button and click OK
VOILA!!!
APPENDIX
(Source: http://www.synergyonline.com/blog/blog-moss/Lists/Posts/Post.aspx?ID=24)
9/18/2008
Ever since v1 of SharePoint Team Services, Microsoft has used OWSSVR.DLL to remotely invoke
functions against SharePoint. With the incorporation of Web Services in v2, this need is partly
deprecated and even more so in v3. Nonetheless, OWSSVR.DLL is still around and still plays an
important role with external applications such as SharePoint Designer. It is part of FP-RPC (Front Page –
Remote Procedure Call) but should not be confused with Front Page extensions.
Knowing this nifty utility can provide you a number commands for your developer tool bag. Here are
http://WebApp/[site]/_vti_bin/owssvr.dll?Cmd=Display&List={ListGuid}&Query=*&XMLDATA=TRUE
2. Or, how about just returning all data for a SharePoint list, but based on a specific view from the list:
http://WebApp/[site]/_vti_bin/owssvr.dll?Cmd=Display&List={ListGuid}&View={ViewGuid}&XMLDATA=TR
UE
<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
xmlns:rs='urn:schemas-microsoft-com:rowset'
xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
</s:AttributeType>
</s:AttributeType>
</s:ElementType>
</s:Schema>
<rs:data>
</rs:data>
</xml>
Either of these two could be useful for consuming in an XML Web Part or from any external application
that can make HTTP requests and process XML output. This includes the browser using XMLHTTP
technology as covered in this article. The example covered in this blog discusses how to consume the
3. Aside from returning XML data, you can also get definition information. For example, you can return
the CAML-based definition of a list. This can be real handy at times, especially if you are creating your
own list definitions. You can create the list using the UI and then scrape its definition this way:
http://WebApp/[site]/_vti_bin/owssvr.dll?Cmd=ExportList&List={ListGuid}
4. How about getting the ONET.XML (site definition) that was used to create a web site:
http://WebApp/[site]/_vti_bin/owssvr.dll?Cmd=GetProjSchema
5. And, finally, I’m not sure how this is helpful, but you could return all of the field types registered into
SharePoint:
http://WebApp/[site]/_vti_bin/owssvr.dll?Cmd=GetProjSchema&SiteTemplate=fldtypes
As you can see, there are a number of practical and interesting ways of using this DLL. I’ve found it
useful for just extracting structure and content out of a SharePoint environment, and consuming this data
from within applications. There are a few more commands that you can also try, but I’ve chosen to not list
them here. You can learn more about it from this blog http://msdn.microsoft.com/en-
us/library/ms478653.aspx. This article isn’t dated, but I suspect much of it was pulled over from STS v2
With that, have fun and let me know what other uses you can find for the output!
Notes:
1. This command will respect your SharePoint security. So, any clients that call into it will need to be
authenticated by the defined provider and object specific permissions are in force.
2. Some of the querystring parameters, such as XMLDATA are case sensitive. If you follow the syntax
3. You may have noticed that in some places, you must supply a GUID. In case you didn’t know, you can
easily extract these using the SharePoint UI. For example, if you go to the settings page for any list
(_layouts/listedit.aspx), you can extract the List GUID from the querystring. If you edit the view for a list,