Udostępnij za pośrednictwem


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

Comments

  • Anonymous
    November 07, 2007
    Nice post.. but in a real world you probably want to publish the infopath form to MOSS more than once. With each publish the timestamp in the namespace changes, doesn't it? So, is there a nice way to retreive the new namespace, other than blowing up the xsn-file and start digging? It would be cleaner to retrieve an empty form from Forms Services with correct namespace and everything. But how can I do that in code?

  • Anonymous
    November 07, 2007
    Hi Jari! If you do it the correct way => don't start from InfoPath :-) Then you actually define your namespace yourself. The problem is that people normally start by launching InfoPath... and don't think about the schema. But you should first create schema and then start building your form on top of it. Then your namespace stays as you have defined. Anyways... Happy hacking! J

  • Anonymous
    November 07, 2007
    Hmm.. you're right. My form is imported from excel, so the schema is a bit reverse engineered.. But now when I have version 1.0 ready I can get the schema out, fix the namepace and continue from there. Cheers!

  • Anonymous
    November 08, 2007
    Holy Cow dude :) Do you ever sleep ? what ever pills you are taking, i want those too :)) :)

  • Anonymous
    November 08, 2007
    Anpassung Liam Cleary MOSS2007 – Link Lists and the Content Query Web part Adding "OpenInNewWindow" option

  • Anonymous
    November 28, 2007
    The comment has been removed

  • Anonymous
    June 20, 2008
    I tried the about example with an aspx page. However, when I try running it, I get an error saying: The element '{http://schemas.microsoft.com/office/infopath/Test5/myXSD/2008-06-20T18:52:11}myFields' is used but not declared in the DTD/Schema. As you can see, I have changed the lines: 66, 72 , 47 - 52 and 57, 63. Can you advise, what is wrong, or can you kindly post your code for me to donwload.

  • Anonymous
    July 15, 2008
    The comment has been removed

  • Anonymous
    July 21, 2008
    Hi, Is it possible to fill submitted infopath form clicking on it and filling data and submit it? If Yes then How? Thanks in advance

  • Anonymous
    October 17, 2008
    Love your blogs. Can't print them out. The first Page comes out right The rest don't print. Any suggestions. thanks, Stephan