Reputation: 117
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
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
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
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
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. Usuallyname
andid
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