Chris
Chris

Reputation: 27384

Auto capitalisation of input field using AngularJS

I have a directive on my input field for a licence key that validates it against a server side API. This works fine but I also want my licence key to auto hyphenate and appear capitalized.

I.e. a user typing in abcd1234qwer5678 will have it appear as ABCD-1234-QWER-5678. (I am first trying to get auto capitalisation working, then Ill try hyphenating)

I have tried a couple of things, firstly a watch within the controller like so

$scope.$watch('licenceKey', function (newValue, oldValue) {
    $scope.$apply(function () {
        $scope.licenceKey = newValue.toUpperCase();
    })
});

And I also tried using a second directive I applied to the input

myApp.directive('capitalize', function() {
   return {
     require: 'ngModel',
     link: function(scope, element, attrs, modelCtrl) {
        var capitalize = function(inputValue) {
           if(inputValue == undefined) inputValue = '';
           var capitalized = inputValue.toUpperCase();
           if(capitalized !== inputValue) {
              modelCtrl.$setViewValue(capitalized);
              modelCtrl.$render();
            }         
            return capitalized;
         }
         modelCtrl.$parsers.push(capitalize);
         capitalize(scope[attrs.ngModel]);  // capitalize initial value
     }
   };
});

The first one seems to do nothing and the second seems to replace my existing text after a short delay. My HTML is like so

<input type="text" name="licenceKey" ng-model="licenceKey" 
    ng-model-options="{ debounce : { 'default' : 150 } }" licence-key-validator />

What is the best way to achieve what I want and why am I getting these issues?

What I have noticed is that if I use Batarang to inspect the scope licenceKey seems to stay null until I submit the form. Why does this not get populated as I type into the input?

angular.module('licenceApp.controllers', [])
    .controller('licenceController', ['$scope', 'licenceAPIservice', '$filter', function ($scope, licenceAPIservice, $filter) {
        $scope.licenceKey = "";

        $scope.$watch('licenceKey', function (newValue, oldValue) {
            $scope.$apply(function () {
                $scope.licenceKey = newValue.toUpperCase();
            })
        });
        ...

Update

I have just notice that when I use the watch, my text isnt capitalised until I get a valid licence key (as validated by the licenceAPIservice) but it DOES get capitalised when I enter a valid key in lower case. Code below:

angular.module('licenceApp.directives', [])
    .directive('licenceKeyValidator', function ($http, $q, licenceAPIservice) {
        return {
            require: 'ngModel',
            link: function ($scope, element, attrs, ngModel) {
                ngModel.$asyncValidators.licenceKeyValidator = function (licenceKey) {
                    var deferred = $q.defer();

                    licenceAPIservice.validateKey(licenceKey).then(function (data) {
                        if (data.data) {
                            deferred.resolve();
                        }
                        else {
                            deferred.reject();
                        }
                    }, function () {
                        deferred.reject();
                    });

                    return deferred.promise;
                };
            }
        }
    });

Upvotes: 1

Views: 483

Answers (1)

SoluableNonagon
SoluableNonagon

Reputation: 11755

I managed to create a small function using a filter I created which capitalizes and hyphenates, take a look and let me know if it meets your needs.

http://plnkr.co/edit/i8MEUQjtUvlthp9WwaBq?p=preview

Code:

var app = angular.module("myApp", []);

app.controller('myCtrl', ['$scope', '$filter', function($scope, $filter){

  $scope.myText = "";

  $scope.update = function(){ 
    $scope.myText = $filter('myFilter')($scope.myText); 
  };

}]); 

app.filter('myFilter', function(){
  return function(text){
    if(!text)
      return text;
    else{
      var toReturn = text;
      toReturn = toReturn.toUpperCase().replace('', '');
      if(toReturn.length > 4 && toReturn[4] !== "-") 
        toReturn = toReturn.substring(0, 4) + "-" + toReturn.substring(4);
      if(toReturn.length > 9 && toReturn[9] !== "-") 
        toReturn = toReturn.substring(0, 9) + "-" + toReturn.substring(9);
      if(toReturn.length > 14 && toReturn[14] !== "-") 
        toReturn = toReturn.substring(0, 14) + "-" + toReturn.substring(14); 
      return toReturn; 
    }
  }; 
});

HTML:

<input ng-model="myText" ng-change="update()"/>

Upvotes: 1

Related Questions