March 14, 2014

API Best Practices, Part III: Using JavaScript Validation

Posted by Craig Christenson Category IconTechnology

In this new blog series, 2Checkout explores the developments and features of its brand new Payment API, currently in BETA. To see the new 2Checkout Payment API BETA and use it as your new checkout, apply here.

In our last API best practices blog post, we explored some of the things we can do with HTML5 validation. In this post, we will walk you through the process of adding JavaScript validation to our Payment API form using a couple of different jQuery validation libraries.

A Good Starting Point

To start out, lets take a look at our example form and JavaScript to integrate with the Payment API.

/

As you can see from the code above, we are not validating any of the fields on this form before making the token request. The Payment API will perform it’s own validation and return an error if data is missing or in an incorrect format. Rather than blindly alerting an error message, let’s look at how we can utilize JavaScript validation libraries to provide the user with some real-time feedback, as well as format the data correctly before making the payment API token request.


Validation with Parsley.js

Parsley.js is a jQuery plugin that allows you to add JavaScript validation to your form fields by simply adding custom data attributes to the input elements. On our Payment API form, we want to insure that all required fields have been filled in and are in the correct format. With Parsley.js, this is as easy as adding the appropriate ‘data-attributes’ to the elements we want to validate.

First, let’s download the Parsley JavaScript library and pull it in after our jQuery reference.


Next, tell Parsley that we want to validate our form by adding the `data-parsley-validate` attribute to the form element.

At this point, we can also create a container to display validation errors to the user and instruct Parsley to utilize it by adding the `data-parsley-errors-container,` specifying the element ID for our container. For this example, let’s add the error container directly above the form element and specify the container’s ID as the value for the `data-parsley-errors-container` attribute. This will insure that the error messages are listed in our new container instead of below each form field.

We should also add some CSS in the `head` of the document to hide the error container and highlight the errors and error fields in red.

    

Now we can add our `parsley-data` attributes to each field to specify our validation rules. These attributes allow you to specify the rule(s) that the field value must conform to. For each of our fields, we want to insure that the value is not empty, only contains numbers and that the length of the value is correct. We show how we can modify our fields to include these additional Parsley attributes below.












Here we specified the `data-parsley-type` as “digits” to insure that only numbers were entered. We added the `data-parsley-length` attribute to specify the minimum and maximum length. We added `data-parsley-required` to indicate that each field cannot be empty. We also used the `data-parsley-error-message` to override the default error message and provide our own custom error message for each field.

Now all we need to do is check against the `parsley.validate()` function to determine if the fields are valid.

$('#myCCForm').submit(function(e){
  e.preventDefault();

  if ( !$('#myCCForm').parsley().validate()) {
    $('#infoArea').show();
  } else {
    $('#infoArea').hide();
    TCO.requestToken(successCallback, errorCallback, 'myCCForm');
  }
});

We can now test our new validation rules to insure that they are working properly.

Field Errors

Since the validation has been triggered, Parsley will automatically validate as we correct the data.

Field Corrections

To finish up the example, let’s safeguard the credit card input validation from other potential errors. The user might enter spaces or dashes with his or her card number, so we should strip out any non-numeric characters before we validate.

$('#ccNo').val($('#ccNo').val().replace(/[^0-9\.]+/g,''));
Complete Example

  
    
  
  
    
/



Validation and Formatting with Formance.js

Formance.js is a form validation library that started off as a fork of the popular jQuery.payment library. Because of it’s roots, Formance.js specializes in validating and formatting payment fields to insure that the user can only enter data in the correct format for the card number, CVC, and expiration date.

Using the example from the beginning of the article, let’s download the Formance JavaScript library and pull it in after our jQuery reference.


Now to integrate our payment form with Formance.js, we’ll set up the formatting when the document loads and run our validation on the submit event.

Formance requires the expiration month and year to be entered on the same field. Let’s start out by modifying our original payment form example from the beginning of this post to take the expiration month and year on a new ‘expDate’ input field. Since the Payment API is expecting this data in separate fields, we will keep hidden input fields for the ‘expMonth’ and ‘expYear’.

And let’s add some JavaScript to our form’s `submit` function to populate our ‘expMonth’ and ‘expYear’ from the data entered in our new ‘expDate’ input field.

$('#myCCForm').submit(function(e){
    e.preventDefault();

    var expiration = $('#expDate').val().replace(/ /g,'').split("/");
    $('#expMonth').val(expiration[0]);
    $('#expYear').val(expiration[1]);

    TCO.requestToken(successCallback, errorCallback, 'myCCForm');
});

Now we can set up the Formance.js formatting on our input fields when the document loads. This will utilize the formatters provided by the library to restrict the input fields to the allowed characters and length for each field type. This also improves the user experience by adding separators for the credit card and expiration date as they are being entered.

$(function($) {
    $("#ccNo").formance("format_credit_card_number");
    $("#expDate").formance("format_credit_card_expiry");
    $("#cvv").formance("format_credit_card_cvc");

    $('#myCCForm').submit(function(e){
      e.preventDefault();

      var expiration = $('#expDate').val().replace(/ /g,'').split("/");
      $('#expMonth').val(expiration[0]);
      $('#expYear').val(expiration[1]);

      TCO.requestToken(successCallback, errorCallback, 'myCCForm');
    });
});

The credit card formatter will add a space after every 4 digits entered, so we will need to strip those before we make our token request.

$('#ccNo').val($('#ccNo').val().replace(/ /g,''));

Next, let’s disable the submit button when the document loads and utilize the Formance.js validation for each field type to check the validation for each field and enable the submit if the field is valid.

$(function($) {
    $("input[type='submit']").prop("disabled", true);

    $("#ccNo").formance("format_credit_card_number");
    $("#expDate").formance("format_credit_card_expiry");
    $("#cvv").formance("format_credit_card_cvc");

    $("#ccNo").formance("format_credit_card_number").on( 'keyup, blur', function (event) {
        if ( $(this).formance('validate_credit_card_number') ) {
            $(this).removeClass('invalid');
            $("input[type='submit']").prop("disabled", false);
        } else {
            $(this).addClass('invalid');
            $("input[type='submit']").prop("disabled", true);
        }
    });

    $("#expDate").formance("format_credit_card_expiry").on( 'keyup, blur', function (event) {
        if ( $(this).formance('validate_credit_card_expiry') ) {
            $(this).removeClass('invalid');
            $("input[type='submit']").prop("disabled", false);
        } else {
            $(this).addClass('invalid');
            $("input[type='submit']").prop("disabled", true);
        }
    });

    $("#cvv").formance("format_credit_card_cvc").on( 'keyup, blur', function (event) {
        if ( $(this).formance('validate_credit_card_cvc') ) {
            $(this).removeClass('invalid');
            $("input[type='submit']").prop("disabled", false);
        } else {
            $(this).addClass('invalid');
            $("input[type='submit']").prop("disabled", true);
        }
    });

    $('#myCCForm').submit(function(e){
        e.preventDefault();

        var expiration = $('#expDate').val().replace(/ /g,'').split("/");
        $('#expMonth').val(expiration[0]);
        $('#expYear').val(expiration[1]);

        $('#ccNo').val($('#ccNo').val().replace(/ /g,''));
        TCO.requestToken(successCallback, errorCallback, 'myCCForm');
    });

});

If the validation fails on a field, Formance.js will add the ‘invalid’ class to the field. So for our example, let’s add some styling in the `head` of the document to highlight the invalid fields in red.


To finish up our validation, we need to ensure that we only make the token request in cases where all of the form fields are valid. We can accomplish this by altering our form’s `submit` function to check the input elements for the ‘invalid’ class and only make the request is if it is not present.

$('#myCCForm').submit(function(e){
    e.preventDefault();

    if ( $('input.invalid').length ) {
      alert('Please correct the fields in red.');
    } else {
      var expiration = $('#expDate').val().replace(/ /g,'').split("/");
      $('#expMonth').val(expiration[0]);
      $('#expYear').val(expiration[1]);

      $('#ccNo').val($('#ccNo').val().replace(/ /g,''));
      TCO.requestToken(successCallback, errorCallback, 'myCCForm');
    }
});

We can now test our validation to guarantee that any invalid fields will show up in red and the submit button is locked down until they are corrected.

Field ErrorsComplete Example




  


    

As this series continues, we will explore some best practices for making the Sale Authorization call server side. Come back to the 2Checkout Blog for more information on how to optimize your Payment API integration as well as read the latest tutorials on all things e-commerce.