Microsoft InfoPath 2010
The official blog of the Microsoft InfoPath team

  • Microsoft InfoPath 2010

    Transforming InfoPath Rich Text to Word

    • 3 Comments

    This article applies to InfoPath 2003 and Word 2003.

    Summary

    InfoPath is great for capturing structured data. A common scenario is that you need to output that data in a Word document. It is quite easy to create an XSLT transformation that will take the XML generated by InfoPath as input and generate WordprocessingML tags. For example, to output the value of the EmployeeName form field in a word document’s paragraph you would use the following XSLT fragment:


    <w:p><w:r><w:t>
         <xsl:value-of select=”my:EmployeeName”/>
    </w:t></w:r></w:p>

    Most mappings will be quite similar, in that they end up in a <w:t> tag, which Word uses to contain, well euh… text. There is one exception to this, namely when you use rich text fields in your form. A rich text field can contain formatted text, images, hyperlinks, tables, etcetera and although the XHTML format that is used to represent the contents is similar to WordprocessingML, there are important differences. This article provides a reusable solution for dealing with those differences.

    Downloads: XSLT transformation source code and sample input files are all bundled in the attached archive.

    Details

    To illustrate the capabilities of a rich text field I created the form below, which contains a single rich text field. I created an instance of it with some sample formatted content:

    The contents of the field itself is structured using the XHTML standard, that looks like this:

    ...
    <div xmlns="http://www.w3.org/1999/xhtml">This is an example of a rich text control that contains various formatted elements such as <strong>bold </strong>and <em>italic </em>text, aligned text with <font color="#0000ff">foreground </font>and <font style="BACKGROUND-COLOR: #3366ff">background </font>colors, <font style="BACKGROUND-COLOR: #ffff00"><strong>bulleted</strong></font> and <font style="BACKGROUND-COLOR: #0000ff" color="#ffff00">numbered </font>lists, a table and an image.</div>
    ...

    Should you try to insert this as such in a <w:t> tag, you would end up with an invalid Word document. You have to take each individual XHTML tag and transform it to its WordprocessingML counterpart. For some tags (strong, font, …) this is quite straightforward, but for others this can be quite a challenge.

    What you will find in the download accompanying this article, is an XSLT template that you can include as is in your own XSLT stylesheets and that will result in a visually equivalent word document. The result of transforming the above form to word using this template looks like this:

    Beware that this is a work in progress. The template is suitable for most basic formatting (things you hand-type in the form), but will most probably fail when you cut/paste content from the web with heavily nested table formatting. If you have that requirement, you’ll have to resort to coding techniques rather than transformation.

    The input files

    The download contains a number of xml documents generated with Infopath. To test these with the transformation, right-click the file and choose Open With… Word. In the XML task pane, browse to the “BASIC IP_To_Word.xslt” to transform.

    The transformation file

    The first part of the “BASIC IP_To_Word.xslt” file is simply a blank word document saved as xml and then turned into a stylesheet. This can be done in a few easy steps:

    1. Wrap the entire document in <xsl:stylesheet version=”1.0”> tags
    2. Remove the <?mso-application …> processing instruction
    3. Move all the namespace definitions in the wordDocument tag to the stylesheet tag
    4. Add the xsl namespace as xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”
    5. Add the namespace of the source xml file, for example: xmlns:ns0=”http://YourCompany/YourXMLRootNode”
    6. Move the closing </w:body> and <w:wordDocument> from the end to right after the <w:body> opening tag
    7. Wrap the <w:wordDocument> node in an <xsl:template match=”/”> node
    8. Right before the <w:wordDocument> node, add
      <xsl:processing-instruction name="mso-application">
      <xsl:text>progid="Word.Document"</xsl:text>
      </xsl:processing-instruction>
    9. In the <w:body> node, add <xsl:apply-templates select=”/ns0:YourXMLRootNode”/>
    10. Wrap the remainder of the body in a node <xsl:template match=”ns0:YourXMLRootNode”/>
    11. Add <xsl:value-of select=”ns0:YourNode”/> instructions where needed
    12. If you have repeating nodes, you can add these with an <xsl:for-each select=”...”> construct

    The interesting stuff is where the rich text field IPRT is passed to a template named “infopath rich text”. Everything below it can be copied to your own stylesheet. Then you can use the following construct to render any rich text field anywhere in the word document:

    <xsl:template match=”my:YourFieldHere”>
          <xsl:call-template name=”infopath-rich-text”/>
    </xsl:template>

    You can also add the following parameters to the call template instruction:

    pPr_Default: A list of paragraph formatting properties that need to be set on each paragraph transformed from the rich text

    rPr_Default: A list of character formatting properties that need to be applied on all the text (for example the default font)

    Stephane Bouillon
    Senior Consultant
    Microsoft Consulting Services

    Thanks goes to David Gerhardt for his articles.

  • Microsoft InfoPath 2010

    Do You Love Access? We do too!

    • 3 Comments

    And that's why there's all the new-and-cool documentation about how to make your InfoPath forms work well with Access:

    And a few bonus articles, also from our friends in the documentation team:

    Happy Friday!
    Alex

  • Microsoft InfoPath 2010

    InfoPath 2007 Training Labs

    • 3 Comments

    I’m pleased to announce that InfoPath 2007 training labs are now live on MSDN. Just like with the hands-on labs for InfoPath 2003, we created a set of exercises that walk you through a real-life scenario, introducing a new InfoPath feature in the process. Here are the new labs:

    Lab 1: Publishing an InfoPath 2007 Form Template to a Server Running InfoPath Forms Services
    Lab 2: Deploying and Managing InfoPath 2007 Forms
    Lab 3: Integrating InfoPath 2007 with the Data Connection Library
    Lab 4: Enabling Digital Signatures in InfoPath 2007 Form Templates
    Lab 5: Importing Word Forms into InfoPath 2007
    Lab 6: Using InfoPath 2007 E-mail Forms
    Lab 7: Restricting Permissions to InfoPath 2007 Forms and Form Templates
    Lab 8: Using the InfoPath 2007 Object Model and Visual Studio Tools for Applications
    Lab 9: Designing InfoPath 2007 Forms for Mobile Web Browsers
    Lab 10: Creating and Inserting InfoPath 2007 Template Parts
    Lab 11: Integrating InfoPath 2007 Forms in Web Sites Using Visual Studio
    Lab 12: Using SharePoint Server Workflows with InfoPath 2007

    Many InfoPath 2003 labs are still relevant - so if you need a refresher on fundamentals, here's the list:

    Lab 1: Editing forms and working with form data (Level 100)
    Lab 2: Creating forms and layout (Level 200)
    Lab 3: Form deployment (Level 200)
    Lab 4: Working with controls (Levels 200 and 300)
    Lab 5: Business logic (Levels 200 and 400)
    Lab 6: Active X controls (Level 400)
    Lab 7: User roles (Level 200)
    Lab 8: Working with data sources (Levels 300 and 400)
    Lab 9: Working with ADO.NET DataSets (Level 400)
    Lab 10: Digital signatures (Levels 300 and 400)
    Lab 11: Advanced form merging (Level 400)
    Lab 12: Workflow support (Level 400)
    Lab 13: Working with schemas (Level 300)
    Lab 14: Working with custom task panes (Level 400)
    Lab 15: Business logic using managed code (Level 400)
    Lab 16: External automation (Level 400)

    Alex Weinstein
    Program Manager

  • Microsoft InfoPath 2010

    Estimate performance and capacity requirements for InfoPath Forms Services environments

    • 3 Comments

    A new document went live today on Technet around capacity planning for IPFS.  Have a look and let us know what you think:

     

    http://technet.microsoft.com/en-us/library/cc879113.aspx

     

     

  • Microsoft InfoPath 2010

    Create a Rating Control using Picture Buttons

    • 3 Comments

    In this short video demo, Matt Bielich from the InfoPath test team shows how you can add a rating control to your InfoPath 2010 forms using picture buttons.

    Get Microsoft Silverlight
  • Microsoft InfoPath 2010

    Free InfoPath 2010 Web Cast: Best Practices in Form Design

    • 3 Comments

    The fourth and final session in the InfoPath 2010 Academy Live series, Best Practices in Form Design, by InfoPath PM lead Daniel Witriol takes place this Wednesday, May 5th at 8:30 AM (PST).

    You can sign up for this free Web cast on https://www.eventbuilder.com/event_desc.asp?p_event=a2d1f10w.

    If you’ve missed any of our earlier sessions, you can watch them on demand at the links below:

    Academy Live

  • Microsoft InfoPath 2010

    Create Code-Free Mashups with InfoPath and SharePoint Web Parts

    • 3 Comments

    Hi, My name is Nicholas Lovell and I’m a developer on the InfoPath team. In this video demo, I will walk through how to create a simple portal page for processing claims at an insurance company. This claims portal includes a SharePoint Web Part with a list of all the claims, an InfoPath Web Part that displays the claim details, and a custom Bing Maps Web part which displays the location of the currently selected claim.

    Get Microsoft Silverlight

    Enjoy and please share your comments with us!

    Nick

  • Microsoft InfoPath 2010

    Philo's WebLog post on "Why Smart Clients?"

    • 3 Comments

    Why Smart Clients? was posted yesterday and provides a nice perspective of the benefits of having such a smart client like InfoPath.

  • Microsoft InfoPath 2010

    Understanding the InfoPath SP1 Deployment and Security Model – An Introduction

    • 3 Comments

    A common question that was asked when people started using the initial InfoPath release was, “How can I distribute a form template to other people through email?”  In InfoPath V1, this was difficult because once you saved or published a form template to a location, it was ‘sited’ to that location.  If it was moved from that location, it would not open in the InfoPath Editor. 

    In the InfoPath Service Pack 1 release, it is now possible for form templates to be opened from locations other than their published location.  There is also a ‘Send Form as Attachment’ option under the File menu which attaches your form template to an Outlook mail message for distribution.  However, for security reasons, there are still limitations on what kinds of form templates can be opened and from what locations.  The following is a guide to understanding the InfoPath SP1 Deployment and Security Model:

    Form Template Security Level

    Each Form Template made in InfoPath SP1 has one of three security levels specified; Restricted, Domain, or Full Trust.  This setting is determined automatically by default, but can be set manually, if desired. 

    NOTE:  To access this setting in the Designer, navigate to Tools | Form Options à Security Tab. 

    Restricted – The form template does not allow any access outside of the form  

    Domain – The form template allows access outside of the form, but only within the domain of the form template

    Full Trust – The form template can access files and settings on the local computer

    The Full Trust security level can only be set manually by the user for installed templates or certificate-signed templates.  The maximum trust level that can be set automatically by InfoPath is Domain.

    All new blank form templates (except for Managed Code solutions) start out at the Restricted security level.  As you build the form, adding any of the following will automatically raise the security level to Domain:

    • Task Pane
    • Script
    • ADO Query or Submit Adapter
    • Web Service Query or Submit Adapter
    • SharePoint Query or Submit Adapter
    • Query to linked XML file
    • HTTP Submit
    • ActiveX Control
    • Roles
    • DLL Resource File
    • HWS
    • Rule that opens a new document 

    Opening the Form Templates in the InfoPath SP1 Editor

    The reason to make a distinction between Restricted and Domain security was to allow for form templates without script or data connections to be opened from anywhere.  Therefore, email deployment of restricted form templates in SP1 is easy, just send out the form template and it can be opened either from the Outlook mail itself or from wherever the recipient saves it. 

    With Domain form templates, some of the same security restrictions from v1 still exist, but SP1 allows for some added functionality.  Domain form templates still require that they be opened from their published location.  However, by using the Send Form as Attachment option in the file menu, a Domain form template can be mailed out as an attachment.  This attachment, when received and opened, functions as a link to the actual published location.  The form template at that publish location is what actually gets opened in the InfoPath Editor, not the one that was clicked on.  At that point as well, the published form template is copied locally and will appear as a selection in the Fill Out a Form dialog every time you launch InfoPath.

    Future Considerations

    This posting is meant as an introduction and does not cover all aspects of Deployment and Security.  If there are any specific questions, please respond via feedback to this article and I will follow up with further entries that will address more specific functionalities and scenarios.

  • Microsoft InfoPath 2010

    Decoding the InfoPath picture format (also Ink Picture)

    • 3 Comments

    InfoPath provides two controls which saves pictures inside the XML form (rather than linking to it). When trying to process this XML file outside of InfoPath, you will need to translate the data back into the image binary. InfoPath picture control data and ink picture control data is stored in the XML as base64 encoded data. You will need to decode the base64 picture into binary before it is usable.

    Below is a code sample in C# that will do it:

    byte[] image = Convert.FromBase64String( s );
    MemoryStream memStr = new MemoryStream();
    memStr.Write( image, 0, image.Length );
    Image img = Image.FromStream( memStr );
    img.Save( filename );

  • Microsoft InfoPath 2010

    Having more control over Page Breaks using Conditional Formatting

    • 3 Comments
    When printing forms, sometimes it might be desired to have more control over where Page Breaks should occur. For example, you might want a Repeating Table to start printing on a new page once it has reached a certain number of rows or you might wish to provide a way for users who are filling out forms to be able to insert/remove Page Breaks in certain locations of the form. You can accomplish this using Page Breaks (available with SP1) with Conditional Formatting.
     
    Example 1: Allow users to insert a Page Break when a Checkbox is checked
    1. In Design mode, insert a Checkbox Control, type "Insert Page Break" next to the checkbox.
    2. Insert a Section Control (From the Control Task Pane, click on "Section")
    3. Within the Section Control, insert a Page Break (Place the cursor inside of the Section Control you just inserted and from the menu Insert | Page Break)
    4. Double click on the Section Control to open the Section Properties dialog. Select the Display tab and click on the Conditional Formatting button.
    5. Click  Add... to set a new condition, which will keep the Page Break "hidden" unless the checkbox is checked, to do this: Select the name of the checkbox in the first condition drop-down and set the condition "is equal to FALSE". Check the "Hide this Control" checkbox and close all open dialogs by clicking "Ok"
    6. You can test your form by clicking on the Preview Form button, in the toolbar.
    Example 2: Start printing a Repeating Table in a new page once it has more than 3 rows
    1. In Design mode, insert a Section Control (From the Control Task Pane, click on "Section")
    2. Within the Section Control, insert a Page Break (Place the cursor inside of the Section Control you just inserted and from the menu Insert | Page Break)
    3. Place the mouse cursor beneath the Section Control and insert a Repeating Table (From the Control Task Pane, click on Repeating Table).
    4. Double click on the Section Control to open the Section Properties dialog. Select the Display tab and click on the Conditional Formatting button.
    5. Click Add... to set a new condition, which will keep the Page Break "hidden" unless the number of rows in the "Repeating Section" exceeds 3, to do this: Select  "The expression" in the first condition drop-down and type the following XPath expression referring to the Repeating Table, "count(../my:group2/my:group3) <=3" in the text field next to it. Check the "Hide this Control" checkbox and close all open dialogs by clicking "Ok"
    6. You can test your form by clicking on the Preview Form button, in the toolbar.
     
  • Microsoft InfoPath 2010

    Modifying InfoPath manifest.xsf file from script (2/5)

    • 3 Comments

    Part 2 of 5: Unpacking the XSN

    To unpack XSN one should use extract.exe utility. It can be found in the %SystemRoot%\system32 directory or in the Microsoft Cabinet Software Development Kit. For the command usage details just run “extract /?”.

    In this part we will also introduce several auxiliary functions that will be extensively used throughout the entire discussion topic.

    var ExtractExeLocation = "%SystemRoot%\\SYSTEM32";

    var ExtractExe = Combine(ExtractExeLocation, "extract.exe");

     

    function Combine(dir, file)

    {

          return dir + "\\" + file ;

    }

     

    function QuoteStr(string)

    {

          return ("\"" + string + "\"");

    }

     

    function Exec(string, flagWait)

    {

          if (flagWait == null)

                flagWait = true;

          var WScriptShell = WScript.CreateObject("WScript.Shell");

          return WScriptShell.Run(string, 0, flagWait);

    }

     

    function ExtractFilesFromXSN(xsnInputPath, outputDirectory)

    {

          var Parameters;

     

          // add the location to place extracted files,

          // a flag "/Y" that prevents prompting before overwriting

          // an existing file, and a flag "/E" that orders to

          // extract all files

          if (outputDirectory != null)

                Parameters = " /Y /E /L " + QuoteStr(outputDirectory);

     

          Exec(QuoteStr(ExtractExe)

                + Parameters

                + " " + QuoteStr(xsnInputPath), true);

    } 

    Now we have a tool to unpack XSN. All of the InfoPath form template files are accessible for changing. In the next part of the series we will be modifying the manifest itself.

  • Microsoft InfoPath 2010

    Converting a Data Source

    • 3 Comments

    For anyone who has developed an InfoPath form template against a schema, database, or Web service that has changed since the form template was initially created, the following should be some good news.  The SP1 Preview Release of InfoPath contains the ability to provide InfoPath with an updated version of your schema or data source and InfoPath will update your solution accordingly.  That’s right, gone are the days of hand modifying the XSF, template file, XSL, etc. in order to change the schema.  You can change your main data source via the ToolsàConvert Main Data Source menu entry or a data connection via the modify button for that source in the ToolsàData Connection dialog.

    When you provide InfoPath the updated data source, InfoPath will update the schema files stored in the form template and look for and apply changes between the old and new data source.  In particular InfoPath will look for type changes, cardinality changes, namespace changes, adds, deletes, renames, and move operations.  For any recognized operation, all existing bindings in the view, XSF, and event handler hookup will be fixed accordingly (note, it is still your responsibility to fix business logic code.)  Unfortunately InfoPath is not omnipotent, so it might not be the best idea to wait until you have renamed, moved, and extremely modified the children of an element before providing the updated schema to InfoPath ;-)

    (And if a menu option to update your data source isn't convenient enough, tomorrow we'll start a five part series on the InfoPath Team Blog showing you how you can automate this sort of operation by taking advantage of InfoPath's XML-based form template file format.) 

  • Microsoft InfoPath 2010

    Use patterns (e.g., digits or quotes) to validate data in InfoPath

    • 3 Comments

    Example 1: How do I restrict the user from entering special characters into certain fields in the InfoPath Form?

    Note: This example assumes you are running InfoPath 2003 with the SP-1 feature enhancements enabled. [Added 6/21/04]

    The easiest way to do this is to use pattern for data validation. For example, you might want a user to enter data in the ###-##-#### format for the Social Security Number field. If the user’s input does not match this format, you may want to throw an alert. You can achieve the above by doing the following:

    1. In Design mode, insert a Textbox Control
    2. Double click on the Textbox Control to get the properties dialog box
    3. Click on Data Validation | Add
    4. Choose “does not match pattern” from the second dropdown and “select a pattern” from the third dropdown
    5. Click on “Social Security number” from the standard patterns dialog

      Picture of the Data Entry Pattern dialog
    6. Click OK to accept the changes
    7. In the Data Validation dialog, choose “Dialog box alert” from the Error alert type dropdown and specify some alert message

      Picture of the Validation dialog
    8. Click OK to accept the changes
    9. You can test your form by clicking on the Preview Form button, in the toolbar  

    Example 2: I cannot put a double quote (“) or an apostrophe (‘) in the pattern builder. How do I validate data against a pattern that contains a double quote (“)?

    You can validate data against a pattern that contains double quotes by using Jscript regular expression. For example, you might want a user to enter data in the “###” format (a pattern contains double quotes) for a field. If user’s input does not match this format, you may want to throw an alert. You can achieve the above by doing the following:

    1. In Design mode, insert a Textbox Control
    2. Double click on the Textbox Control to get the properties dialog box
    3. Click on Data Validation
    4. In the Script section, choose “OnAfterChange” from the dropdown and Edit

    Picture of the Data Validation dialog

    1. Add the followings to your code  

    function msoxd_my_field1::OnAfterChange(eventObj)

    {

    // Write code here to restore the global state.

                    if (eventObj.IsUndoRedo)

                        {

    // An undo or redo operation has occurred and the DOM is  read-only.

                                    return;

                         }

     

    // A field change has occurred and the DOM is writable. Write code here to respond to the changes

     

                    // Specify your pattern using Jscript regular expression

                    var re1 = new RegExp(“\x22\\d\\d\\d\x22”);

     

                    // Get the field value

    var s = XDocument.DOM.selectSingleNode(“my:myFields/my:field1”).text;

     

    // Find a match within string s

    if (re1.exec(s) = = null && eventObj.Operation = =  “Insert”)

                    XDocument.UI.Alert(“User input does not match the required pattern”);

                    }

     

    1. After editing all the code, click OK to accept the changes
    2. You can test your form by clicking on the Preview Form button, in the toolbar
  • Microsoft InfoPath 2010

    Recursive Controls support in InfoPath 2003 SP1

    • 3 Comments

    The SP1 release of InfoPath 2003 supports recursive controls such as Repeating Recursive Section and Optional Recursive Section. Based on the schema of the solution, these controls are automatically suggested when dragging nodes from the Data Source task pane. This article talks about different types of recursion that are supported within InfoPath.

    Direct Recursion:

    This is the case when the node is recurring directly under itself. For example, if you are creating an organization chart, you might have a schema that has the following structure:

    Employee*

    EmployeeData

    ID
    Name
    …..

    Employee*

    Every employee has EmployeeData associated with him and can have 0 or more employees working for him. Note that the * stands for repeating 0 or more times. If you select the top level Employee node in the Data Source task pane, InfoPath would suggest a Repeating Recursive Section in this case with the recursive instance showing up directly under its parent.

    Picture of design mode for the direct recursion structure

    Indirect Recursion:

    This is the case when the node is recurring as a child of another node within itself. For the above organization chart, you may choose to abstract the fact that Employee is a manager or not by introducing an Optional node Manager. In this case the structure is as follows:

    Employee*

    EmployeeData

    ID
    Name
    …..

    Manager?

    ManagerData

    ID
    Name
    NumOfReports
    …..

    Employee*

    In this case, when you drag top level Employee node, InfoPath will create a Repeating Recursive Section that has the recursive instance within an Optional Section that corresponds to Manager node.

    Picture of design mode of the indirect recursion structure

    Potential Recursion:

    This is the case when the node is recurring under as one of the choices under itself. Again taking the above organization chart example, we may choose to not include EmployeeData for managers since it is covered under ManagerData. So now we could have the following structure:

    Employee*

    Choice

    Non-Manager

    EmployeeData
    ID
    Name
    …..

    Manager

    ManagerData
    ID
    Name
    NumOfReports
    …..

    Employee*

    Now we have an employee who can either be a manager or not. In this case, when you drag top level Employee node, InfoPath will create a Repeating Recursive Section that has the recursive instance within a Choice Section.

    Picture of design mode of the potential recursion structure

    In summary, you have seen how InfoPath supports various types of recursion in its SP1 release. These three examples were just to illustrate the broad categories of recursion but you can go beyond these and try various other combinations based on your needs.

  • Microsoft InfoPath 2010

    What button was clicked?

    • 3 Comments

    Another question that we get asked a lot:

    I include a Repeating Section control in my form, containing a Button and a Text Box. At runtime, a user inserts 5 items. How do I know which Button was clicked so I can get to the Text Box’s value?

    That’s actually the wrong question to ask. Strictly speaking, InfoPath doesn’t know the difference between the Buttons. They are all identical clones. What’s different about each button is its context within the view, and the view is mapped to the data. (In InfoPath it always comes back to the data.)

    If your schema looks like this:

    • myNodes
      • group1
        • group2 (repeating)
          • field1

    Your view probably looks something this:

    [View Structure]

    Since the Button control is inside the Repeating Section which is bound to group2, we say that the Button’s context is group2.

    So what?

    When the Button event is received, it contains a DocActionEvent object. The event object has a Source property. And this property is the Button’s context node – the specific group2 instance the Button is inside.

    So at this point, you can just use eventObj.Source to refer to data relative to the Button. Probably the easiest thing to do is just do some old school debugging using alerts. Here’s how to make sure you’re getting the context right:

    function CTRL3_5::OnClick(eventObj)

    {

    // Write your code here

    XDocument.UI.Alert( eventObj.Source.xml );

    }

    Here’s what you’d get:

        <my:group2 xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2004-09-14T16:02:14">

            <my:field1>abc</my:field1>

        </my:group2>

    And to wrap things up, to get the text inside the Text Box, you need to use eventObj.Source.selectSingleNode():

    function CTRL3_5::OnClick(eventObj)

    {

    // Write your code here

    XDocument.UI.Alert( eventObj.Source.selectSingleNode("my:field1").text );

    }

  • Microsoft InfoPath 2010

    InfoPath Quick Tip: Setting a User Role as the Initiator

    • 3 Comments

    In Microsoft Office InfoPath 2003, you can assign users to distinct categories, called user roles, which are based on job title or other criterion. InfoPath can perform custom actions that vary based on the current user role, such as switching views, conditional formatting, data validation, or filter settings.

    Some InfoPath form designers have found the Set as initiator option for user roles to be somewhat confusing when specifying a role using network accounts. (The Set as initiator option is available when defining a user role by clicking User Roles on the Tools menu, and then clicking Add). Setting a user role as the initiator will cause InfoPath to use that role whenever a new blank form is opened for the first time regardless of how the user is logged on to the network. However, the next time that user opens the same form, InfoPath will use the person's assigned user role instead of the initiator role

    For example, suppose you create a form template with an Employee View and a Manager View and then create a rule to switch views based on whether the current user role is Employee or Manager as demonstrated in Lab 7: User Roles in InfoPath 2003. Because the Employee role is set as the initiator, when a user creates new blank form, InfoPath will always set the user role to Employee even if the current user is not a member of the network group or user accounts specified for the Employee user role. As a result, InfoPath will always switch to the Employee View the first time a user creates a new blank form. Only after the form is saved and re-opened will the rule be applied based on the user role defined for the user's network account.

  • Microsoft InfoPath 2010

    Enforcing unique values in a repeating list

    • 3 Comments
    Have you ever created a form which allows the user to choose items from a list and you wanted to make sure the user doesn't choose the same item twice?  If you've got InfoPath 2007 you can use the new Multi Select List Box, but if you've got InfoPath 2003, you're still in luck, this blog entry is for you!
     
    Note: You should be familiar with XPath expressions before preceding.
     
    Let's start with a repeating table with a dropdown control bound to a secondary data source.
     
     
    There are a few choices when it comes to enforcing unique values selected by the user:
    1. Only show values that have not already been selected by the user.
    2. Show a validation error when the user selects something which has already been selected.
    3. Write code using the Changing event.
     
    This blog entry will cover both options 1 and 2.
     
    Option 1 - Only show values that have not already been selected by the user
     
    Only showing certain values implies that a filter is being applied to the dropdown.  To apply a filter, click the Filter Data… button when selecting the entries for the dropdown to show the condition builder.  Unfortunately, there is no UI in the condition builder to build an expression that means "don't show anything that is already in the list".  Thus, we'll have to construct this manually by selecting The Expression.
     
     
    You might be tempted to put the following expression:
    . != xdXDocument:get-DOM()/my:myFields/my:items/my:item/my:product
    This will return true if any one value from the list matches the current value.  In other words, this condition will always return true if there are two entries in the list which are different.  (Definitely not what we are looking for)
     
    The correct condition is a slight adjustment to the former expression:
    not(. = xdXDocument:get-DOM()/my:myFields/my:items/my:item/my:product)
    This will only return true if none of the values from the list matches the current value.  In other words, only values that are not in the list will be displayed.
     
    Preview the form and you will see that the dropdown only lists the products that have not already been selected.
     
     
     
    Option 2 - Show a validation error when the user selects something which has already been selected
     
    The only way this will work properly is if we add a hidden calculated field along with the product selection.
    (The reason for this is a bit too complex to explain here, so it'll have to wait for another time.)
     
     
    The formula for the unique field is the following:
    not(../my:product = (../preceding-sibling::my:item | ../following-sibling::my:item)/my:product)
    This will set Unique to true if and only if the product isn't already selected preceding or following the current item.
     
    The next and final step is to use data validation on the dropdown to show an error.
     
     
    Preview the form and you will see that the dropdown will show a validation error if the items are not unique.
     
     
    - Gary
    Software Development Engineer
  • Microsoft InfoPath 2010

    More than one way to write code: Visual Studio and InfoPath

    • 3 Comments
    If you need to write some Visual Basic or C# code behind your form, or maybe just some script, there are a few different tools you can use depending on which versions of InfoPath and Visual Studio you have.
     
    Here's a quick table summarizing it all:
     
     
    Note that both Microsoft Script Editor (MSE) and Visual Studio Tools for Applications (VSTA) come with InfoPath 2007 Beta, so you can open them from the Tools | Programming menu. If you don't see the one you want, change the language in Tools | Form Options. If it gives you an error that it's not installed, here's how to install them:
     
    1. If you are going to install VSTA, make sure you have the pre-requisites first:
    2. Go to Start > Control Panel > Add or Remove Programs
    3. Select your Office installation and click Change
    4. In the Office Setup wizard select to add features
    5. Find Microsoft Script Editor (under Office Tools) and/or Visual Studio Tools for Applications (under InfoPath > .NET Programmability) and select Run from my computer
    6. Finish the wizard
     
    Happy code writing!
    - Ned
  • Microsoft InfoPath 2010

    Yesterday's InfoPath WebCast: Programming Workflow into InfoPath Solutions: Using InfoPath with BizTalk Server 2004 and Human Workflow Services

    • 3 Comments

    Hello everyone,

    I want to personally thank those of you who attended yesterday’s WebCast: Programming Workflow into InfoPath Solutions: Using InfoPath with BizTalk Server 2004 and Human Workflow Services which was presented by Rick Severson.  I hope you enjoyed the talk as much as I did and were able to learn something new.  Also, I hope you filled out a survey at the end of the talk so you are entered in the Halo 2 contest.  (Please visit the following URL to view the contest rules: http://msdn.microsoft.com/office/understanding/infopath/multimedia/halo/default.aspx.)

    If you were unable to attend the talk, don’t worry.  It was recorded and is available via the following URL: http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032259548&Culture=en-US.   (You will have to register before you can view the recorded WebCast.)

    Please join us next Tuesday, December 14 from 11am – 12:30pm PST for the next presentation in the InfoPath WebCast series: “Database Connectivity in InfoPath Through ADO.NET DataSet Support” which will be presented by Mikhail Vassiliev, a Software Design Engineer on the InfoPath team.  You can register for this talk by clicking on the following URL: http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?EventID=1032259550&Culture=en-US.  I hope you will join us.

    Here is more information about the talk:

    MSDN Webcast: Database Connectivity in InfoPath Through ADO.NET DataSet Support—Level 400    

    Start Time:       Tuesday, December 14, 2004 11:00 AM (GMT-08:00) Pacific Time (US & Canada

    End Time:        Tuesday, December 14, 2004 12:30 PM (GMT-08:00) Pacific Time (US & Canada

    Event Description 

    In this webcast session you will learn how to use Microsoft® Office InfoPath™ to design a form as a front-end to a Web Service that exposes ADO.Net DataSet structure. We will teach you the InfoPath Data Adapter architecture, new Data Adapters in InfoPath 2003 SP-1, and talk about reasons for using ADO.NET DataSets in a Web Service with InfoPath forms. See the advantages and the restrictions when using DataSets in InfoPath. You will also get an inside view of the InfoPath DataSet support implementation so you can see how this feature works in InfoPath.

    Presenter: Mikhail Vassiliev, Software Design Engineer,Microsoft Corp.

    Mikhail Vassiliev has been a member of the Microsoft® Office InfoPath™ Team from the beginning of the application development, joining Microsoft at 1998. He has been designing and implementing a wide range of the program components starting from the basic editing, data adapters, and finishing with SDK tools. Mikhail enjoys programming and continues to work on the new InfoPath features.

    Scott Roberts

  • Microsoft InfoPath 2010

    Microsoft Office InfoPath 2003 Toolkit for Visual Studio 2005

    • 3 Comments

    Visual Studio 2005, SQL Server 2005, and BizTalk 2006 all launched on Monday.

    That means the Microsoft Office InfoPath 2003 Toolkit for Visual Studio 2005 is now available as part of the Visual Studio 2005 Tools for the Microsoft Office System.

    To install the Toolkit, run setup from the CD labeled "Microsoft Office InfoPath 2003 Toolkit for Visual Studio 2005" that is included with the Visual Studio 2005 Tools for Office package, or from the separate related download for MSDN Subscribers.

    Find out more here: http://msdn.microsoft.com/office/understanding/vsto/

     

  • Microsoft InfoPath 2010

    Hiding hint text when conditionally hiding a repeating or optional control

    • 2 Comments

    Certain controls, such as repeating and optional sections and repeating tables, will display a link that, when clicked, will insert a new item into the form. By default, the text of this link, which is called hint text, is “Insert item” for repeating controls and “Click here to insert” for optional sections.  This text can be customized or turned off completely through each of these control’s property dialogs.

    In addition, the InfoPath Designer enables you to specify conditional formatting for these controls.  One of the actions that you can perform is to hide the control based on some condition.  When that condition is true, the control is hidden.  However, when the control is hidden, the hint text remains visible. This is often perceived as a bug in InfoPath but is actually by-design.

    The reason behind this is simple and makes complete sense once you understand it.  Very simply put, each of the repeating controls allows you to set conditional formatting on a per-row basis.  This means that you can specify a condition that will hide a specific row and not the entire repeating table or all instances of the repeating section.

    However, sometimes, especially in the case of optional sections, you wish to hide the entire control instead of just a single row.  The workaround for this is to put the control inside a section.  Then, set the condition which will hide the control on the section itself.  This will hide the section and all controls within it.

     

  • Microsoft InfoPath 2010

    TechEd Source Code

    • 2 Comments

    Some people were using digital cameras to capture the source code from our "InfoPath: Developing Forms with Managed Code" sessions, but we want to make it easier than that!

    So here's the code Ned Friend used in the TechEd Europe version of the presentation (David Gerhardt used similar code in his USA version of the talk in Orlando):

    DISCLAIMER: This code is designed to be short and sweet for demo purposes only. IT IS NOT BEST PRACTICES NOR READY FOR PRODUCTION.

    using System;

    using Microsoft.Office.Interop.InfoPath.SemiTrust;

    // Add .NET reference: System.Xml

    using System.Xml;

    using System.Xml.Xsl;

    using System.Security.Cryptography;

    using System.IO;

    // Add COM reference: Microsoft Word 11.0 Object Library

    using Word = Microsoft.Office.Interop.Word;

     

    // Office integration attribute. Identifies the startup class for the form. Do not

    // modify.

    [assembly: System.ComponentModel.DescriptionAttribute("InfoPathStartupClass, Version=1.0, Class=StatusReport.StatusReport")]

    namespace StatusReport

    {

    // The namespace prefixes defined in this attribute must remain synchronized with

    // those in the form definition file (.xsf).

        [InfoPathNamespace("xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xdUtil=\"http://schemas.microsoft.com/office/infopath/2003/xslt/Util\" xmlns:xdXDocument=\"http://schemas.microsoft.com/office/infopath/2003/xslt/xDocument\" xmlns:tm=\"http://microsoft.com/wsdl/mime/textMatching/\" xmlns:dfs=\"http://schemas.microsoft.com/office/infopath/2003/dataFormSolution\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\" xmlns:xd=\"http://schemas.microsoft.com/office/infopath/2003\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:tns=\"http://tempuri.org/\" xmlns:msxsl=\"urn:schemas-microsoft-com:xslt\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xdMath=\"http://schemas.microsoft.com/office/infopath/2003/xslt/Math\" xmlns:xsf=\"http://schemas.microsoft.com/office/infopath/2003/solutionDefinition\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" xmlns:my=\"http://schemas.microsoft.com/office/infopath/2003/myXSD/2005-05-24T18:10:14\" xmlns:xdDate=\"http://schemas.microsoft.com/office/infopath/2003/xslt/Date\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")]

        public class StatusReport

        {

            private XDocument thisXDocument;

            private Application thisApplication;

            // For encryption/decryption

            private Rijndael key = new RijndaelManaged();

            public void _Startup(Application app, XDocument doc)

            {

                thisXDocument = doc;

                thisApplication = app;

                // You can add additional initialization code here.

            }

            public void _Shutdown()

            {

            }

            // The following function handler is created by Microsoft Office InfoPath. Do not

            // modify the type or number of arguments.

            [InfoPathEventHandler(EventType = InfoPathEventType.OnLoad)]

            public void OnLoad(DocReturnEvent e)

            {

                // Set the username

                IXMLDOMNode userName =

                    thisXDocument.DOM.selectSingleNode("/my:status/my:name");

                if (userName.text == String.Empty)

                {

                    userName.text = Environment.UserName;

                }

                // Load key information

                IXMLDOMNode keyNode = thisXDocument.DOM.selectSingleNode("/my:status/my:key");

                IXMLDOMNode ivNode = thisXDocument.DOM.selectSingleNode("/my:status/my:iv");

                byte[] keyBytes = Convert.FromBase64String(keyNode.text);

                byte[] ivBytes = Convert.FromBase64String(ivNode.text);

                // Decrypting the project name

                MemoryStream ms = new MemoryStream();

                CryptoStream csRijndael =

                    new CryptoStream(ms, key.CreateDecryptor(keyBytes, ivBytes), CryptoStreamMode.Write);

                IXMLDOMNode projectNode =

                    thisXDocument.DOM.selectSingleNode("/my:status/my:project/my:name");

                byte[] projectBytes = Convert.FromBase64String(projectNode.text);

                csRijndael.Write(projectBytes, 0, (int)projectBytes.Length);

                csRijndael.FlushFinalBlock();

                string projectName =

                    System.Text.Encoding.Unicode.GetString(ms.GetBuffer(), 0, (int)ms.Length);

                projectNode.text = projectName;

            }

            // The following function handler is created by Microsoft Office InfoPath. Do not

            // modify the type or number of arguments.

            [InfoPathEventHandler(MatchPath = "/my:status/my:date", EventType = InfoPathEventType.OnValidate)]

            public void date_OnValidate(DataDOMEvent e)

            {

                // Custom data validation because InfoPath does not have functions for date arithmetic

                if (e.Operation == "Insert")

                {

                    try

                    {

                        DateTime date = DateTime.Parse(e.NewValue.ToString());

                        if (date.CompareTo(DateTime.Today.AddDays(5)) > 0)

                        {

                            e.ReportError(e.Site, "Date cannot be more than 5 days away.",

                                                         false, null, 1, "modal");

                        }

                    }

                    catch (FormatException)

                    {

                        // Incorrectly formatted dates are handled automatically by InfoPath.

                    }

                }

            }

            // The following function handler is created by Microsoft Office InfoPath. Do not

            // modify the type or number of arguments.

            [InfoPathEventHandler(EventType = InfoPathEventType.OnSubmitRequest)]

            public void OnSubmitRequest(DocReturnEvent e)

            {

                // If Online, submit using data adapter

                if (thisApplication.MachineOnlineState == XdMachineOnlineState.xdOnline)

                {

                    WebServiceAdapter2 webServiceAdapter =

                        (WebServiceAdapter2)thisXDocument.DataAdapters["Submit"];

                    webServiceAdapter.Submit();

                }

                // If Offline, save to cache

                else

                {

                    XmlDocument xmlDoc = new XmlDocument();

                    string now = DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss.ff");

                    xmlDoc.PreserveWhitespace = true;

                    xmlDoc.LoadXml(thisXDocument.DOM.xml);

                    xmlDoc.Save("C:\\TechEd2005\\Submit\\Form " + now + ".xml");

                }

                e.ReturnStatus = true;

            }

            // The following function handler is created by Microsoft Office InfoPath. Do not

            // modify the type or number of arguments.

            [InfoPathEventHandler(EventType = InfoPathEventType.OnSaveRequest)]

            public void OnSaveRequest(SaveEvent e)

            {

                // Set up encryption streams

                MemoryStream ms = new MemoryStream();

                CryptoStream csBase64 =

                    new CryptoStream(ms, new ToBase64Transform(), CryptoStreamMode.Write);

                CryptoStream csRijndael =

                    new CryptoStream(csBase64, key.CreateEncryptor(), CryptoStreamMode.Write);

                // Encrypt project name

                IXMLDOMNode projectNode =

                    thisXDocument.DOM.selectSingleNode("/my:status/my:project/my:name");

                byte[] projectBytes =

                    System.Text.Encoding.Unicode.GetBytes(projectNode.text);

                csRijndael.Write(projectBytes, 0, (int)projectBytes.Length);

                csRijndael.FlushFinalBlock();

                string projectEncrypted =

                    System.Text.Encoding.ASCII.GetString(ms.GetBuffer(), 0, (int)ms.Length);

                // Save key information

                IXMLDOMNode keyNode = thisXDocument.DOM.selectSingleNode("/my:status/my:key");

                IXMLDOMNode ivNode = thisXDocument.DOM.selectSingleNode("/my:status/my:iv");

                keyNode.text = Convert.ToBase64String(key.Key);

                ivNode.text = Convert.ToBase64String(key.IV);

                // Save encrypted project name, then decrypt in view

                string projectOriginal = projectNode.text;

                projectNode.text = projectEncrypted;

                e.IsCancelled = e.PerformSaveOperation();

                projectNode.text = projectOriginal;

                thisXDocument.SetDirty(false);

                e.ReturnStatus = true;

            }

            // The following function handler is created by Microsoft Office InfoPath. Do not

            // modify the type or number of arguments.

            [InfoPathEventHandler(MatchPath = "ButtonGenerate", EventType = InfoPathEventType.OnClick)]

            public void ButtonGenerate_OnClick(DocActionEvent e)

            {

                // This button converts the XML Form to a Word Document

                

                // Load the XSLT file from resources

                IXMLDOMDocument domDocument = thisXDocument.CreateDOM();

                domDocument.load("StatusReport.xsl");

                XmlDocument xsltDocument = new XmlDocument();

                xsltDocument.LoadXml(domDocument.xml);

                // Load the XML DOM into System.Xml

                XmlDocument infoPathDocument = new XmlDocument();

                infoPathDocument.LoadXml(thisXDocument.DOM.xml);

                // Apply the XSLT to the XML DOM

                XslCompiledTransform xslt = new XslCompiledTransform();

                xslt.Load(xsltDocument);

                XmlDocument outputDocument = new XmlDocument();

                System.Xml.XPath.XPathNavigator outputNavigator = outputDocument.CreateNavigator();

                using (XmlWriter writer = outputNavigator.AppendChild())

                {

                    xslt.Transform(infoPathDocument, writer);

                }

                // Instantiate Word with the new document

                object missing = System.Reflection.Missing.Value;

                Word.Application wordApplication = new Word.ApplicationClass();

                Word.Document oDoc = new Word.DocumentClass();

                oDoc = wordApplication.Documents.Add(ref missing, ref missing, ref missing, ref missing);

                wordApplication.Selection.Range.InsertXML(outputDocument.OuterXml, ref missing);

                wordApplication.Visible = true;

            }

        }

    }

  • Microsoft InfoPath 2010

    Encrypting and Decrypting InfoPath Form Data

    • 2 Comments

    This question comes up frequently:

    Can I encrypt the XML data coming out of InfoPath?

    The answer is "yes!", and there is a wonderful article on MSDN that explains just how to do it, titled Extending the Save Functionality in InfoPath 2003. The article covers a lot of ground, and includes managed code samples showing how to perform data encryption during OnSaveRequest and decryption during OnLoad. Similar code can be used during OnSubmitRequest to encrypt the data before sending it out over the wire.

  • Microsoft InfoPath 2010

    Check if form is new using roles, not code

    • 2 Comments
    Ever want to add conditional formatting or special rules that only fire if your form was just created?
     
    For example, you want to show one view by default when someone creates a new expense report, but you want show a summary view for everyone else who opens the form.
     
    Here's how.
     
    Click on Tools, then User Roles, and use the dialog to add two roles:
    • New Form: Check the checkbox for "initiator" (don’t set any other properties) This role will apply for new forms only.
    • Old Form: Set this one as the "default" in this list
     
    You'll get something like this in the dialog:
     
     
    Now you've got roles to detect whether the user just created the form or is opening it later on, so you can use that information in Rules, Data Validation, Conditional Formatting, even Filters. Just go to the place you want to be conditional, then pick User's Current Role in the first dropdown of the condition, and pick the role you want to test for in the third dropdown (New Form or Old Form).
     
    You'll get something like this:
     
     
    Now when someone opens the form, you'll know if they just created it or are coming back later, and can make your form dynamic accordingly. It doesn't make sense for most forms, but like all the tricks in the blog, I hope this trick helps you make quick progress when the need arises.
     
    And there you have it. A little tip for the week.
     
    - Ned
Page 7 of 12 (298 items) «56789»