AngularJs Validation Directive

AngularJs Validation Directive

The Card Number Validation Problem

I worked on a Stripe integration for OctoPerf, our load testing tool during the past weeks.

Validating a credit card number is really complex. Thankfully Stripe comes with a JavaScript API to validate the various fields of a credit card. But an AngularJs integration is not that straightforward.

Note:

The method explained here can be used to validate the other fields of the credit card.

The Custom Directive Solution

We are going to create a custom directive that uses the Stripe JS to do the validation. The error messages are displayed via ng-messages.

Injecting Stripe

The first step is to inject Stripe. To do so we need to create a service that provides it:

app.service('Stripe', ['$window',
    function ($window) {
        return $window.Stripe;
    }
]);

Stripe is retrieved from the $window object. So we must include the Stripe Script in our HTML:

<script type="text/javascript" src="https://js.stripe.com/v2/"></script>.

The Directive

Then we create a custom validation directive:

app.directive('stripeCardNumber', ['Stripe', function(Stripe) {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function(scope, elm, attr, ctrl) {
            if (!ctrl) return;
            ctrl.$validators.cardNumber = function(modelValue, viewValue) {
                return Stripe.card.validateCardNumber(viewValue);
            };
        }
    };
}]);

Here we add our cardNumber validator to the enclosing controller and delegate the job to the function Stripe.card.validateCardNumber.

The HTML code

Finally on the HTML view we can create the following form:

<form name="cardForm" class="form-validation">
<input type="text" class="form-control" name="number" ng-model="card.number"
placeholder="{{'Card number' | translate}}" stripe-card-number required>

<div ng-messages="cardForm.number.$error" class="text-danger" role="alert"
     ng-show="cardForm.number.$touched">
    <div ng-message="required">{{ 'You need to enter a card number.' | translate}}</div>
    <div ng-message="cardNumber">{{ 'You need to enter a valid card number.' | translate}}</div>
</div>
</form>

Our stripe-card-number directive is added to the text input (we do not use a number input here).

Using ng-messages we can display an error message when the validation fails. The ng-message="cardNumber" value must match the name given in the stripeCardNumber directive ctrl.$validators.cardNumber. Ng-messages is a separate angular module. So we need to include the angular-messages script in our HTML and add ngMessages as one of our application dependencies.

Conclusion

We can easily do the same to validate the CVC:

ctrl.$validators.cvc = function(modelValue, viewValue) {
    return Stripe.card.validateCVC(viewValue);
};
<div ng-messages="cardForm.cvc.$error" class="text-danger" role="alert"
     ng-show="cardForm.cvc.$touched">
    <div ng-message="required">{{ 'You need to enter a Card Verification Code.' | translate}}</div>
    <div ng-message="cvc">{{ 'You need to enter a valid CVC.' | translate}}</div>
</div>

And a direct solution is to use existing AngularJs modules:

By - CEO.
Tags: Angularjs Open Source Github

Comments

 

Thank you

Your comment has been submitted and will be published once it has been approved.

OK

OOPS!

Your post has failed. Please return to the page and try again. Thank You!

OK