How to implement client side phone validation

Recently on CiviCRM irc and forum few people asked about adding client side validation for phone field. By default CiviCRM packages validate plugin, so this can be easily implemented with minor customization. Below is the example of validating US phone number on new contact form.


Index: templates/CRM/Contact/Form/Edit/Phone.tpl
--- templates/CRM/Contact/Form/Edit/Phone.tpl   (revision 37399)
+++ templates/CRM/Contact/Form/Edit/Phone.tpl   (working copy)
@@ -39,10 +39,10 @@
 <tr id="Phone_Block_{$blockId}">
-    <td>{$$}&nbsp;&nbsp;{ts}ext.{/ts}&nbsp;{$$blockId.phone_ext.html|crmReplace:class:four}&nbsp;&nbsp;&nbsp;{$$blockId.location_type_id.html}</td>
+    <td>{$$|crmReplace:class:"phoneUS"}&nbsp;&nbsp;{ts}ext.{/ts}&nbsp;{$$blockId.phone_ext.html|crmReplace:class:four}&nbsp;&nbsp;&nbsp;{$$blockId.location_type_id.html}</td>
     <td colspan="2">{$$blockId.phone_type_id.html}</td>
     <td align="center" id="Phone-Primary-html" {if $blockId eq 1}class="hiddenElement"{/if}>{$$blockId.is_primary.1.html}</td>
     {if $blockId gt 1}
        <td><a href="#" title="{ts}Delete Phone Block{/ts}" onClick="removeBlock('Phone','{$blockId}'); return false;">{ts}delete{/ts}</a></td>
\ No newline at end of file
Index: packages/jquery/plugins/jquery.civicrm-validate.js
--- packages/jquery/plugins/jquery.civicrm-validate.js  (revision 37399)
+++ packages/jquery/plugins/jquery.civicrm-validate.js  (working copy)
@@ -5,4 +5,13 @@
  *  To define phone validation for your site:
  *  jQuery.validator.addMethod("crm_phone", function(phone_number, element) { validation logic here }
+(function() {
+        jQuery.validator.addMethod("phoneUS", function(phone_number, element) {
+            phone_number = phone_number.replace(/\s+/g, ""); 
+            return this.optional(element) || phone_number.length > 9 &&
+                phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
+        }, "Please specify a valid phone number");
+        jQuery.validator.addMethod("postalcode", function(postalcode, element) {
+                return this.optional(element) || postalcode.match(/(^\d{5}(-\d{4})?$)|(^[ABCEGHJKLMNPRSTVXYabceghjklmnpstvxy]{1}\d{1}[A-Za-z]{1} ?\d{1}[A-Za-z]{1}\d{1})$/);
+        }, "Please specify a valid 5 digit zip code.");

I have tested this on CiviCRM v3.4 ( latest ). I hope this is helpful.





Having phone numbers in any random format makes deduping on phone fields difficult. I would love to see phone fields be more strict about what characters they allow (only numbers and dashes) and in what combinations (can't have two dashes in a row). This could happen on the client side for convenience, but would need to happen on the server side as well.

I haven't been able to implement this on my own site because hook_civicrm_pre and hook_civicrm_post don't get fired for phone objects. But I have heard some murmurs on the irc that others may be at work on this problem. Any news?

Hi Coleman - adding PRE & POST hooks where they are missing is pretty straight forward (and safe). I expect that even though we are in feature freeze Lobo would be OK with putting these into Phone create / add as appropriate

I was actually refering to hearing murmurs that others were at work on the phone normalization problem. Any word on that front?

And thanks for the tip about the hooks.