Partager via


Powerful Declarative Logic: Phone Number Parsing

When entering phone numbers in InfoPath, you can validate that it is a phone number easily enough (Data Validation->field1 “matches pattern” Phone number), but what do you do if the input does not match that pattern? Asking users to exactly enter the format “(000) 000-0000” may be a little constraining. Therefore, you may want a rule so that any combination of spaces, dashes, parenthesis and 10 digits will be reformatted nicely.  Below I will describe how to do this in a rule, although you could do the same in business logic. 

For the rule’s action, you would want to use translate, substring and concat functions.  Logically, as your first action you would translate to remove all unwanted characters (spaces, dashes and parenthesis).  Then, as your second action substring and concat everything. 

However, you cannot break it into two actions.  When the translate is executed, it changes the text field.  InfoPath immediately reruns the rule on that field (even before the rest of the actions are run from the first time).  For the second run of this rule, the conditions will all pass (as you would have a number like “0123456789” due to the translate that already happened), and the translate action would be run again.  This will happen repeatedly and causes a recursion error. 

Therefore, you would need to do this all in one action (the rule will be rerun here, but the conditions will not pass since it will match the phone number pattern).

On your text box, you will need:

1. One condition with 3 parts:

- Field “does not match pattern” phone number “and”

- Without the “()- “ characters, it has length 10:
“The expression” string-length(translate(., "()- ", "")) = 10 “and”

- There are no characters other than digits and “()- “ characters
“The expression” string-length(translate(translate(., "()- 0123456789", "")) = 0

2. One action that removes (), - and spaces; takes substrings; and concatenates it all together at once:

Set a field’s value “.” to concat("(",substring(translate(., "()-", ""), 1, 3), ")", substring(translate(., "()-", ""), 4, 3), "-", substring(translate(., "()-", ""), 7, 4)))

And you're done! Note that this technique will work in InfoPath 2003 and 2007, and it is supported in browser-enabled form templates. Download the form template that has this trick implemented; make sure to save it to your desktop.

Nicholas LovellSoftware Design Engineer Alexei LevenkovSoftware Design Engineer

PhoneNumberFormatting.xsn

Comments

  • Anonymous
    November 13, 2006
    But you won't be able to input international phone numbers, right? If yes, that would be a terrible solution to implement in any place, because I just can't imagine any software that stores phone numbers where there isn't eventually a need to store internation phone numbers...

  • Anonymous
    November 13, 2006
    The comment has been removed

  • Anonymous
    November 13, 2006
    I agree, just validating international phone numbers is incredbly difficult. But at the end of the day, it is in almost all cases better to NOT validate at all than to be too restrictive in your validation. I just fear that blog posts like this will lead to more forms or apps with too restrictive validation logic. Let me just repeat: I think no one should reuse this example here in a real world app. I cannot imagine any scenario where you can rule out during dev time that someone will at some point want to enter an international phone number in your phone number field. I think it would be great if you would augment this post with a warning "Never use this in the real world, you will annoy your users to no end if you disallow entering international phone numbers".

  • Anonymous
    November 14, 2006
    The comment has been removed

  • Anonymous
    November 14, 2006
    Sorry, I should have tried it before starting to complain. If it doesn't validate, it actually looks great to me!

  • Anonymous
    August 09, 2007
    The real issue is that not all validation using regular expressions is acceptable by InfoPath. I use regexlib.com patterns for years in web apps. But the following is not acceptable according to InfoPath 2007. (?:([2-9]d{2}) ?|[2-9]d{2}(?:-?| ?))[2-9]d{2}[- ]?d{4} This regular expression will allow three US formats with  area codes 200-999: 5305551212 or (530) 555-1212 or 530-555-1212 I had to fall back to the following which still allows the following format, 530-555-1212 with area codes 200-999. [2-9]d{2}-d{3}-d{4} is accepted by InfoPath 2007. In order to provide richer validation and support for international phones, InfoPath 2007 needs to support these regular expressions. Dave

  • Anonymous
    June 19, 2008
    Hi, I have a requirement where in I do not want user to enter charecters other than Numbers, -, (,) Using what expression do I need to implement this procedure? Regards, Vipul Mehta

  • Anonymous
    June 08, 2012
    Too bad the form template is no longer available.

  • Anonymous
    June 12, 2012
    In the third rule for step 1, you typed the word 'translate' twice. As the screenshot and in the sample form, it should read " string-length(translate(., "()- 0123456789", "")) = 0 "

  • Anonymous
    October 15, 2012
    This works like a charm with one exception... Now the placeholder is missing and in its place "()-" waiting for data. How do I maintain the placeholder, or simply have nothing in the entry space?