Posted by DevExpert on February 16th, 2009
InfoPath is a great tool when you need to build simple data-entry forms. Although the tool is clearly limited when it comes to creating a rich user interface with complex controls, there are things you can do to enhance the experience if you’re creative.
One of the ways various applications collect data is through the familiar wizard-style interface. A wizard can be great if you need to collect a lot of information from user, but want to break it down into manageable chunks. At first glance, InfoPath does not support such a thing, as there isn’t a fancy wizard control like there is in ASP.NET. Luckily InfoPath allows us to create views, which provide a completely different display for the fields defined in the form. With a little code and finesse, we can successfully implement a wizard-style browser-enabled InfoPath form. The end result looks like the following:
The first thing to do is define the fields that are required in the form. For the sake of this post, I built a very simple New User Wizard with a few fields, but in the real world a wizard is better suited for collecting a lot of data:
Now that the fields are defined, a view needs to be created for each “page” of the wizard. In this case, I created 2 views in addition to the default view, and also renamed the default view to page1:
On the first page, I laid out the controls for the first page, and also included a Cancel button, Back button, and Next button. I really don’t need a Back button for the first page, but i kept it in there as a placeholder and just disabled it by adding a conditional format. In addition to the fields that the user needs to fill out, we have to perform our own data validation. The reason is the validation doesn’t fire until the form is submitted, and we need to perform incremental validation just to ensure the first page’s fields are filled out correctly. I’ll get to the code required to do this shortly, but for now I just added the errorMessage field, set the fill to transparent, removed the border, and disabled it:
Next, I created the second page of the wizard by cutting & pasting the first page and adding the appropriate fields:
Finally, I created the third page of the wizard, which for this scenario is just a summary page of previously filled-in data:
Now that the form UI is set up, we can start adding the rules and code to make it behave like a wizard. Since I like my code nice and pretty, I renamed all of my buttons to btnCancel1, btnBack1, btnNext1, btnCancel2, etc. For each cancel button, I added a rule to just close the form.
For the back button, we don’t need to validate the fields, so the code required to jump back to the previous page is straightforward. To switch views I used the SwitchView() method of the form’s ViewInfoCollection:
Next I needed to implement the “Next” functionality, but before we switch the view to the next page, the fields on the current page need to be validated. For this, I added the errorMessage field to each of the pages, and if the validation fails, I set the value of that field to the error message. To do the validation and to set the field, I created two wrapper methods: GetFieldValue and SetFieldValue:
Now for the Next buttons, I can verify data has been entered and if not, set the errorMessage field value:
The end result is something like this when an error occurs:
If all the data has been entered successfully, the last page is eventually visible:
Pretty slick, huh?