Ku Jin Shin
Ku Jin Shin

Reputation: 117

jQuery validate plugin adding multiple .rules() function

Like I stated on the title, I would like to add multiple function .rules() to my script. When I tried this:

$("#braintree-payment-form").validate({});



    $("#month").rules('add', {
        required: true,
        regex: "(0[123456789]|10|11|12)",
        messages : {
            required: "Expiration date is required.",
            regex: "Invalid expiration date."
        }
    });
    $("#year").rules('add', {
        required: true,
        regex: "([0-9][0-9])",
        messages : {
            required: "Expiration date is required.",
            regex: "Invalid expiration date."
        }
    });


    $("#cardNum").rules('add', {
        required: true,
        regex: "(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})",
        messages : {
            required: "Credit card number is required.",
            regex: "Invalid credit card number"
        }
    });

Only the last .rules() applied, and also it applied to the first input element rather than corresponding id one.

Thanks in advance :)

Here is the form that I am currently using:

<form action="#" method="POST" id="braintree-payment-form">
    <p>
      <label>Card Number</label>
      <input type="text" size="20" autocomplete="off" name='number' id='number' data-encrypted-name="number"/>
    </p>
    <p>
      <label>CVV</label>
      <input type="text" size="4" autocomplete="off" name='cvv' data-encrypted-name="cvv" id='cvv'/>
    </p>
    <p>
      <label>Expiration (MM/YYYY)</label>
      <input type="text" size="2" data-encrypted-name="month" id="month" name = 'month' /> / <input type="text" size="4" data-encrypted-name="year" id="year" name='year' />
    </p>
    <input type="submit" id="submit" name='braintree'/>
  </form>

Upvotes: 2

Views: 8627

Answers (4)

tim peterson
tim peterson

Reputation: 24315

There is a way to extend the validator object to add multiple rules. See the documentation here.

var newRules = {name: {required: true}, email: {required: true} }; //your object of new rules

$.validator.addClassRules(newRules);

Upvotes: 0

bernaldani
bernaldani

Reputation: 1

Hi all I solve this way

$('#purchase_form').validate({
        rules: {
            name: {
                required: true
            },
            number: {
                required: true,
                minlength: 13,
                maxlength: 19
            },
            month: {
                required: true,
                regex: "(0[123456789]|10|11|12)"
            },
            year: {
                required: true,
                regex: "([0-9][0-9])"
            },
            cvv: {
                required: true,
                minlength: 3,
                maxlength: 4
            },
        },
        submitHandler: function (form) {
            $('#purchase_form').hide();
            $('#processing').show();

            braintree.encryptForm($(form));

            $.ajax({
                type: "POST",
                url: base_url+'items/purchase_direct',
                data: $(form).serialize(),
                dataType: "json",
                success: function (response) {
                    if(response.status == 'error')
                    {
                        $('#number_direct').attr('name','number');
                        $('#cvv_direct').attr('name','cvv');
                    }
                    else
                    {
                        $('#purchase_form').hide();
                        $('#processing').hide();
                        $('#purchaseconfirm').show();

                    }
                }
            });
            return false;
        }
    });

add the braintree.encryptForm($(form)); inside the submitHandler.. that makes the braintree removed there the input name. in the case it fails again I will add the input name again.

Don't forget to remove braintree.onSubmitEncryptForm('braintree-payment-form', optionalCallback);

sorry for my english..

Upvotes: 0

Cyberprompt
Cyberprompt

Reputation: 1

I have successfully been able to use the jQuery validator plugin with braintree.js. The first thing I had to do was download braintree.js to my local instead of the hosted version. I then edited the file where:

element.removeAttribute("name");

was located. I simply commented it out thus:

/*element.removeAttribute("name");*/

It's in the last line of the file.

I also put braintree's initialization before the validation script

var braintree = Braintree.create("<%=SESSION("ENCRYPTIONKEY")%>");
braintree.onSubmitEncryptForm('donation-form', null);

As you can see, I am integrating some server-side code for the encryption key, and I do not call any function after it does it's thing with the form.

I use a regular submit button which triggers both the validator and braintree.js. Braintree creates the new hidden inputs with the same name as the fields. jQuery validator validates normally as it only looks at the first instance of the input name. Then in the submitHandler method of jQuery validator I do the removal of the name attribute, but creating a new "name" attribute called "xname". This is because if braintree returns errors on their end, we have to allow the user to resubmit the form. I'll get to how that will work next.

submitHandler: function(form) {
// braintree has duplicated our fields as hidden encrypted.
// now change the name attribute from each field so it won't be submitted

$("input[data-encrypted-name]").each(function(){
$this = $(this);
var thisname = $this.attr("name");
$this.attr("xname",thisname);
$this.removeAttr("name");
}).promise().done(function(){ 
ajaxpost();             });                     

} // end submitHandler

The ajaxpost call is an $.ajax function which posts to a PHP file. This is a trick part, as I get the response from Braintree and create my own JSON with a "result" key. If the result is not "success" also, it will be either "error" or "invalid".

In the case of either "error" or "invalid" i then call a function which reinstates the original name of the fields.

    var reinstate = function(){
    // if the form has already been submitted, but braintree returns errors,
    // we have to reinstate the original field names.

    $("input[xname]").each(function(){
        $this = $(this);
        var thisxname = $this.attr("xname");
        $this.attr("name",thisxname);
        $this.removeAttr("xname");
    });
}

Now the user can try again. Hope this helps. I know this explaination is pretty hairy considering all the ajax and server side processing solutions I implemented.

tl;dr You have to stop braintree from removing the name attributes and then do it yourself right before submission.

Upvotes: 0

Sparky
Sparky

Reputation: 98748

Just a guess, since I cannot reproduce your problem from the limited code you've posted, but I'd say you forgot to include a name attribute on each input element. The jQuery Validate plugin requires a unique name on every input.

See the "Markup recommendations" section on the General Guidelines page:

"The name attribute is 'required' for input elements, the validation plugin doesn't work without it. Usually name and id attributes should have the same value."

<form id="braintree-payment-form">  
     <input type="text" name="month" id="month" data-encrypted-name="month" />
     <input type="text" name="year" id="year" data-encrypted-name="year" />
     <input type="text" name="cardNum" id="cardNum" data-encrypted-name="cardNum" />
     <input type="submit" />
</form> 

Otherwise, your code is working fine: http://jsfiddle.net/hc2Bj/2/

EDIT after OP posted HTML:

I also noticed you are targeting #cardNum in your jQuery, yet I do not see id="cardNum" anywhere in your posted HTML.

Upvotes: 2

Related Questions