Use dynamically created InfoPath form instance to pre-fill form

If you want to pre-fill InfoPath form before user gets his/her hands to it... you have two ways to do that:

  1. Call Web Services from InfoPath
    • It normally takes quite long
  2. Dynamically create InfoPath form instance
    • Fast and there isn't any limitations where to get data

Both methods have been mentioned many times in different sites but I still decided to create a demo about the "Dynamically create InfoPath form instance"to make this crystal clear... and give some code to get you started on this if you're interested.

So I created really simple InfoPath Request Form:

I added submit rule to the button (I just used fixed url for the form library).

Then I created following UI for my solution:

Here is the code behind the astonishing UI (a.k.a. button inside web part):

 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
 using System;using System.Runtime.InteropServices;using System.Web.UI;using System.Web.UI.WebControls.WebParts;using Microsoft.SharePoint;using System.Web.UI.WebControls;namespace InfoPath_Creator{  [Guid("16ba4e60-d230-45d3-9966-da959d20a90b")]  public class InfoPath_Creator : System.Web.UI.WebControls.WebParts.WebPart  {    public InfoPath_Creator()    {      this.ExportMode = WebPartExportMode.All;    }    protected override void CreateChildControls()    {      Controls.Clear();      base.CreateChildControls();      this.ChildControlsCreated = true;      Button createRequestForm = new Button();      createRequestForm.Text = "Create request";      string url = this.Page.Request.Url.ToString();      if (url.IndexOf('?') == -1)      {        url += "?";      }      else      {        url += "&";      }      url += "CreateRequest=true";      createRequestForm.OnClientClick = "document.location.href='" + url + "'; return false;";      this.Controls.Add(createRequestForm);    }    protected override void Render(HtmlTextWriter writer)    {      this.RenderChildren(writer);      if (string.IsNullOrEmpty(this.Page.Request["CreateRequest"]) == false)      {        string requestType = "Request for dynamic request forms";        string requestTitle = "My dynamically created request";        string estimatedCost = "123";        string user = SPContext.Current.Web.CurrentUser.Name;        string costCenter = "999888777"; // TODO: get cost center from UserProfile        int classification = 54321;        string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +          "<?mso-infoPathSolution solutionVersion=\"1.0.0.8\" productVersion=\"12.0.0\" " +           "PIVersion=\"1.0.0.0\" href=\"" +           "https://demo1:1000/PressReleases/Request%20forms/Forms/template.xsn\" " +          "name=\"urn:schemas-microsoft-com:office:infopath:" +          "Request-forms:-myXSD-2007-11-07T19-32-12\" ?>" +          "<?mso-application progid=\"InfoPath.Document\" " +          "versionProgid=\"InfoPath.Document.2\"?>" +           "<my:myFields xmlns:my=\"" +          "https://schemas.microsoft.com/office/infopath/2003/myXSD/2007-11-07T19:32:12\" " +          "xml:lang=\"en-us\">" +          // Here I fill the fields:          "<my:RequestType>" + requestType + "</my:RequestType>" +          "<my:RequestTitle>" + requestTitle + "</my:RequestTitle>" +          "<my:EstimatedCost>" + estimatedCost + "</my:EstimatedCost>" +           "<my:User>" + user+ "</my:User>" +           "<my:CostCenter>" + costCenter + "</my:CostCenter>" +           "<my:Classification xmlns:xsi=\"https://www.w3.org/2001/XMLSchema-instance\">" +           classification + "</my:Classification>" +          "</my:myFields>";        this.Page.Response.Clear();        this.Page.Response.AppendHeader("Content-Disposition", "attachment;filename=Request-" +           DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") );        this.Page.Response.ContentType = "application/ms-infopath.xml";        this.Page.Response.Write(xml);        this.Page.Response.Flush();        this.Page.Response.End();      }    }  }}

In lines 54 to 73 I created the XML for the form (it looks like real mess and I'm sorry about it!). Most important stuff happens between lines 66 and 72 where the actual field values are stored. Of course you could use some magic code to get the correct values to the variable at lines 47 - 52. And you can also probably see the URL of the XSN file (line 57) and as well as the namespace (line 63). It looks like this when user clicks the Create request button:

And when user presses the button in InfoPath the form data is submitted to the form library:

So hopefully after this post you'll remember that this method is powerful (and not the messy XML :-) if you want fill InfoPath with data. You have much more possibilities than just simple web service request in InfoPath.

By the way... Why do I always end up with titles with word "dynamic*" in it :-) (see my previous post for example)

Anyways... Happy hacking!

J