hollyquinn
hollyquinn

Reputation: 652

Angularjs Iterating through array with loop

Hi I am brand new to Angularjs and I have no clue what I'm doing. :) I need to be able to enter a credit card number in a textbox and then loop through to figure out what kind of credit card is being used and display an image for that credit card. So far I have the following code in my directive.

EDIT

app.directive('myDirective', function () {
return {
    restrict: 'E',
    scope: {
        cardNum: '=',
        cardType: '='
    },
    template: '<input ng-model="cardNum"></input>',
    replace: true,
    link: function ($scope, elem, attr) {
        scope.$watch('cardNum', function (val) {
            var regMap = [
                      { id: 'visa', reg: '^4[0-9]{12}(?:[0-9]{3})?$' },
                      { id: 'mastercard', reg: '^5[1-5][0-9]{14}$' },
                      { id: 'discover', reg: '^6(?:011|5[0-9]{2})[0-9]{12}$' },
                      { id: 'amex', reg: '^3[47][0-9]{13}$' }
                    ];

            angular.forEach(regMap, function(e){
                //The current element of the regMap sits in e which is an object `{id:, :reg}`
                if(e.reg.test(val)) {
                    //In the above if you test if the val(which is the input value) is matching the regex `e.reg` and if there is a match you pass the id of the object to a scope variable which was sent into the directive.
                    scope.cardType = e.id
                }
            })
        })

    }
};
});    

<div class="form-group">
                <div class="row">
                    <div class="col-lg-8">                            
                        <label for="CCnum" class="control-label">{{ 'CC_NUMBER' | translate }}</label>
                        <input id="CCnum" name="CCnum" class="form-control" title="Number on the front of your card" required="" type="text" ng-model="crdNo">
                        <!--ve-credit-card-no="vm.ccType"-->
                        <ve-credit-cardno card-num="crdNo" card-type="crdTy"></ve-credit-cardno>
                        {{crdTy}}
                        <div class="error_msg" ng-show="ccform.CCnum.$error.required && submit">Please enter a credit card number</div>

                    </div>
                    <div class="col-lg-3">
                        <label for="ccimg" class="control-label"></label>
                        <span ng-show="crdTy == 'visa'">visa<img id="ccimg" class="img-responsive" src="../../Assets/img/visa.png" /></span>
                        <span ng-show="crdTy == 'mastercard'">mastercard<img id="ccimg" class="img-responsive" src="../../Assets/img/mastercard.png" /></span>
                        <span ng-show="crdTy == 'discover'">discover<img id="ccimg" class="img-responsive" src="../../Assets/img/discover.png" /></span>
                        <span ng-show="crdTy == 'discover'">amex<img id="ccimg" class="img-responsive" src="../../Assets/img/amex.png" /></span>
                    </div>
                </div>
            </div>

Upvotes: 1

Views: 209

Answers (1)

alexsmn
alexsmn

Reputation: 1746

A quick solution. I'll improve it later if you want.

First add your html into a directive template if its not there at the moment.

Input in templete directive:

<input ng-model="cardNum">

Directive:

app.directive('myDirective', function() {
  return {
  restrict: 'E',
  template: '<input ng-model="cardNum"></input>',
  replace: true,
  link: function($scope, elem, attr) {
    $scope.$watch('cardNum', function(val){
      console.log($scope.cardNum)
    })
  }
 };
});

Now you can notice that every time you type something into your input, console.log will print the value, just take that value and do what you want with it.

Have a look here

UPDATE

Sorry for the wait.

First, you want to check the type of your card, by using regex expressions:

var regMap = [
  { id: 'visa', reg: /^4[0-9]{12}(?:[0-9]{3})?$/ }, 
  { id: 'mastercard', reg: /^5[1-5][0-9]{14}$/ }, 
  { id: 'discover', reg: /^6(?:011|5[0-9]{2})[0-9]{12}$/}, 
  { id: 'amex', reg: /^3[47][0-9]{13}$/ }
];

What you need to do now, is to check if your input is matching one regex from the above list.

scope.$watch('cardNum', function(val){
  //The value of the input sits in `val`
  angular.forEach(regMap, function(e){
    //The current element of the regMap sits in e which is an object `{id:, :reg}`
    if(e.reg.test(val)) {
    //In the above if you test if the val(which is the input value) is matching the regex `e.reg` and if there is a match you pass the id of the object to a scope variable which was sent into the directive.
      scope.cardType = e.id
    }
  })
})

The above pice of code, is watching the cardNum model, $watch('cardNum') and every time the value of cardNum changed the code inside the $watch scope will be run. Inside the scope there is a forEach loop which is taking each regex and tests the new value. If there is a match the some string is assigned to scope.cardType;

The directive scope:

scope: {
  cardNum: '=',
  cardType: '='
},

cardNum, will have the value of the input.

cardType, will be the type of your card.

<input ng-model="crdNo"></input>
<!--Notice how do you send the value of the input, and how you get the card type-->
<my-directive card-num="crdNo" card-type="crdTy"></my-directive>
{{crdTy}}

See how this works, here

Once you get the type of your card from crdTy which will be a string, you can then use them here:

span ng-show="crdTy == 'visa'">visa<img id="ccimg" class="img-responsive" src="../../Assets/img/visa.png" /></span>
<span ng-show="crdTy == 'mastercard'">mastercard<img id="ccimg" class="img-responsive" src="../../Assets/img/mastercard.png" /></span>
<span ng-show="crdTy == 'discover'">discover<img id="ccimg" class="img-responsive" src="../../Assets/img/discover.png" /></span>
<span ng-show="crdTy == 'discover'">amex<img id="ccimg" class="img-responsive" src="../../Assets/img/amex.png" /></span>

Upvotes: 2

Related Questions