InfoPath Forms with Master Page Applied or Script Enabled
Say what you will about InfoPath. It’s a dead technology, it’s not getting any Microsoft love, it’s only for the wealthy (Forms Services is only available only in Enterprise -level CALs of SharePoint), it has no future. I’ve heard all of these and more. That said, it’s a pretty solid technology and works. We can bemoan it’s future, but we can also use it today to Get Good Stuff Done.
All that said, InfoPath browser-based forms don’t do everything one might need. I’ve written in the past about the way my friend Marcel Meth (@marcelmeth) and I worked together to use jQueryUI’s autocomplete function to augment InfoPath’s functionality in my post Using SPServices with jQueryUIās Autocomplete Function on InfoPath Forms in SharePoint.
I was trying to do this again in an Office365 tenant recently and ran into a roadblock. A similar method worked just fine when filling out a new form, but we also needed it to work with existing form data when we edited it.
By default, InfoPath browser-based forms open up in a “chrome-less” state. By that, I mean that they don’t use the master page so one doesn’t see any of the site branding or tools around the form on the screen. From a branding perspective, that can be annoying but tolerable. However, when one needs to add some additional script to the page, one needs that chrome. This should be something simple to implement, but lo, it is not.
I had an InfoPath form that worked great. One of the things I needed to work in it is a little bit of script which is similar to the one in my blog post above. In this case, the basic idea was to add some autocomplete functionality to a field on the form, choosing (in this case) from a list containing 19000 cities and towns. (Cities seems to be a pretty common use case; there are a lot of them and autocomplete works well.)
To implement the script in the form, I created a new aspx page and dropped an InfoPath Form Web Part on it to display the form. The InfoPath Form Web Part pointed to my InfoPath form and the appropriate Content Type and worked perfectly. I embedded a reference to the script I needed in a Content Editor Web Part (CEWP) and everything worked a charm. By adding a few well-placed links to that page on the site, it was easy to get there to create a new InfoPath item.
The problem came in when we wanted to edit an existing form. Because links to the form go to
_layouts/15/FormServer.aspx?XmlLocation=...
, I couldn’t get my script to run in the page. As I mentioned, the FormServer.aspx page doesn’t pick up the chrome or anything else from the master page, which was where I wanted to put the script references.
I found a great suggestion on StackOverflow to simply run some script in the master page which changes the destination of links to the FormServer.aspx page. The posts didn’t give all of the details on how to do it, but I whipped something up pretty quickly.
//Rewrite Form Links to Open in Custom Page $("a.ms-listlink[href*='/sites/Projects/Sales Orders']").each(function() { var formFileName = $(this).attr("href"); var formServerUrl = "/sites/Projects/SitePages/Manage%20Sales%20Orders.aspx"; $(this).bind("click", function(e) { e.preventDefault(); var destination = formServerUrl + "?XmlLocation=" + formFileName + "&Source=" + location.href; location.href = destination; }); });
The script worked, in that it rewired all of the existing links to the FormsServer.aspx page correctly, sending me to a link that looked something like this, which was basically what I wanted:
https://domain/sites/Projects/SitePages/Edit%20Sales%20Order.aspx?XmlLocation=/sites/Projects/Sales%20Orders/SO1.xml&Source=https://domain/sites/Projects/
Unfortunately, the InfoPath Web Part then showed the error below.
Error
There has been an error while loading the form.
Click Try again to attempt to load the form again. If this error persists, contact the support team for the Web site.Click Close to exit this message.
Hide error details
XmlLocation and XsnLocation have both been set to non-empty values. It is an error to set both to non-empty values. Set XsnLocation to open a new copy of the form template. Set XmlLocation to open the xml file corresponding to an existing InfoPath document.
There had to be some way to pass the XmlLocation to the InfoPath Web Part successfully.
The trick turned out to be pretty simple, but I don’t know if I ever would have gotten to it. Luckily I have friends in far away places. John Liu (@johnnliu) in Sydney, Australia saw my #SPHelp on Twitter which pointed to my query on the MSDN Forums. (John’s a newly awarded MVP, so congratulations to him! Well deserved.)
John’s suggestion seemed cryptic at first. (Hey, he was limited to 140 characters on Twitter.) I was passing in the XmlLocation, so why wasn’t it working?
After some thought (OK, a lot of thought), I decided to try something which seemed crazy. I created a new page and dropped an InfoPath Form Web Part on it, but I didn’t configure it at all. It looked like this on the page:
This seemed to be asking for trouble, right? Without configuring the Web Part, how would it work?
But I tried my URL with this page, and voila, it worked!
The issue with the first page was that it was configured to point to the XSN file for the InfoPath form. By omitting that configuration, the InfoPath Form Web Part was open to discussion about what to load.
As far as I know, this isn’t documented *anywhere* on the InterWebz. At least I couldn’t find it with my Bingling skillz.
Now I have two pages: New Sales Order.aspx which has the InfoPath Form Web Part configured as usual, and Edit Sales Order.aspx with the InfoPath Form Web Part not configured. Going to New Sales Order.aspx with no XsnLocation or XmlLocation on the query string loads the form to create a new item. Going to Edit Sales Order.aspx with the XmlLocation on the Query string opens an existing form for editing.
Everybody thinks they know the future of InfoPath… Last I checked the technology for time travel does not exist yet. Thanks for the post.
Incredibly helpful! Thank you Marc.
Thanks for the post, this seems to be the same issue i’m facing and would be grateful if you could explain your steps a little further for me.
The script you wrote that lives in the master page, does it have to be stored there or can i add a content editor web part to my form library and add the URL to the script?
Also ‘/sites/Projects/Sales Orders’ is that your library name? If not what do i need to put here?
and lastly the ‘edit sales order.aspx’ page, where / how do you link this page so it opens up when an InfoPath form is opened for editing?
Any advice would be appricated Marc.
Great post, but unfortunately the InfoPath Viewer Web Part seems to prevent users from using Rich Text Boxes on the form because it needs a ribbon: “Your browser does not support the InfoPath Rich Text Edit control. To permanently remove all rich text formatting and edit the content of this control in plain text format, click OK.”
Thank you Marc, you are a lifesaver.
I didn’t fully understand your jquery. I also had a slightly different problem, as I needed that if someone would figure out the form page’s url, they would not be able to view it. I did it by creating that empty infopath-form sharepoint page. I then added into the actual formserver.aspx page the following javascript that redirected it. (I need to redo it in aspx, but for now this works):
if (window.location.href.indexOf(“xxxxxxx”) > -1)
{ var formname = location.href.substring(location.href.indexOf(“xxxxxxx”));
formname= formname.substring(0, formname.indexOf(“.xml”));
window.location.replace(“/Pages/theblankformpage.aspx?XmlLocation=/”+formname+”.xml”);
}
Thank you, that is a great solution. However, the custom InfoPath Web Part form does not close automatically on submit. Is there a workaround for that?
Adding the library reference to the InfoPath web part, setting the form to close automatically, and then removing the library reference from the web part fixed the problem! If you are using multiple action submit you may have to change that to single action submit in order to be able to customize your InfoPath web part.
Thank you Marc. That was really helpful.