How to set a single field to use Email or Phone validation?

I'm using jquery-validate plugin to perform client side validation, what I'm trying to accomplish is to give a single input the rules for email or phone number based on another input.

If the second input has the value for "email" then the rule for email is set true and the rule for phoneNumber is set to false and visceversa.

The problem I'm facing is that no matter what I do, the validation always asks for a valid e-mail address.

I'm not using the built in rules for email or phone, I made some of my own, here they are:

jQuery.validator.addMethod( "phoneNumber", function( phone_number, element ) {
            return this.optional( element ) || phone_number.length > 9 &&
                phone_number.match( /^[0-9]{7}|[0-9]{10}|\([0-9]{3}\)[0-9]{7}|\([0-9]{3}\)[\s\-]{1}[0-9]{3}[\s\-]{1}[0-9]{4}|[0-9]{3}[\s\-]{1}[0-9]{3}[\s\-]{1}[0-9]{4}$/ );
        }, 'Enter a valid phone number');

jQuery.validator.addMethod( "emailAddress", function( email, element ) {
            return this.optional( element ) ||
                email.match( /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ );
        }, 'Enter a valid e-mail address');

The way I'm assigning the rules is:

$(`#input1`).rules('add', {
     required: function(element) {
          if($(`#input2`).val() != '') return true;

          return false;
     },
     emailAddress: function(element) {
          if($(`#input2`).val() == 'email') return true;

          return false;
     },
     phoneNumber: function(element) {
          if($(`#input2`).val() == 'phone') return true;

          return false;
     }
});

So, the field is only required when the input2 has some value (working good), but no matter what option I select on input2 the validation always fail with 'Enter a valid e-mail address'.

I expect that when input2 has the value "email" the validation fails with 'Enter a valid e-mail address' and when the value for input2 is "phone" then fails with 'Enter a valid phone number'.

What I'm doing wrong?

Upvotes: 2

Views: 1518

Answers (1)

Sparky
Sparky

Reputation: 98738

Since you are completely swapping out the rules, I would write a handler that dynamically adds and removes the rules as needed.

$('#input2').on('keyup', function() {
    if ($(this).val() == 'phone') {
        $('#input1').rules('remove', 'emailAddress');
        $('#input1').rules('add', {
            phoneNumber: true
        });
    }
    if ($(this).val() == 'email') {
        $('#input1').rules('remove', 'phoneNumber')
        $('#input1').rules('add', {
            emailAddress: true
        });
    }
});

DEMO: jsfiddle.net/gk0e372j/

However, when nothing is typed into the #input2 field, the phone/email field (#field1) is still required and will accept anything, so you still need to decide how you want to handle that part, like what is your default position. Otherwise, you have shown no HTML and not explained why you are using .rules() to declare these.


Here is the same logic except it's declaring everything within the .validate() method and using the depends option.

$('#myform').validate({ 
    rules: {
        input1: {
            required: true,
            phoneNumber: {
                depends: function(element) {
                    return ($('#input2').val() === 'phone') ? true : false;
                }
            },
            emailAddress: {
                depends: function(element) {
                    return ($('#input2').val() === 'email') ? true : false;
                }
            }
        }
    }
});

DEMO 2: jsfiddle.net/wnpxh9cm/

Upvotes: 2

Related Questions