One of the main issues with hosting web enabled InfoPath forms is that of the branding. The form shows up as full screen page without the master page. Hence there is no navigation available for the end user to go to other parts of the site. In this writing I share a complete solution for InfoPath forms to display them inside a master page.
Here is how a form looks like without a master page.
InfoPath form displayed in SharePoint site without master page |
Notice that SharePoint renders the form using an application page with a URL /_layouts/FormServer.aspx. This page is actually specified in a configuration xml file under the 12 or 14 hive (depending on your version of SharePoint) at \12\TEMPLATE\XML\serverfiles_FormServer.xml. The contents of the file look like the following:
<?xml version="1.0" encoding="utf-8"?>
<ServerFiles>
<Mapping FileExtension="xml" ProgId="InfoPath.Document" RedirectUrlTemplate="/_layouts/FormServer.aspx?XmlLocation=|0" />
<Mapping FileExtension="xml" ProgId="InfoPath.Document.2" RedirectUrlTemplate="/_layouts/FormServer.aspx?XmlLocation=|0" />
<Mapping FileExtension="xml" ProgId="InfoPath.Document.3" RedirectUrlTemplate="/_layouts/FormServer.aspx?XmlLocation=|0" />
<Mapping FileExtension="xml" ProgId="InfoPath.Document.4" RedirectUrlTemplate="/_layouts/FormServer.aspx?XmlLocation=|0" />
<Mapping FileExtension="xsn" RedirectUrlTemplate="/_layouts/FormServer.aspx?XsnLocation=|0" />
</ServerFiles>
We can easily change this file to set the RedirectUrlTemplate to a custom page within our site but it is not the recommended way. Any service updates will overwrite the file and functionality will be lost. The trick here is to create another file with a name which is similar to the existing name but comes after the original file name when alphabetically sorted in ascending orde.
One such name would be serverfiles_FormServerCustom.xml
The SharePoint platform seems to register these files in alphabetical order. So by placing a different mapping in our custom file, it is possible to overwrite the settings without breaking SharePoint. Here is what the file content of out custom file will look like.
<?xml version="1.0" encoding="utf-8"?>
<ServerFiles>
<Mapping FileExtension="xml" ProgId="InfoPath.Document" RedirectUrlTemplate="/Pages/EditForm.aspx?XmlLocation=|0" />
<Mapping FileExtension="xml" ProgId="InfoPath.Document.2" RedirectUrlTemplate="/Pages/EditForm.aspx?XmlLocation=|0" />
<Mapping FileExtension="xml" ProgId="InfoPath.Document.3" RedirectUrlTemplate="/Pages/EditForm.aspx?XmlLocation=|0" />
<Mapping FileExtension="xml" ProgId="InfoPath.Document.4" RedirectUrlTemplate="/Pages/EditForm.aspx?XmlLocation=|0" />
<Mapping FileExtension="xsn" RedirectUrlTemplate="/Pages/NewForm.aspx?XsnLocation=|0" />
</ServerFiles>
It would be very obvious now that I plan to create two pages in the Pages library, which are NewForm.aspx and EditForm.aspx. Both of them would be web part pages. In my case I like to user the “Blank Web Part Page”. On the NewForm page add a Page Viewer Web Part. In the Page Viewer Web Part’s properties, set the property called “Link” as follows:
/_layouts/FormServer.aspx?OpenIn=browser&XsnLocation=/FormServerTemplates/MyInfoPathForm.xsn
Make sure the XsnLocation is the location where you have published the form. You may also want to adjust the height or the width. Once you save and publish the NewForm.aspx page, it would display your InfoPath form. And yes, it would have your master page.
The EditForm page requires a bit of coding. Basically the idea is the same as the NewForm to host a web part which will accept XmlLocation parameter and display the contents from this URL. In this case the URL (XmlLocation) is going to be dynamic because the form is already saved and all saved forms will have different URLs. So we need a dynamic way to set the “Link” property of the Page Viewer Web Part. The quick and easy way is to wrap the PageViewerWebPart class in a custom web part. I present the minimal code for your interest. The main code is in the CreateChildControls method.
private PageViewerWebPart pageViewer;
[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[System.ComponentModel.Category("Custom Properties")]
[WebDisplayName("Form Page Url")]
[WebDescription("Url of edit form page")]
public string PageUrl
{
get
{
if (_pageUrl == null)
{
_pageUrl = "/_layouts/FormServer.aspx";
}
return _pageUrl;
}
set { _pageUrl = value; }
}
protected override void CreateChildControls()
{
if (!_error)
{
try
{
base.CreateChildControls();
// Your code here...
String contentLink = PageUrl + "?";
String queryData = Context.Request.Url.ToString().Split(new char[] {'?'}, StringSplitOptions.RemoveEmptyEntries)[1];
pageViewer = new PageViewerWebPart();
pageViewer.ContentLink = contentLink + queryData;
pageViewer.ChromeType = this.ChromeType;
pageViewer.ChromeState = this.ChromeState;
pageViewer.Width = this.Width;
pageViewer.Height = this.Height;
pageViewer.Hidden = this.Hidden;
pageViewer.Title = this.Title;
this.Controls.Add(this.pageViewer);
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
Once webpart is deployed to the SharePoint server, add it to the Editform page. Set all the properties of this web part as you had set the properties on the Page Viewer Web Part. Once you save the page and publish it, the web part would be able to open the InfoPath forms in edit mode.
Make sure you deploy the serverfiles_FormServerCustom.xml to the \12\Template\XML folder.
Make sure you deploy the serverfiles_FormServerCustom.xml to the \12\Template\XML folder.
InfoPath forms (edit and new) displayed within master page. |
Now if you go to any of the saved forms, and click on the link, they will open up in a page with master page.
No comments:
Post a Comment