4219 Views // 0 Comments // Not Rated

InfoPathology - Part 7 - Popup Error Validation

One of the nicest things about InfoPath is that it adds some pizzazz to otherwise boring controls. It'll outline textboxes as you mouse over them, shade sections and tables, and a host of other "pretty" things that set InfoPath apart form Win Form and Web Apps. One of the nicest of these nice-to-haves is the implicit runtime form validation formatting. This is pretty much a build-in implementation of the Win Form's error provider, without all the configuration.

What this will do for you is outline the control in red (called a screen tip), and provide a descriptive tool tip for the user. Depending on the data type and formatting you have set up on the control, this happen automatically when the user populates it with invalid data. You can even setup conditional Boolean validation, write code behind the validation event, and customize the tool tip and popup message text.

Although this is great for quick and easy control validation, it does not quite go far enough. I have created forms that use four, five, six, and more controls strung together to perform complex calculates based off one another's values. In this case, if the user enters bad data into the first control, then you can be left with half a dozen red-outlined textboxes and your form will look like a battle zone!

Also, you cannot depend on the users to enter data in the implied order. So if bad data is entered in the first box, and then more garbage is put into a fourth box, you may have any number of textboxes pop up in a daisy chain of messy validation You will then have to deal with forms submitted with values such as "NaN," "Infinity," or "#DIV" for numbers.

What I came up with is a clean way to handle data validation, isolating each control so that bad data does not matriculate itself though your form. What this does is outline the control in red and popup a messagebox at the same time, giving the user a nice visual representation of the error situation. Then, it will reset the control back to its original value so that the user can simply try again. Here's how to implement this:

  1. Write the validation method:

    Code Listing 1

    1. private bool IsValidNumber(string xPath, object oldValue, string controlName)
    2. {
    3. //initialization
    4. int notUsed;
    5. bool result = true;
    6. string text = thisXDocument.DOM.selectSingleNode(xPath).text;
    7. //test number
    8. if (!double.TryPrase(text, out notUsed))
    9. {
    10. //error message
    11. MessageBox.Show("Please enter a numeric value for " + controlName + ".", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
    12. //reset value
    13. thisXDocument.DOM.selectSingleNode(sXPath).text = oldValue;
    14. result = false;
    15. }
    16. //return
    17. return result;
    18. }
  2. Create the following OnAfterChange event handler for the textbox created in Step #1.  (See a future blog entry for descriptions of the calls regarding recursive events.)

    Code Listing 2

    1. [InfoPathEventHandlerMatchPath = "/my:myFields/my:txtTest", EventType = InfoPathEventType.OnAfterChange]
    2. public void txtVendor1Bid_OnAfterChange(DataDOMEvent e)
    3. {
    4. //block event for sorting
    5. if (!this._sortingEventBlocker)
    6. {
    7. //block recursive event firing
    8. this._recursiveEventCounter++; //these are global variables
    9. if (!this._recursiveEventFired)
    10. {
    11. //test for numeric value
    12. this._recursiveEventFired = true;
    13. if (this.IsValidNumber("/my:myFields/my:txtTest", e.OldValue, "the test amount"))
    14. {
    15. //set this amount if this is the selected bid
    16. thisXDocument.DOM.selectSingleNode("/my:myFields/my:txtTest").text = e.NewValue;
    17. }
    18. //continue blocking recursive events
    19. this._recursiveEventCounter += 2;
    20. }
    21. }
    22. //allow recursive event firing
    23. if (this._recursiveEventCounter == 4)
    24. {
    25. this._recursiveEventCounter = 0;
    26. this._recursiveEventFired = false;
    27. }
    28. }

And there you have it. If the user enters data that violates the basic type of the textbox, InfoPath will outline it according to the formatting. Then, the custom validation in our IsValidNumber method will pop up a descriptive error message to tell the user the problem and the control that needs to be updated. Finally, in the case of an error situation, it will reset the value back to the original number so that the user doesn't have to go all over the form to fix the mistakes that will propagate though the other computed fields.

1 Tag

No Files

No Thoughts

Your Thoughts?

You need to login with Twitter to share a Thought on this post.