Band-Aided
Since my last post I've been working on the same application while we also do requirements gathering for a Sharepoint v3 project which has to be in production no later than 1/30/2007 (that's a huge chunk to chew). This forms application, however, was supposed to get demo'd as a proof of concept at the end of May... last week that got moved up to Wednesday and I basically have spent my days swearing at my box, biting my nails off and otherwise cursing myself for ever being a “pioneer” and developing any proof of concept of a beta platform. My biggest problem revolved around the XmlFormViewer for web based InfoPath forms. I'm still not sure about this control and its usefulness but I have it working nonetheless.
The XmlFormViewer requires that the ASPX page hosting the control run either in the root Sharepoint site collection or installed as a “feature.” I never did figure out how to install the ASPX page as a feature and have it be usable and no one I've spoken to seems to really understand how to use it that way. I could get the ASPX page to run and fire the OnSubmit event if I had it in the root but, then, I had no control over the page in order to retrieve the OnSubmit data (xml return from the InfoPath form). I tried a bazillion different things.... at one point I completely shot my Sharepoint installation and had to completely reformat my box in order to get things back to normal.
Basically, I have an ASP.NET application that allows my users to select one or more documents to generate. The documents all have user interface requirements which I'd like to use InfoPath forms for. I'm using the Office 12 file formats to push the data into the document (both from LOB datasources and the return from the InfoPath forms). The application needs to be able to display one or more InfoPath forms so I need control over the actual XmlFormViewer, changing the XsnLocation and reloading the page after every submit. In the end, I've stubbed together the application by storing all my session information in SQL tables. I've kept the ASPX page with the XmlFormViewer in the root site collection, it pokes the SQL table and then pushes the return data into the same place. It then calls a separate ASPX page that goes into the SQL table, figures out if another template is waiting to be generated, and if so, calls the XmlFormViewer ASPX page again. We do this until we have processed all templates and then generate the documents pulling out the document part, tearing about the document.xml and then putting it all back together again.
Lastly, my users are left with a list of documents they can, supposedly, open as a link from IE; however, that part still isn't working and I understand it is an actual beta issue rather than my coding (thankfully).
Some tidbits I've discovered during this process:
-- You can retrieve a customXml node out of document.xml using xPath and the tag "w:customXml" by using something like the following code snippet. Note that in the new file formats, each child node is it's own entity. Whereas in 2003 you might have MyNode/MyChildNode you would now have two separate //w:customXml nodes with MyChildNode being a child of MyNode.
XmlNodeList thislist = masterDoc.DocumentElement.SelectNodes("//w:customXml[@w:element=\"MyXmlElementName\"]", _nsMgr);
-- If you are editing document.xml (you'll have to first get the document part, using my earlier code block should help you get that), you must push it back into your document:
//reassert the output as a create object
outputStream = documentPart.GetStream(FileMode.Create, FileAccess.ReadWrite);
//write the new XML with the node values into the document part
StreamWriter ts = new StreamWriter(outputStream);
ts.Write(masterDoc.InnerXml);
ts.Flush();
ts.Close();
-- You can change the values in document.xml for things like checkboxes and use the compatibility pack for earlier versions of office and have full fidelity (the same is not true for things like content controls and other 2007 based features).
-- Treating the document.xml as a string is faster than replacing text within bookmarks for example (i.e., mydocumentxml.replace("mytext", "myreplacetext").
-- To get your XML data out of the return from the XmlFormViewer, you'll need to do this:
XPathNavigator _xNavMain = FormsViewer.XmlForm.MainDataSource.CreateNavigator();
string myXML = _xNavMain.InnerXml;
After much playing around with the XmlFormViewer, you can take away everything but, apparently the powered by bar which fortunately is blue and matches my color scheme... if I had gone with a red color scheme, that bar would stick out like a sore thumb. I also can't figure out how to apply a css style to a button but that's the least of my concerns. On Beta1TR, the "title" of the InfoPath form doesn't display for some reason so I've dummied the title by making it appear in the body of the form. This control will be a huge benefit to people who deal with automation on this level (if it works in some semblance of a manner that is useful) because the editing and creation of InfoPath forms is much, much more accessible and easy than designing ASPX pages for the same purpose.
