Thursday, May 20, 2010

JavaScript phone number reformatting, programmatically setting onblur

There are two problems I solved in a hurry last night that are apparently talked about a lot in JavaScript forums:
- Detecting something in a text input field that looks like a phone number. and remformatting it to the standard (xxx) xxx-xxxx layout
- Programmatically setting the onblur of a text input field


The first I attacked using regular expressions, naturally. For setting onblur, I wanted to have the function remember what input field called it, as if I had said something like:
<input type=text name=phone onblur=doSomething(this)>
"This" didn't come through if I did something like:
document.forms[0].phone.onblur=doSomething(this);
None of the discussion I found on various coding boards centered around capturing the caller, either. So I cheated and looked at how the DOM looked when onblur was set manually in the input field (first example). I exposed that with:
alert(document.forms[0].phone.outerHTML);
...which displayed something to the tune of:
function onblur() { doSomething(this) }
When I substituted that in programmatically, it worked! I'm interested in doing it this way because I'm working on a large form with a lot of fields to validate. Rather than just have the validator parse everything en masse at the end and surprise the user with all the mistakes he made, I'm going to give him little hints as he goes along by validation each element after it loses focus, highlighting any perceived mistakes in red. And I don't want to go back and edit each input field and add onblur=... to each of them, as it would look uglier in the code, and there's always the possibility that I'd miss a field or two.

Here is the HTML I ended up with as a beta test for the phone input validation:
<!doctype html>
<html><head><title>Phone number validation, set onblur programmatically</title></head>
<body>
<form>Phone number: <input type=text name=phone size=20 /></form>
<script>

/* Phone number validation, plus formatting
   Written by Curtis Autery, ceautery@gmail.com
   Released under LGPL Version 3                */

function usage() {
  alert("Type something that looks like a phone number (10 digit) in the\n"
      + "input field, then click out of the field. Phone number will be\n"
      + "reformatted to standard phone book layout, or background color\n"
      + "will change to red if the number can't be parsed.");
}

function validatePhone(el) {
  var phoneMatch = /^\(\d{3}\) \d{3}\-\d{4}$/;
  var phoneSimilar = /^\s*\(?(\d{3})\)?\s*[-\.]?\s*(\d{3})\s*[-\.]?\s*(\d{4}).*$/;
  el.style.background = 'white';
  if(phoneMatch.test(el.value)) { return true; }
  if(phoneSimilar.test(el.value)) {
    el.value = el.value.replace(phoneSimilar, "($1) $2-$3");
    return true;
  }
  el.style.background = 'red';
  return false;
}

document.forms[0].phone.onblur = function onblur() { validatePhone(this) };
usage();
</script></body></html>
Example parseable number formats:
6145551212
614-555-1212
614.555.1212
614 555-1212
(614) - 555 - 1212

Try it!
Phone number:

No comments:

Post a Comment