Microsoft InfoPath 2010
The official blog of the Microsoft InfoPath team

  • Microsoft InfoPath 2010

    Getting the XPath without straining your brain

    • 5 Comments
    Yesterday I talked about using System.Xml in the new object model. My code examples included a key part of the InfoPath programming model: looking up fields in the data source using XPath so that you can set and get values.
     
    Unfortunately, figuring out the absolute XPath to a field can be a pain.
     
    Fortunately, we've made that easy in InfoPath 2007.
     
    Here's how
    Right click the field in the Data Source task pane and click Copy XPath
     
    Now you can paste the XPath into your code and be on your merry way.
     
    Hope that helps,
    Ned
  • Microsoft InfoPath 2010

    Cool video on InfoPath in Outlook

    • 5 Comments
    As part of getting everyone up to speed on Office 2007, and in preparation for the imminent release of the Beta, we've just posted some "Partner technical readiness training" videos.
     
    It includes a great one on using InfoPath in Outlook, so I thought I'd call it out:
     
    You can check out all the videos here:
     
    Enjoy!
    -ned
  • Microsoft InfoPath 2010

    Adding a Data Connection to Some WebServices Cause InfoPath 2003 to Disappear

    • 5 Comments

    When adding a web service data connection to an InfoPath 2003 form template, there is a bug that will cause InfoPath 2003 to disappear if the web service’s WSDL contains a particular recursive schema construct.  The following snippet of XSD illustrates the issue:

     

    <xs:element name="RecursiveRoot">

    <xs:complexType>

    <xs:sequence>

    <xs:element name="Branch1" minOccurs="0">

    <xs:complexType>

    <xs:sequence>

    <xs:element ref="ns:RecursiveRoot " maxOccurs="unbounded" />

    </xs:sequence>

    </xs:complexType>

    </xs:element>

    <xs:element name="Branch2" minOccurs="0">

    <xs:complexType>

    <xs:sequence>

    <xs:element ref="ns:RecursiveRoot" maxOccurs="unbounded" />

    </xs:sequence>

    </xs:complexType>

    </xs:element>

    </xs:sequence>

    </xs:complexType>

    </xs:element>

     

    This XSD contains a recursive structure in which there is more than 1 path of recursion and the recursive root is not marked as an optional element in the XSD when referenced.  InfoPath 2003 will work with the WSDL containing this XSD as expected if both references to RecursiveRoot were optional as illustrated in the following modified XSD (changes in red).

     

    <xs:element name="RecursiveRoot">

    <xs:complexType>

    <xs:sequence>

    <xs:element name="Branch1" minOccurs="0">

    <xs:complexType>

    <xs:sequence>

    <xs:element ref="ns:RecursiveRoot " maxOccurs="unbounded" minOccurs="0"/>

    </xs:sequence>

    </xs:complexType>

    </xs:element>

    <xs:element name="Branch2" minOccurs="0">

    <xs:complexType>

    <xs:sequence>

    <xs:element ref="ns:RecursiveRoot" maxOccurs="unbounded" minOccurs="0"/>

    </xs:sequence>

    </xs:complexType>

    </xs:element>

    </xs:sequence>

    </xs:complexType>

    </xs:element>

     

    If you are having issues with a web service that you own, one work around to this issue with InfoPath 2003 is to modify the WSDL for your web service as shown above.  In the case that this is not an acceptable work around, or you do not own the web service, the following steps will help you work around the problem:

     

    1.      Download the WSDL file for the web service to your local machine

     

    2.      Modify the XSD in the WSDL as shown above

     

    3.      Add a Data Connection to the local version of the WSDL file

     

    If you are setting up a submit or receive/submit web service connection then the following steps are required as well to ensure that the data InfoPath submits to the web service adheres to the original schema:

     

    4.      File --> Extract Form Files to save your form template in an uncompressed format

     

    5.      Remove the modifications made to the WSDL XSD in the copy of the XSD that was added to the form template

     

    If you modify the data connection or add another data connection to this local WSDL file for a submit web service then steps #4-#5 will have to applied again.  If you expect other users to modify the design of this form template then the local version of the WSDL should be stored in a shared location that all designers have access to.

     

    This issue has been reported to the InfoPath team as occurring in the ItemLookup method of the web services that Amazon exposes (http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl).  In the case of this method, the modification that is necessary to avoid the InfoPath 2003 bug (step #2) is the following:

     

    1.       Find the BrowseNode element that contains references to other BrowseNode elements

    2.       Add minOccurs=”0” to the BrowseNode references (these occur under the “Children” element and the “Ancestors” element)

     

    Since ItemLookup is a receive only method, there is no need to modify the form template files by hand (steps #4 and #5).

     

  • Microsoft InfoPath 2010

    Information Rights Management: Protecting Forms

    • 5 Comments

    In a recent post, we discussed ways to protect sensitive data in your InfoPath forms. This article will drill down on one of these mechanisms - Information Rights Management, a.k.a. IRM. InfoPath 2007 features the ability to set permissions on both the form template that you’re designing and the forms that are based on it. You can choose to restrict who can read or write your form/form template, as well as whether read permissions include the ability to copy, print, etc. This feature is available in the both the designer and editor by clicking the Permission button on the Standard toolbar:

    Form instance permissions
    When filling out a form, users can set permissions for that particular form. Clicking on the Permissions button in the Standard toolbar will pop up the following dialog:

    The user that created that instance of the form will have full control permissions and can grant read or write permissions to other users. Users that do not have any permissions to that form will not be able to even open it.

    This feature can make InfoPath a great tool for scenarios where some degree of privacy is required, for example, feedback to a manager to peer.

    Form template permissions
    In addition to setting permissions for each individual form that is filled out, InfoPath also provides Permission functionality for the form template. When designing a form template, clicking on the Permissions button will pop up the Permission dialog:

    The ‘Restrict permission to this form template’ checkbox at the top will initially be unchecked – check it to turn on Permissions. You will then be able to select users or groups that will have different levels of permissions for this form template.

    Keep in mind that this area only allows you to control access to the form template itself, not to the forms that are based upon it. To restrict permissions to the forms based on this form template, you would check the second checkbox, ‘Restrict permission to forms based on this form template’:

    As mentioned for users setting these permissions in the editor, the user that created the instance of the form will always have Full Control permissions for that form instance, but you can get more specific by clicking ‘Change permissions…’. Here you’ll be able to select who will have Read and Change permissions and which additional features will be available to users.

    If you are designing a form for your specific team, you can take advantage of this feature to only give Write rights to members of the team. Everyone else can be given Read rights.

    Managing your credentials
    When working with InfoPath forms or form templates that have restricted permissions, you can select an account to access the content with. For example, if your personal e-mail address does not have permissions to view an expense reporting form, you can set InfoPath to use your work address instead.

    You can access this feature by clicking on Manage Credentials in the File menu:

    Thanks all. I hope you find this useful.

    One thing to keep in mind is that IRM is not a security feature – there are ways to get around it. It’s there to make it more difficult for users to accidentally or maliciously tamper with sensitive data.

    Bojana
    Program Manager

  • Microsoft InfoPath 2010

    All you wanted to know about browser compatibility

    • 5 Comments

    These articles will help you answer many of the questions you might have about Forms Services browser compatibility, rich-client only features, and the Design Checker.

    Title

    Details

    Audience

    Plan browser support (OSS)

    Describes the different levels of browser support for MOSS.

    Admin

    Creating InfoPath Form Templates That Work With Forms Services

    Describes the following:

    1. Features supported by both InfoPath and Forms Services
    2. Features not supported by Forms Services
    3. Object Model that works in Both InfoPath and Forms Services
    4. Object Model that works only in InfoPath

    Dev

    Web browser compatibility in InfoPath Forms Services

    Describes the following:

    1. Which browsers are compatible with Forms Services?
    2. Which InfoPath 2007 features are supported in browser-enabled form templates?

    End-user

    InfoPath 2007 features that are unavailable in InfoPath Forms Services

    Describes the following:

    1. Controls that work in both InfoPath and Forms Services
    2. Controls that work only in InfoPath (lists Design Checker errors and messages)
    3. Features that work in both InfoPath and Forms Services
    4. Features that work only in InfoPath (lists Design Checker errors and messages)

    End-user

    Microsoft Office server system requirements

    Describes system requirements for all server products, including browser requirements.

    All

     

    Anneliese
    Senior Writer

  • Microsoft InfoPath 2010

    Take a list offline using SharePoint Workspace 2010

    • 5 Comments

    In this short video demo, Shirish Pulikkal from the InfoPath test team shows how you can customize a SharePoint list in InfoPath designer and work with the list offline in SharePoint Workspace.

    The Scenario: A fictitious company Fabrikam wants to track assets in their lab using SharePoint list. They want to be able to track assets both in the online and offline case. Fabrikam has decided to use InfoPath to customize the list and SharePoint workspace to enable working offline with the list.

    The Process: We start by customizing the form for the SharePoint list in InfoPath designer and add a secondary data connection to pull data from another SharePoint list. Then we publish the form back to the SharePoint list and sync it in SharePoint Workspace. Now we can create list items while working offline in SharePoint Workspace and items can be synced to SharePoint server when we get back online.

    Get Microsoft Silverlight

  • Microsoft InfoPath 2010

    Cool Forms! NCAA March Madness Bracket

    • 5 Comments

    This week’s cool InfoPath form is a browser form used to run a bracket tournament at Microsoft. The form uses filtered dropdowns to let users make their picks for NCAA March Madness 2010, and uses conditional formatting to show correct and incorrect picks as the tournament progresses. There’s also a printable view that shows the full bracket on one page, making it easy to print your bracket and show it off to your co-workers.

    The form contains several data connections to SharePoint lists containing participants and results, which means that updating the results is as simple as editing a SharePoint list item, and doesn’t involve changing the form at all.

    Edit View (click to see larger image):

    Edit View

    Display View (click to see larger image):

    Display View

    Print View (click to see larger image):

    Print View

    For details on how we created the filtered dropdowns in this form, see Use Rules and Filters to Create Cascading Dropdowns.

    If you have a “cool” form that you would like to share with us, please send an e-mail with the following details to coolform@microsoft.com -

    • Attach 1 or 2 screenshots of your form
    • Provide a brief description of the form
    • You may also attach the XSN file (optional)

    The most popular submissions will be featured on our blog in future posts.

    Check out other Cool Forms! here.

  • Microsoft InfoPath 2010

    Using Relative URLs with the ServerInfo Class in InfoPath 2010

    • 4 Comments

    Hi, my name is Jill Anderson and I am a tester on the InfoPath team. In this post, I would like to introduce you to the one of the newest members of the InfoPath Object Model, the "ServerInfo" class.  For InfoPath forms published to a SharePoint server, the members of this class give you context about that particular site. Documentation about this new class can be found at: http://msdn.microsoft.com/en-us/library/microsoft.office.infopath.serverinfo.aspx.

    In this short video demo, I show you how you can use the members of this class to enable your form to submit data using a relative URL.  This enables you to package a Site Collection as a WSP and move it to a new server.  With these changes, the submit data connection moves to the new server as well.

    Initial Setup:

    To make sure that my form template was correctly associated with my SharePoint Form Library both before and after the Site Collection Migration, I published it as a Content Type (http://office.microsoft.com/en-us/infopath-help/create-a-sharepoint-library-or-site-content-type-for-your-form-template-HA010103005.aspx ). The ability to publish a Sandboxed Solution as a Content Type is a new feature for Office 2010.

    Afterwards, I associated this content type with the correct SharePoint Form Library on the SharePoint Server. The steps to do this are as follows: 

    1. Create a new "Form Library"
    2. Open the newly created "Form Library"
    3. Open the "Library Settings" located under the "Library" Tab on the Ribbon
    4. Open "Advanced Settings" and set "Allow management of content types?" to "yes".
    5. Under "Content Types" select "Add from existing content types"
    6. Add the content type you published to the SharePoint server.

    Sample Code:

    This is the code I used to relativize the submit to the SharePoint site.

    /// <summary>
    
            /// Submits the form to the SubmittedTimeCards form library on SharePoint and calls a function to update the Vacation 
    
            /// and Sick Balance for the employee.
    
            /// </summary>
    
            /// <param name="sender">The source of the event.</param>
    
            /// <param name="e">Provides data for the Microsoft.Office.InfoPath.FormEvents.Loading event.</param>
    
            
    
            public void FormEvents_Submit(object sender, SubmitEventArgs e)
    
            {
    
                FileSubmitConnection fileSubmit = (FileSubmitConnection)this.DataConnections["SharePoint Library Submit"];
    
                // Refreshing the Total number of hours and total pay for this given form.
    
                this.CalculateWorkWeekHours();
    
                this.CalculateTotalTypeHours();
    
                this.CalculateTotalPay();
    
                // Update the new Sick leave and Vacation Balance.
    
                this.DeductVacationAndSickPay();
    
                // Relative the SharePoint Submit location to current SharePoint site.
    
                fileSubmit.FolderUrl = this.ServerInfo.SharePointSiteUrl.ToString() + "SubmittedTimeCards/";
    
                fileSubmit.Execute();
    
                // If the submit operation is successful, set
    
                e.CancelableArgs.Cancel = false;
    
            }
    
    
    

    Additional Links

    For more information about creating and publishing Sandboxed Solutions see Phil Newman's post on
    Introduction to Sandboxed Solutions - Sort data in repeating tables using managed code
    Jill

  • Microsoft InfoPath 2010

    Peer to Peer Solutions using SharePoint Workspace 2010

    • 4 Comments

    In the 2nd of 2 videos about InfoPath 2010 and SharePoint Workspace integration, Shirish Pulikkal from the InfoPath test team shows how to create and maintain an Asset Tracking list for both online and offline use, using InfoPath designer and SharePoint Workspace.

    The Scenario: In the 1st video, Taking a list offline using SharePoint Workspace 2010, Shirish showed how to take a SharePoint Asset Tracking list offline in SharePoint Workspace. Smaller organizations with budget constraints may not have access to a SharePoint Server. In this video we show you how to create and maintain an Asset Tracking list for both online and offline use, using just InfoPath and SharePoint Workspace.

    The Process: We use an Asset Tracking form and Categories form for the demo. Initially the Categories form is imported into SharePoint Workspace and we enable lookup to the list tool containing the Categories form. Next we design a new form for Asset Tracking from within SharePoint Workspace and add a SharePoint Workspace data connection to the Categories form. Then we import the Asset Tracking form in list tool in SharePoint Workspace, publish the tool and make the form available to other users subscribed to the workspace to create new list items. This is an example of a peer to peer scenario. The changes you make in your workspace will be immediately visible to other users subscribed to your workspace.

    Get Microsoft Silverlight
  • Microsoft InfoPath 2010

    InfoPath 2010 Public Beta is Here!

    • 4 Comments

    InfoPath 2010 LogoThe InfoPath team is excited to announce the release of the Office 2010 and SharePoint Server 2010 public betas! For the 1st time members of the public can download InfoPath 2010. Download it now from www.microsoft.com/2010!

    Here are just some of the highlights in this new release. (For more details, see our earlier What's New in InfoPath 2010 post).

    Quick and Easy Form Design

    • Designing good looking forms has been made easier with our new page layout templates, layout tables, and themes.
    • With our new out-of-the-box rules and improved rules management UI, you can easily add rules to validate data, format your form, or perform other actions with just a couple of clicks, and without any code. 
    • Our new “quick” publish functionality allows you to publish forms in a single click (no more clicking through the Publishing Wizard every time you want to make an update to your forms!)
    • New Controls include the picture button, signature line control and person/group picker which is now available out-of-the-box in the controls gallery.

    SharePoint Integration
    Over the past 3 years of product development, we’ve made huge investments in integration with the SharePoint platform to make it much easier to build rich forms-based applications on top of SharePoint Server 2010.

    • Using InfoPath, you can now extend and enhance the forms used for creating, editing and viewing items in a SharePoint list.
    • With the new InfoPath Form Web Part, you can host your forms on portal pages without writing a single line of code. 
    • With SharePoint sandboxed solutions, forms with code can be published directly to SharePoint libraries without requiring administratror approval.
    • Richer browser forms:Bulleted, numbered, and plain lists, multiple selection list boxes, Combo boxes, Choice group and sections, and Filtering functionality are now supported in browser forms.
    • InfoPath Forms Services Administration and Management: We have invested in many improvements to make it easier to manage InfoPath Forms Services as a component of Microsoft SharePoint Server 2010. These include Powershell commandlets to automate tasks and SharePoint Maintenance Manager Rules to monitor the health of your server.

    New iconIntroduced since the technical preview, InfoPath now supports connecting to REST Web Services.

    Go download the beta now and send us your feedback using Send-a-Smile.

    Enjoy!

    The InfoPath Team

  • Microsoft InfoPath 2010

    InfoPath 2010 is unveiled at the SharePoint Conference

    • 4 Comments

    As many of you may know, the SharePoint Conference 2009 is taking place this week in Las Vegas, Nevada and it's been a particularly exciting week for the InfoPath product team. Over the past 3 years of product development, we have made huge investments in integrating with the SharePoint platform. Finally, this week, we got the opportunity to unveil the fruits of these investments to the world, and so far, the reception has been tremendously positive! (Check out what people are saying about InfoPath 2010 on Twitter.)

    SPC is taking place at the Mandalay Bay Hotel:

    SPC 2009 - Mandalay Bay Hotel

    InfoPath Booth:

    (from left: Umut Alev - development lead, Peter Allenspach - group program manager, Rick Severson - test lead):

    SharePoint Conference - InfoPath Team Members

    InfoPath 2010 is well represented at this year's conference with a total of 5 sessions. The 1st session took place on Monday and was presented by Peter Allenspach and Bojana Duke from the InfoPath program management team.

    The InfoPath session drew big crowds:

    SPC 2009 - InfoPath Session Audience

    The session opened with an introduction to InfoPath 2010, followed by 3 feature demos which illustrated just how easy InfoPath 2010 makes it for Information Workers to create their own solutions without reliance on IT departments. Some highlights below -

    InfoPath 2010 Overview:

    InfoPath 2010 Overview

    Demo 1: Customizing a SharePoint list form

    In this demo, Peter and Bojana walked through a real Microsoft internal College Recruiting scenario. Employees use SharePoint lists to sign up for recruiting trips. Bojana wowed the audience by taking the Recruitment Trip list form and customizing it in InfoPath in under a minute!

    Peter and Bojana then went on to show how this form could be further enhanced and customized. Our new out of the box rules were used to add data validation and to conditionally show or hide sections in the form. A data connection to the Colleges list was added to pull details about the colleges into the recruiting trip sign-up form. The form layout was customized using our new pre-built layout tables and themes. They then showed how in a single click, the form could be published to SharePoint. Not only that, but they then showed how the list, including the customized form could be taken offline in SharePoint Workspace.

    Last but not least, they opened the form in Firefox showing that you can use your browser of choice to fill out your forms.

    Before Form:

    SharePoint List - Default Form

    After Form:

    SharePoint List - Customized InfoPath Form

    Offline Form in SharePoint Workspace:

    SharePoint WorkSpace - Offline Form

    Demo 2: Creating Mashups using the InfoPath Form Web Part
    The 2nd demo took the Recruiting scenario to the next level. In this demo, Bojana created a simple portal page with 2 Web Parts, the Recruiting trip list and the new InfoPath Form Web Part. In only a few clicks, she connected the 2 Web Parts. Now when she selected an item in the recruitment list, the details for that trip were displayed in an InfoPath form.

    Portal Page:

    InfoPath Form Web Part

    They concluded the 2nd demo by showing that both SharePoint solutions and InfoPath forms are truly portable and reusable. The site was saved as a template (WSP) and a new site was created from this template. The SharePoint list, portal page and InfoPath form were fully functional on this new site.

    Demo 3: Office Business Applications: Procurement scenario
    In this final demo,  Peter and Bojana showed the audience how InfoPath helps IT departments develop full Office Business Applications on the SharePoint platform. They used a procurement scenario to demo these capabilities. In this scenario, an employee submits a request to purchase a new laptop computer. The solution used an InfoPath form that connects to a vendor database, that brings in details about the goods you can purchase.

    Procurement Form:

    Procurement Form

    This type of application can be built in SharePoint Designer, using web part pages to create the user experience. The data can be stored in form libraries, SharePoint lists, and external systems using Business Connectivity Services. If InfoPath rules don’t do the job of defining the desired form behavior sandboxed or full trust code can be added to the forms. SharePoint workflows can be used to send e-mail notifications and track status. And once you’re all done, you can package your application so it can be tested and eventually deployed to the production servers.

    Procurement Portal Page:

    Procurement Portal Page 

    This first session set the stage for the remaining InfoPath sessions of the week:

    • Building Applications with InfoPath and SharePoint Designer (this session took place on Tuesday - more details to follow)
    • Performance Best Practices for Forms Applications
    • InfoPath 2010: Form Design Best Practices
    • Form-Driven Mashups using InfoPath and Forms Services 2010

    Stay tuned for more updates from Las Vegas!

  • Microsoft InfoPath 2010

    InfoPath-Related Blogs: OPML Compilation

    • 4 Comments

    We promised, and here it is: the OPML compilation of RSS feeds of bloggers that write about InfoPath. Just download the file and import it into your favorite news aggregator.

    Sneak peek:

    Cheers!
    Alex

  • Microsoft InfoPath 2010

    Sorting Repeating and Tabular Data

    • 4 Comments

    InfoPath is a great way to easily gather and present XML data to the masses. But what about efficiently presenting a massive amount data? Tons of data (e.g., a list of hundreds product names) usually find their ways into lists that we’ll find on SharePoint, in a database, or just sitting in an XML file. Controls like Repeating Sections and Tables are useful mechanisms for displaying lists of data. But their usefulness is limited to how efficiently the user of your form can find and work with such large lists of data. An easy solution to effectively present large lists of data to your users is through sorting that data.

    No Sorting Options in InfoPath
    Try scouring the Repeating Table or Repeating Section controls’ properties dialogs for anything related to “sort”. Sorry to say, you’ll come up empty handed. That’s why we thought you’d find this blog entry handy. Our goal is to show you how to sort any repeating data and to do so in many different ways: sort by string, sort by number, sort ascending or descending, and even sort by different fields (or columns) in the repeating data. What we’ll show you, in both the code and the design of the view, is designed to be browser-compatible. This means you can publish this form template to a SharePoint server running Forms Services 2007 and fill out the form in a Web browser. Let’s get started.

     

    Figure 1: Filling out the SortingPeople sample form template

    The sample form template is attached; download the ZIP to your desktop, expand it, then right-click the XSN and select "Open in Design Mode". This sample requires InfoPath 2007, and will work in the browser when published to InfoPath Forms Services.

    The View for the SortingPeople Form Template
    To show you how to sort data in your form, we’ll use a concocted example to sort a list of people. As you can see in Figure 1, there are various options to sort the data. Clicking the “Sort” Button triggers the sort otherwise the data is not sorted automatically (more on this later). You can also sort by clicking any of the “Sort by this column” Buttons in the header and footer of any column. There are three columns in the Repeating Table representing our repeating data: Last Name, First Name, and Age. (The string data type is used for the first two columns and an integer data type for the last column.) In Figure 1, we’ve filled out the form with names of famous architects. (Their ages are fictitious.) While we’re not working with enough data to really justify a sort, this example is simply for demonstrative purposes. As you might expect, we can sort the Repeating Table data by any column and by any direction (ascending or descending). At any time we can change the existing data or even add or remove rows. But we would need to invoke the sorting functionality to put things into place again.

    The Data Source for the SortingPeople Form Template
    To begin designing this form template we started with controls and the data source. We inserted a Repeating Table control and renamed its data source groups and fields to map with our people example. The main data source is shown in Figure 2. To accommodate the various sorting options that we expose via controls at the top of the view (e.g., the Sort By Drop-Down List Box), we’ve added attribute fields under the SortingPeople document element. These attribute fields remember, for example, whether we’re sorting by the Last Name or the Age column.

    Figure 2: Data source for the SortingPeople sample form template

    Considerations When Sorting Data
    Now we’ll look at how we implemented sorting functionality behind this form template. This is accomplished through C# code behind the form. While we could have opted for an easier XSL-based implementation to sorting data, it would not have been compatible with Forms Services. So we’re left to actually sorting the data. There are advantages as well as disadvantages to our approach. Sorting the data is preferred when you want to persist the sorting in the saved or submitted form. While the initial cost is much higher to sort the data in the data source instead of the view, there is much less processing that occurs on subsequent visits to that data because it will already be sorted. If your form template has multiple views, switching to and from a view that performs an XSL sort is very expensive. On the contrary, a sorted data source adds no additional processing requirements on view switches. A final reason why you may want to sort the data in the data source instead of the view: submitting sorted data to a database or Web service may be optimal (or even a requirement) for that backend system.

    Sorting Data with C# Form Code
    To best understand how we designed the code behind form template to support sorting, we’ll be talking about its C# form code and how it interacts with the main data source. Let’s start by looking at some of the supporting form code that will make it easier for us to implement the sort feature. The properties are used within the sort itself to read the options at the top of the view about how to sort the data. The methods are very useful helpers that we use throughout our sample code.

    /// <summary>

    /// Returns the "Sort By" Drop-Down value.

    /// The value returned by this property MUST match with an item within the Repeating Table.

    /// </summary>

    private string SortBySelection

    {

        get { return GetValue("@my:SortBy").Replace(" ", string.Empty); }

    }

     

    /// <summary>

    /// Does the user want the SortBy by number (true) or string (false)?

    /// </summary>

    private bool SortAsNumber

    {

        get

        {

            return 0 == GetValue("@my:SortAs").CompareTo("number");

        }

    }

     

    /// <summary>

    /// Does the user want an ascending (asc) or descending (des) sort?

    /// </summary>

    private bool SortAscending

    {

        get

        {

            return 0 == GetValue("@my:Order").CompareTo("asc");

        }

    }

     

    /// <summary>

    /// Helper to wrap an int within brackets.

    /// </summary>

    /// <param name="intToWrap"></param>

    /// <returns></returns>

    private string WrapAsIndexer(int intToWrap)

    { return WrapAsIndexer(intToWrap.ToString()); }

     

    /// <summary>

    /// Helper to wrap a string within brackets.

    /// </summary>

    /// <param name="strToWrap"></param>

    /// <returns></returns>

    private string WrapAsIndexer(string strToWrap)

    { return "[" + strToWrap + "]"; }

     

    /// <summary>

    /// Helper to get an XPathNavigator's value.

    /// </summary>

    /// <param name="xpath"></param>

    /// <returns></returns>

    private string GetValue(string xpath)

    {

        return Root.SelectSingleNode(xpath, NamespaceManager).Value;

    }

     

    /// <summary>

    /// Helper to set an XPathNavigator's value.

    /// </summary>

    /// <param name="xpath"></param>

    /// <param name="value"></param>

    private void SetValue(string xpath, string value)

    {

        Root.SelectSingleNode(xpath, NamespaceManager).SetValue(value);

    }

     

    /// <summary>

    /// Helper to get the document element of the main data source.

    /// </summary>

    private XPathNavigator Root

    {

        get { return CreateNavigator().SelectSingleNode("/my:SortingPeople", NamespaceManager); }

    }

    Next, let’s take a look at the code behind all of the Buttons in our form template. We created these event handlers through each Button’s properties dialog. Their implementations are quite trivial. You can see that adding additional sorting columns to the Repeating Table is a simple task. If you wanted to add a column that doesn’t need to be sorted, there’s nothing to do beyond adding the column in the Table!

    public void SortButton_Clicked(object sender, ClickedEventArgs e)

    {     

        SortList();

    }

     

    public void LastNameSort_Clicked(object sender, ClickedEventArgs e)

    {

        SetValue("@my:SortBy", "Last Name");

        SortList();

    }

     

    public void FirstNameSort_Clicked(object sender, ClickedEventArgs e)

    {

        SetValue("@my:SortBy", "First Name");

        SortList();

    }

     

    public void AgeSort_Clicked(object sender, ClickedEventArgs e)

    {

        SetValue("@my:SortBy", "Age");

        SortList();

    }

    Now the million dollar question: what’s behind the SortList method? Let’s look and then we’ll explain how it works.

    /// <summary>

    /// Bubble sorts the list of people.

    /// </summary>

    private void SortList()

    {

        string sortBy = SortBySelection;

        string itemsToSort = "my:People/my:Person";

        System.Globalization.CultureInfo currentThreadCulture =

            System.Threading.Thread.CurrentThread.CurrentCulture;

     

        int numPeople = Root.Select(itemsToSort, NamespaceManager).Count;

     

        // basic bubble sort implementation

        for (int i = 1; i < numPeople; i++) // xpath is 1-based

        {

            for (int j = i + 1; j <= numPeople; j++) // keep j ahead of i; we can index [numPeople]

            {

                // swap (i,j) if necessary

                string iValue = GetValue(itemsToSort + WrapAsIndexer(i) + "/my:" + sortBy);

                string jValue = GetValue(itemsToSort + WrapAsIndexer(j) + "/my:" + sortBy);

     

                // Do we sort by number or string?

                if (SortAsNumber)

                {

                    int iNum, jNum;

                    if (!Int32.TryParse(iValue, out iNum) || !Int32.TryParse(jValue, out jNum))

                    {

                        // Let InfoPath take care of the invalid datatype with its own validation, we'll keep sorting the rest

                        continue;

                    }

     

                    if ((SortAscending && iNum > jNum) || (!SortAscending && iNum < jNum))

                    {

                        Swap(itemsToSort + WrapAsIndexer(i), itemsToSort + WrapAsIndexer(j));

                    }

                }

                else // SortAsString

                {

                    if ((SortAscending && String.Compare(

                        iValue, jValue, true /*ignoreCase*/, currentThreadCulture) > 0)

                        || (!SortAscending && String.Compare(

                        iValue, jValue, true /*ignoreCase*/, currentThreadCulture) < 0))

                    {

                        Swap(itemsToSort + WrapAsIndexer(i), itemsToSort + WrapAsIndexer(j));

                    }

                }

            } // end inner-for

        } // end outer-for

    }

    Analyzing the C# Form Code
    Let’s break down what we’re doing in this SortList method. First we get the column to use for sorting, the XPath to the repeating group that we want to sort, and the culture of the thread so we respect the current locale when sorting. Next we get the number of people that we’ll be sorting. We need this number because we’ll use it for our bubble sort implementation.

    The two nested for-loops implement the bubble sort algorithm. We chose bubble sort because of its simplicity and for demonstrative purposes. (We’d recommend you use the most efficient sorting algorithm based on your requirements.) The variables i and j iterate through the people. We use the iValue and jValue variables to select the data pointed at by i and j to determine if a swap is necessary as part of the sort loop.

    Next, we have an if-else statement that checks if the sort is by string or by number. A sort by number will attempt to parse out 32-bit integer values from the iValue and jValue fields. If the parse fails for any reason, we skip this specific comparison and continue trying to sort the rest of the data. Once we have integers, we do a simple comparison and swap if needed. If we’re sorting by string instead of numerical value, we use the static .NET library String.Compare method to make a culture sensitive comparison. A swap is performed if it’s necessary. (Note that we could have combined some code in the SortList method to make it more compact. We left the structure of the code unoptimized for maximum readability.)

    The last bit of code we have not yet revealed is the Swap method. This method, as its name suggests, simply swaps the positions of two XPathNavigator objects as identified by their XPaths. (An XPathNavigator is a pointer into an XML tree of data. You can read more about the XPathNavigtor class on MSDN.)

    /// <summary>

    /// Swaps two XPathNavigators at xpath1 and xpath2.

    /// </summary>

    /// <param name="xpath1">First XPath.</param>

    /// <param name="xpath2">Second XPath.</param>

    private void Swap(string xpath1, string xpath2)

    {

            XPathNavigator item1 = Root.SelectSingleNode(xpath1, NamespaceManager);

            XPathNavigator item2 = Root.SelectSingleNode(xpath2, NamespaceManager);

     

            // Make a copy of item1

            XPathNavigator item1Clone = item1.Clone();

            // Move item2 to item1

            item1.ReplaceSelf(item2);

            // Make the original item2 be item1 that we cloned earlier

            item2.ReplaceSelf(item1Clone);

    }

    Sorting Automatically
    One of the things you might ask is why we decided against sorting the data automatically. The most important reason is user experience and then followed by form responsiveness. Think about what would happen if the Repeating Table rows sorted themselves whenever data changed that required a sort. Say you were entering data into a new row. You start by typing a person’s last name and then either hit tab or click into the First Name field. If the form is sorting by the Last Name field, the row may have jumped to another location relative to the other rows in the Repeating Table! You would expect that you could fill in all of the data for a new row before it sorts itself. There are also other weird cases that automatic sorting would spoil. For example, you would not see a new row added within the middle of the Repeating Table. Why? As soon as you added it, it immediately jumped to the top (or bottom) of the Repeating Table as sorted data. Let’s consider for a moment why we didn’t automatically sort because of form responsiveness; for now let’s assume that we somehow worked out all of the kinks with the user model. Obviously the form will be less responsive in InfoPath, especially on a slow computer, with so much sorting. But the real problem is realized when filling out such an intense form template in a Web browser. Every time code runs while a form is filled out in a browser, the form data is posted back to the server for processing. Postbacks themselves can take several seconds or even minutes depending on many variables including the network connection speed as well as the client and server machines’ performance capabilities. As you can see, an automatically sorting form isn’t necessarily a better form.

    Hagen Green
    Software Design Engineer in Test

  • Microsoft InfoPath 2010

    Complex Data Validation

    • 4 Comments
    How do you test more than 5 parameters? How do you group parameters? One answer to both questions, is to have multiple validations in one statement. We'll look into these problems in detail in the case studies below.

    Case Study #1

    Problem: a form designer wants to use this logic:

    IF (State="Ohio" or State="Alabama" or State="Arizona" or State="Georgia" or State="Utah" or State="Idaho" or State="Iowa") THEN (fail...)

    Since the Validation UI only supports 5 statements, you run out of room before entering all of the tests.

    Solution: Put more than one test in a statement. If you aren't sure of the syntax, follow along.

    Enter the first three tests.

    Click [OK] to close the dialog. Notice that the syntax is displayed in this dialog:

    Click [Modify] and use this syntax.

    When you change the first column to "The expression", you will see how to refer to the field you are checking. This differs depending on if you are checking the current field or a different field. In this case, State is the selected field, so we can enter the validation like this:

    If you OK this and then come back to it, InfoPath will automatically break out the last 4 tests into separate statements. This makes it easier to see more of the conditions that are being evaluated.

     

    Case Study #2

    Problem: a form designer wants to use this logic:

    IF (State="Ohio" or State="Alabama") and TaxRate is blank THEN (fail...)

    Using just the default Validation UI, you can't group tests like this.

    Solution:  Put more than one test in a statement. Again, if you aren't certain of the syntax, enter the tests in the Validation dialog:

    Click [OK] to close. Note the syntax in this dialog:

    Click [Modify], and use the syntax shown in the Validation statements.

     

    Alternative Approach

    Another way to handle both of these scenarios is to use multiple validations:

    This will work and in some cases would be easier to follow (the 50 states could be listed and you could scroll the Validations).

    Performance may be better in one or the other, but that would depend on the logic you are validating.

    All of these statements are evaluated. There is not an implied "and" or "or" combining them. In this last example, if you were checking the "State = ...  OR TaxRate is blank", both would fail. You could check the number of errors and would get 2, even though only 1 error message would be shown (the first one).

    Jerry Thomas
    Software Design Engineer in Test

  • Microsoft InfoPath 2010

    IE7 is here

    • 4 Comments

    Our friends from the Internet Explorer team are celebrating a major milestone - the release of Internet Explorer 7. You all know about the great features it brings to browser users (security, performance, ease of use); you may have seen them first-hand by trying out their Release Candidates.

    You may be wondering - how does this affect InfoPath? From the first look, there shouldn't be much connection, but there is.

    InfoPath ‘s editing surface is built on top of Internet Explorer. This means that most things that you see when you fill out an InfoPath form are, really, just clever HTML elements. Internet Explorer 7 brings improved implementations - thus, InfoPath users will benefit from the IE7 install, too.

    Some specifics:

    • IE7 provides a windowless SELECT control, which brings better performance for InfoPath forms that use the Drop Down List Box, List Box, or Combo Box controls .
    • IE7 offers full type-ahead support for dropdowns: for example, if a dropdown contains {"apple", "banana", "orange"}, then typing "ba" with the focus on the control will take you to "banana". InfoPath inherits this perk.
    • Overall rendering performance is improved
    • Many InfoPath crashes are fixed

    This list is relevant for InfoPath 2007. InfoPath Forms Services will benefit just like any other web app.

    Bottom line: if your organization uses InfoPath, the returns on deployment of Internet Explorer 7 will be even greater! IE7 will be distributed as a public update; if you can't wait (and I personally couldn't - I downloaded the final release of IE7 the minute I found out it was available), get it here.

    Alex Weinstein
    Program Manager

  • Microsoft InfoPath 2010

    Move Up/Move Down

    • 4 Comments

    One stumbling block for developers coming up to speed on InfoPath is that the SDK documentation leads you to the edge of the XML cliff and then goes mysteriously quiet. For web developers who have programmed applications with the MSXML SDK for manipulating XML this isn’t a problem – they brought their parachute with them and happily jump off. For others, this can be a little intimidating.

    Here’s a good way to get started manipulating the XML DOM directly – let’s add “Move Up” / “Move Down” buttons to a Repeating Table so you can re-order the items.

    First off, let’s build the view:

    1. Fire up InfoPath 2003 and start a new blank form
    2. Insert a Repeating Table from the Controls task pane
    3. Delete the text box in the last column, and add two buttons in that cell instead
    4. Pull up the properties on first button and give it the label “5” and the ID “MoveUp”
    5. Pull up the properties on second button and give it the label “6” and the ID “MoveDown”

     At this point, you’re thinking “5 and 6???”

    1. Select both buttons (Click the first, and Ctrl+Click the second)
    2. On the Font drop-down on the toolbar, select Marlett. Then take a look at the buttons.

    (Sneaky, huh? Glyphs from this font are used by Windows to render all sorts of UI elements like the Minimize/Maximize Window buttons. This is a handy way to avoid having to use images for simple things like arrows.)

    Now that we have it looking pretty, let’s add the event handlers for the buttons. We’ll build on the logic from this blog entry to figure out which instance of the buttons was clicked.

    1. Pull up the properties on the first button and click Edit Code – paste the following into the editor:

    Sub MoveUp_OnClick(eventObj)

    ' Write your code here

     

       Dim oItem, oParent, oPrevious

      

       Set oItem     = eventObj.Source

       Set oParent   = oItem.parentNode

       Set oPrevious = oItem.previousSibling

      

       If Not ( oPrevious Is Nothing ) Then

             

              oParent.removeChild oItem

             

              oParent.insertBefore oItem, oPrevious

             

       End If

     

    End Sub

    The logic here is straightforward:

    • Grab the context node of the button (the row of the table, in our case)
    • If there is another item before the context node, remove the context node from the tree and re-insert it before the previous node
    1. Pull up the properties on the second button and click Edit Code – paste the following into the editor:

    Sub MoveDown_OnClick(eventObj)

    ' Write your code here

     

       Dim oItem, oParent, oNext

      

       Set oItem   = eventObj.Source

       Set oParent = oItem.parentNode

       Set oNext   = oItem.nextSibling

      

       If Not ( oNext Is Nothing ) Then

             

              oParent.removeChild oNext

             

              oParent.insertBefore oNext, oItem

             

       End If

     

     

    End Sub

    The logic here is similar:

    • Grab the context node of the button (the row of the table, in our case)
    • If there is another node after the context node, remove the it and re-insert it before the context node

    Almost done – let’s just use a little Conditional Formatting to disable the buttons when the item is the first or last in the list:

    1. Add a conditional for the first button which reads:

      if “The expression” “position() = 1” then Disable this control
       
    2. Add a conditional for the second button which reads:

      if “The expression” “position() = last()” then Disable this control

    Now try it out.

    As an aside, this was the author’s first foray into VBScript. Although I cut my teeth in Applesoft BASIC I’ve done most of my programming in C-style languages (C, C++, C#, Perl, Java). Did I do anything silly?

  • Microsoft InfoPath 2010

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

    • 4 Comments

    Part 5 of 5: The final function

     

    And the final function is

     

    function FixupSolutionXSN(

          inputDirectory,

          xsnInputName,

          outputDirectory,

          xsnOutputName,

          serviceURL,

          wsdlURL)

    {

          var XsnInputPath = Combine(inputDirectory, xsnInputName);

          var XsfInputPath = Combine(inputDirectory, "manifest.xsf");

          var XsfOutputPath = Combine(outputDirectory, "manifest.xsf");

     

          ExtractFilesFromXSN(XsnInputPath, outputDirectory);

          FixupXSF(XsfInputPath, XsfOutputPath, serviceURL, wsdlURL);

          MakeXSNFromFiles(inputDirectory, "manifest.xsf", outputDirectory, xsnOutputName);

    }

     

    Now the gentle reader has free reins to drive the code above to the helpful utility.

     

    Converting the script to managed code would be a good exercise as well.

     

     

  • Microsoft InfoPath 2010

    Auto height for sections

    • 4 Comments
    InfoPath forms are all about being dynamic, so it's important that the sections in your form grow and shrink appropriately. For example, if someone deletes an optional section from inside another section, the outer section should shrink accordingly.
     
     
    Of course, sections will grow/shrink by default after you insert them, but InfoPath will change it to a fixed size if you resize the section, since we don't want to disobey your command to be a specific size. So in the example above, the outer section will stay the same size even when the Notes section isn't there -- it will just have a bunch of white space in its place.
     
    The trick: Use "auto"
    If you resized a section by accident and want to return it to the default, just open its properties, switch to the "Size" tab, and type auto for the height. Now it will only be as big as it needs to be and never bigger.
     
    - Ned
  • Microsoft InfoPath 2010

    Add C# or Visual Basic to your existing form using VSTO

    • 4 Comments
    Have you ever created an InfoPath form to later discover that you have to write code in order to accomplish something you need?
     
    If so, you have one of two options:
     
    You can use VSTA to add managed code to your form.  It is included in the Office package, but it is turn off by default.  You must go the Add/Remove Programs and customize Office to install it.
     
    -- OR --
     
    You can use VSTO to add managed code to your form which is what this blog entry is about.
     
    When you create an InfoPath Form Template using Visual Studio 2005, you start with the Design a Form dialog.  On the left you’ll see:
     
     
    Choosing one of these options will allow you to create a project using an existing form template.  For example, if you wanted to use a form template from a SharePoint site, you would choose the second option.  You can also choose the last option to import an Excel workbook or a Word document as your form template.
     
    If you've selected an existing form template, you will get a message:
     
     
    If you've selected a form template that already had code behind it, the existing code will be removed from the new form template as well.
     
    VSTO will now create a project based on the form you've selected and you're ready to add code!
     
     
    - Gary
    Software Development Engineer
  • Microsoft InfoPath 2010

    Advanced server-side authentication for data connections, part 2

    • 4 Comments

    In the first part of this series I introduced the concepts involved in three tier authentication. Now let's drill into the details and work with some code.

     

    Using Office Single Sign-on  with individual mapping

     
    An Office Single Sign-on (SSO) application definition, can be set up in one of three ways:  individual, group, or group using restricted credentials.  An InfoPath form published to the server can use either of the first two.  However, in order to use individual credentials, the SSO database must contain a separate username and password for each user who connects to the form.  A typical server application would check whether the connecting user had credentials in the database, and redirect to a credentials management page when appropriate to allow the user to enter their credentials.  While InfoPath Forms Services does not do this generically for forms that use SSO, it’s possible to implement a solution for an individual form or a set of forms the same way an Office Server application would, by using the Pluggable SSO API.
     
    The general approach is to have users link to an ASP.NET page rather than directly to the form.  The ASP.NET page attempts to get the user’s credentials from the SSO database, and based on the result either redirects to the form or to a credential management page  which allows the user to input their credentials.
     
    Enough talk.  Let’s get our hands dirty.
     
    My code assumes that you have defined an SSO application definition called MyApp and that the application is set up to use individual credentials.  I also assume that that have an administrator-approved form template called myform.xsn activated on the site collection, and that the form uses one or more data connections that reference the MyApp application.
     
    In order to use SSO to make the data connection, you must be using data connection settings in a UDC file on the server.  To add the reference to the MyApp app definition, you add an Authentication element to the UDC file.  The authentication element must be the last subelement of the ConnectionInfo element, and it looks like this:
     
    <udc:Authentication>
      <udc:SSO AppId="MyApp" CredentialType="NTLM"></udc:SSO>
    </udc:Authentication>
     
    To create the redirector page, the first thing is to add a new ASP.NET page to the root site of your SharePoint server.  Find the home directory of your root site by opening up Internet Services Manager and checking the Home Directory page of the properties page for the web application.  Open this web in Visual Studio and add a new ASP.NET page.  In the properties  for the page, enable session state.  Finally, add a reference to the Microsoft.SharePoint.Portal.SingleSignon namespace.
     
    Once this is done, the new page should look like this:
     
    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="SingleSignonRedirector.aspx.cs" Inherits="SingleSignonRedirector" EnableSessionState="True" %>
    <%@ Import Namespace="Microsoft.SharePoint.Portal.SingleSignon" %>
     
    Open the code file for the page, and add a using statement for the SingleSignon namespace
     
    using Microsoft.SharePoint.Portal.SingleSignon;
     
    The code itself is relatively straightforward.  Start by using the pluggable API to get a reference to the installed SSO provider.
     
    ISsoProvider provider = SsoProviderFactory.GetSsoProvider();
     
    (this call will fail if no provider is installed, or if the Single Signon service is not running)
     
    Your page will run under the credentials of the user attempting to access the form, so when you call GetCredentials, SSO will return a credential for that user, or throw SingleSignonCredsNotFoundException if the credential does not exist.
     
    try
    {
       SsoCredentials credentials = provider.GetCredentials("MyApp");
    }
    catch (SingleSignonCredsNotFoundException)
     
    In the event that the credentials are not found, you can get the URL of the credentials management page for the installed provider.
     
    Uri CredentialsManagementUrl = provider.GetCredentialManagementURL("MyApp");
     
    Now, at this point you could simply redirect to the credentials management URL.  However, you would miss part of the magic of the credentials management page.  The credentials management page supplied with the Office single Sign-on provider will redirect back to the referring page once the user has entered valid credentials.  I chose to handle this by presenting a link to the user to allow them to click through to the credentials management page.
     
    Response.Write("<P>Before you can access this form, you must enter credentials to access backend data.</P>");
    Response.Write("<P><A href=\"" + CredentialsManagementUrl.ToString() + "\">Click here to enter your credentials</A></P>");
    Response.End();
     
    An alternate approach could be to add the HTTP referer header to the response before performing a redirect.  Either way, once the user has entered their credentials, the redirector page will be called again.  This time the GetCredentials call will succeed, and the page will redirect on to the form.
     
    Here’s the complete code-behind for the page:
     
    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using Microsoft.SharePoint.Portal.SingleSignon;
     
    public partial class SingleSignonRedirector : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            ISsoProvider provider = SsoProviderFactory.GetSsoProvider();
            try
            {
                SsoCredentials credentials = provider.GetCredentials("MyApp");
            }
            catch (SingleSignonCredsNotFoundException)
            {
                Uri CredentialsManagementUrl = provider.GetCredentialManagementURL("MyApp");
                Response.Write("<P>Before you can access this form, you must enter credentials to access backend data.</P>");
                Response.Write("<P><A href=\"" + CredentialsManagementUrl.ToString() + "\">Click here to enter your credentials</A></P>");
                Response.End();
            }
            catch (Exception ex)
            {
                Response.Write("<P>Single Sign-on returned an error:  " + ex.Message + "</P>");
                Response.End();
            }
     
            // Good to go - on to the form
    Response.Redirect( "http://myserver/formservertemplates/myform.xsn?openin=browser" );
           
        }
    }
     
    Getting jiggy with it
    For a real-world application, there are a few more things I might do to this page to round out the implementation.  Depending on the needs of the specific application, one or more of the following might apply:
     
    • Loop through multiple Application IDs to allow the user to enter credentials for each
    • Attempt to log on the user using the SSO credentials to verify that the credentials are valid and have not expired
    • Use this code in a page which hosts the form in question using the XmlformView control
    • Create a generic page which takes the URL to the form and the Application ID as query parameters
    With a little bit of ingenuity, you can use this approach to create a seamless end-to-end experience to satisfy any scenario.
     
    In my next and final post in this series, I'll talk about how to use a web service proxy for authentication. Stay tuned!
     
    - Nick
    Program Manager
  • Microsoft InfoPath 2010

    Browser Forms with Spell Check

    • 4 Comments
    With InfoPath Forms Services, you can take powerful InfoPath forms, and allow users to fill them out by using a browser. This enables your forms to reach more customers than ever before. Many Office users have been enjoying the convenience of spell check in Word and InfoPath. To enable this valuable feature for browser forms, we recommend pointing your customers to an Internet Explorer extension called ieSpell. It will check the spelling in your document, just like you would expect it to; you even get to store your personal word list or (clever!) point ieSpell to a Microsoft Office dictionary.
     
    After filling out a form, hit the ieSpell button and it pops up a dialog, similar to the Microsoft Office spell check. If you want to know the meaning of the word, the thesaurus is just a click away.
     
     
    Installing the program is quick and easy. Download from here (free for non-commercial use). When you're done, you will see a new button in the IE toolbar, as well as a new Tools menu item.
     
     
    If you are interested to learn more about ieSpell and other browser extensions, take a look at this article from the Internet Explorer team blog.
    Pradeep Rasam
    Program Manager
  • Microsoft InfoPath 2010

    InfoPath Trick to Localize a form in a single view

    • 4 Comments

    TRICK: Localized form in a single view

    Applies to: Microsoft Office InfoPath 2003 SP1

    Need the same form in many languages?  Here’s a trick that’s easier than multiple views.

    Summary

    By taking advantage of new SP1 features, there’s a simple way to create a multi-language view without duplicating bindings.

    I have used a secondary data source with read-only borderless fields as labels for the view.  This secondary data source is populated by an XML File Data Connection that grabs a file in the LabelsLanguage form library.  This form lib populates a drop-dom, changes of this update the aux-dom and refresh the view.

    There are 2 buttons for adding new languages and editing the current labels of the form.  These pop up a second solution.  To add a new language, just fill out the form and submit.  Look at one of the existing languages for examples.  If you see a typo in your language, feel free to correct it and save.

    To work with button labels, manually update the view using xsl:value-of elements.  Otherwise, use the workaround that I have in the screenshot.

    Known issues:

    • If you update a language on the fly, you need to force IE to always update the cache so you will get the drop-down changes.
    • Some flashing when changing the language.

    Example

    Here’s a sample of what it might look like:

    Picture with a language drop down selection 

    Form Code


    public void ChangeLanguage(DataDOMEvent e)
    {           
          if (e.IsUndoRedo) return;
          if (e.Operation.ToUpper() == "DELETE") return; //handle double notifications
     
          // Generate the new file name from the drop-down
          string strFileName = (string)e.NewValue; //from dropdown english.xml
          XMLFileAdapter2 xfaLabels = e.XDocument.DataAdapters["Labels"] as XMLFileAdapter2;
          string strCurrentUrl = xfaLabels.FileURL; //from adapter http://server/site/francais.xml
          string strBaseUrl = strCurrentUrl.Substring(0,strCurrentUrl.LastIndexOf("/")); // http://server/site
          string strCurrentFileName = strCurrentUrl.Substring(strCurrentUrl.LastIndexOf("/")); // francais.xml
          string strNewUrl = strBaseUrl + "/" + strFileName;          // http://server/site/english.xml
          xfaLabels.FileURL = strNewUrl;
     
          // the drop-down refreshes everything
          xfaLabels.Query();
          (e.XDocument.DataAdapters["Languages"] as SharepointListAdapter).Query();
    }
     
    public void AddLanguage(DocActionEvent e)
    {
          string strLanguagesFormUrl = "http://your-forms-url/template.xsn";
          thisApplication.XDocuments.NewFromSolution(strLanguagesFormUrl);
          (e.XDocument.DataAdapters["Languages"] as SharepointListAdapter).Query();
    }
     
    public void EditLabels(DocActionEvent e)
    {
          XMLFileAdapter2 xfaLabels = e.XDocument.DataAdapters["Labels"] as XMLFileAdapter2;
          thisApplication.XDocuments.Open(xfaLabels.FileURL, 1);     
    }
     
  • 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 );

Page 6 of 12 (298 items) «45678»