Microsoft InfoPath 2010
The official blog of the Microsoft InfoPath team

August, 2004

  • Microsoft InfoPath 2010

    Problems downloading/installing the InfoPath SDK?

    • 1 Comments

    We're getting reports from some users who are having problems installing the InfoPath SDK. The problem appears to be caused by intermittent network traffic issues causing downloads to fail part-way through. You'll end up with a file that appeared to download but is missing some or most of the data. Restarting the download sometimes accesses the incomplete cached version, which doesn't improve the situation.

    The file size of InfoPathSDK.msi downloaded from http://www.microsoft.com/downloads/details.aspx?FamilyId=351F0616-93AA-4FE8-9238-D702F1BFBAB4&displaylang=en should be 4.34 MB (4,552,192 bytes). If you end up with a smaller file it's been truncated due to network problems, and the install will fail. Clear your browser cache (in IE: Tools | Internet Options, Delete Files...) and try the download again.

     

  • Microsoft InfoPath 2010

    Example script for showing Mail Envelope based on User’s Role

    • 1 Comments

    The option to “Submit as Email” doesn’t include the form in the body of the mail, so here’s another way to encourage your form-fillers to send their forms as email and include that body.

    This script could be used in a Blogger form to turn on the Mail Envelope when the user switches to the “Email” view. That event could be triggered by the form-filler using the View menu, or even by a Rule on a button. It also makes some decisions based on the user’s current role so you can see how to do that.

     

    function XDocument::OnSwitchView(eventObj) {

      var mail = XDocument.View.Window.MailEnvelope;

     

      if (XDocument.View.Name == "Email") {

        // get nodes from DOM

        var blog = XDocument.DOM.selectSingleNode("/dfs:myFields/dfs:dataFields/d:blog");

       

        var id       = blog.selectSingleNode("@ID");

        var title    = blog.selectSingleNode("@Title");

        var blogger  = blog.selectSingleNode("@BloggerName");

        var replies  = blog.selectNodes("d:reply/@ReplyName");

     

        // Set To field to include blog and the original blogger

        mail.To = "blog; " + blogger.text;

     

        // Set CC field to include all the replies (minus the current one)

        if (replies != null) {

          var cc = "";

          for (var i = 0; i < replies.length - 1; i++) {

            cc += replies(i).text + "; ";

          }

          mail.CC = cc;

        }

     

        // Set subject to look like a thread

        var subject = "Blog " + id.text + " - " + title.text;

        if (XDocument.Role != "Create")

          subject = "RE: " + subject;

        mail.Subject = subject;

     

        // Show the mail envelope

        mail.Visible = true;

      }

      else {

          mail.Visible = false;

      }

     

     

  • Microsoft InfoPath 2010

    ActiveX Controls in InfoPath 2003 - in Visual Basic 6.0

    • 1 Comments

    Andrew Ma, a tester on the InfoPath team, has created a Visual Basic 6.0 version of the InfoPath Hands-On Lab for creating custom controls. You can find it here on Andrew's blog:

    http://blogs.msdn.com/ajma/articles/213868.aspx

     

  • Microsoft InfoPath 2010

    The Microsoft Office InfoPath 2003 SDK has been updated for SP1!

    • 2 Comments

    The Microsoft Office InfoPath 2003 Software Development Kit (SDK) contains sample forms, tools, macros, code libraries, and documentation to assist with InfoPath form development in both InfoPath 2003 and InfoPath 2003 SP1.

    Here’s what’s new in the updated SDK

    • New tool: Using the InfoPath to Word Wizard
    • New code library: Build a Custom BizTalk 2004 Pipeline Component
    • New code library: Build a Custom Importer
    • New code library: Using a Custom Script Library for Common Tasks
    • Macros to assist in Visual Studio Development
    • Ability to create installers in multiple languages with the RegForm tool
    • Other improvements and updates to the existing tools
    • 6 new common developer tasks
    • Many SP1 updates to existing content and tools
    • Updated InfoPath Developer’s Reference

    Download the SDK today!  Go to http://www.microsoft.com/office/infopath and look in the Downloads section at the bottom of the page.

  • Microsoft InfoPath 2010

    Are you an InfoPath whiz?

    • 1 Comments

    When it comes to InfoPath, will you squeak by with a passing grade or graduate at the very top of your class? Take a short quiz on Office Online and find out exactly where you stand.

    http://office.microsoft.com/assistance/quiz.aspx?AssetID=QZ010971581033

    If that was too simple, here's the next question for you InfoPath whizzes out there: What questions would you ask to find out if someone knows InfoPath inside and out?

  • Microsoft InfoPath 2010

    Implementing Change Tracking for InfoPath Forms

    • 1 Comments

    Although InfoPath doesn't have a Change Tracking feature built-in like Word and some of the other Office System applications, read on for guidance on how to implement it in your own solutions.

    There are several problems to decide before jumping into implementation: where do you want to store change tracking information, how do you map between list of changes and elements, tracking information protection, and what format you use to store change tracking information.

    Storage options

    Depending on schema of XML there are several options:

    1.  Closed schema - public or required by third party.
      1. "Envelope" approach - you can store whole document as XML sub tree inside your own XML with open schema.
      2. Using Processing Instructions to store data is possible when the schema allows it and consumers of XML can handle processing instructions correctly. Note that even if one suppose to ignore them it is not always the case.
      3. Separate file. Just keep tracking information somewhere (I.e. local file or remote Web service). This approach is remotely reasonable if you know how to associate data with tracking information.
    2. Open schema
      • Store tracking information as single attribute.
      • Store tracking information as sub-tree of each element that is interesting for change tracking
      • Store tracking information in single node providing some mapping between elements you are interested in and tracking information.

    Format options

     1. XML friendly.

    If you want your tracking information to be processed using some form of normal XML handling (XSL, XML readers, XPath navigation) then you should use XML sub-trees to store change tracking information.

    For example:

     <changes>
      <change forElement="element1233" date="2004-06-12" author="john" type="textChange">New text</change>
      <change forElement="element1233" date="2004-06-14" author="fred" type="textChange">Don't writen new text!</change>
     </changes>

     2. Custom text format

     If you can't use normal XML for some reasons (i.e. storage options 1.b, 2.a) then you can develop text format to store the data. You can use approach close to XML (i.e. just store sub-tree as string) or even go with Base64 encoded binary.

    Mapping between element and tracking information

     1. Direct access.

     If you can put tracing information right into element you are interested in then you don't need any mapping.

     Note that this approach requires you to think through deletion scenario because the element itself might be deleted along with it's tracking information.

     2. Element ID. 

    This is an easy option to implement if you have or can establish persistent unique element identifiers for each element you want to track changes. It could be attribute on elements or some combination of attributes and values of element.

    Note that you can not use XPath to element as unique id if you have any repeating content you want to track changes on.

    The problem here is that you need to have good ID and should think through insertion of elements.

    3. Position based mapping.

    This is the most complex option to implement. If you can't have any identifiers for element you had to go with position based mapping. I.e. 

    <change forElement="/root/items[0]/item[4]/component[3]" date="2004-06-12" author="john" type="textChange">New text</change>

    where forElement contains the XPath to the element of interest.

    The main problem here is that you have to dynamically update all mappings on element insertions through the tree.

    Change tracking information protection

    You should consider if and how you want to protect this data. Approaches would vary from digitally signing each change (or editing session) to "who cares if it is changed?"

    Coding ideas for simplest case

    You have unique element IDs that somehow get generated for elements. You are interested in recording changes in text value of an element.

    Here is sample of XML you want to record changes for:

    <root>
     <items>
      <item id = "12"><textToTrack>text</textToTrack></item>
      <item id = "23"><textToTrack>text</textToTrack></item>
      <item id = "55"><textToTrack>text</textToTrack></item>
     </items>
    </root>

    The approach choosen to store the data: separate from the data as subtree of the <root> node, and no protection and tamper detection for tracking information.

    Here is example of XML with tracking information.

    <root>
     <changes>
      <change forElement="12" date="2004-06-12" author="john" type="textChange" ><old>text</old><new>Shining new text</new></change>
      <change forElement="12" date="2004-06-14" author="fred" type="textChange" ><old>Shining new text</old><new>Don't write new text!</new></change>
      <change forElement="23" date="2004-06-14" author="fred" type="delete"></change>
     </changes>
     <items>
      <item id="12"><textToTrack>Don't write new text!</textToTrack></item>
      <item id="55"><textToTrack>text</textToTrack></item>
     </items>
    </root>

    To code this in InfoPath you need:

    Make sure schema allows <changes> to be inserted. I.e. In designer for new solution create this structure in the Data Source task pane.

    Figure out how to get user name if needed.

    Add an "OnAfterChange" listener for <items> node, and implement the following pseudo-code:

     IF change = "add" AND node-name = "item"
      make sure ID is generated for "add"
      record (ID, added) information.
     IF change = "remove" AND node-name = "item"
      record  (ID, deleted)
     IF (change = "add OR change = "remove" OR change = "change") AND node-name = "textToTrack"
      record (ID, textChange, oldValue, newValue)
      

    Where ID is "id" attribute of corresponding "item" node, and record means append all needed information a <changes> collection. Record function should also take care of merging change information for the same date/user like if node was added in this session all changes should be combined into "added" record, rather then creating multiple "changed" sections.

    Note that "undo" user actions will rollback change as well as tracking information. If you store data in separate file you should take care of undo yourself.

     

  • Microsoft InfoPath 2010

    Conditional Presence versus Conditional Visibility

    • 2 Comments

    InfoPath supports a feature called Conditional Formatting which allows among other things to show or hide sections of the form based on some condition.

     

    However, the underlying XML data still stays there even though it is not visible in the view. What if one wants to remove the XML data altogether? It is easy to achieve this by writing a little bit of code.

     

    First of all, a trick: an optional leaf field can be wrapped in an Optional Section without adding any additional nodes in the Data Source. Suppose that your data source looks like that:

     

          myFields

                  field1

     

    Instead of dragging field1 into the view (which will produce a Text Box, assuming its datatype is a string), right-click on it, select More… and pick Optional Section with Controls.

     

    Now the Text Box is wrapped in an Optional Section and you can remove or insert it as desired.

     

    At this time, suppose that you want field1 appear conditionally based on a state of a Check Box bound to some node (let’s call it field2). Attach an “OnAfterChange” event to it with the following code:

     

    function msoxd_my_field2::OnAfterChange(eventObj)

    {

          if (eventObj.IsUndoRedo || eventObj.Operation != "Insert")

          {

                return;

          }

     

          if (eventObj.NewValue == "true")

          {

                XDocument.View.ExecuteAction("xOptional::insert", "field1_1");

          }

          else

          {

                XDocument.View.SelectNodes(XDocument.DOM.selectSingleNode("/my:myFields/my:field1"));

                XDocument.View.ExecuteAction("xOptional::remove", "field1_1");

          }

    }

     

    Here, we use the xOptional::insert command to insert field1 (and hence the Optional Section) when the Check Box is checked, and xOptional::remove to remove it when the Check Box is unchecked.

     

    A few comments on the code above:

    • The “field1_1” string is the xmlToEdit name associated with the section. To find out what this name is for your section, look at the “Advanced” tab of the Optional Section properties.
    •  When executing actions, InfoPath is using the current XML context to determine how to perform the action. Clicking on the checkbox moves the XML context to field2 in our example. While InfoPath can still handle the insertion properly, it cannot figure out what section to delete. In order for xOptional::remove to succeed, we use SelectNodes() method on the view to set the xml context to the section we are trying to remove.
    • Finally, to prevent the user from inserting or deleting the Optional Section by other means than using the Check Box, bring up the properties of the Optional Section, click “Customize Commands” and uncheck everything under “Insert” and “Remove” actions. Also uncheck the “Show insert button and hint text”.

    P.S. The conditional presence technique is especially useful in scenarios where the schema contains optional elements that are not allowed to be blank (which could be a desirable design in some scenarios where the XML-consuming backend cannot handle xsi:nils).

     

    P.P.S. The technique of calling View.SelectNodes() can solve the ExecuteAction() focus/context problem. The ExecuteAction() documentation states that sometimes calling ExecuteAction() from button’s onClick can fail. Calling View.SelectNodes() from onClick shold remedy to this problem.

Page 1 of 1 (7 items)