I have integrated a directive into my input field to validate a license key against a server-side API. While this functionality works well, I also want the license key to automatically add hyphens and appear in capital letters.
For example, when a user inputs abcd1234qwer5678
, it should display as ABCD-1234-QWER-5678
. (I am focusing on achieving auto-capitalization first, then I will work on adding hyphens).
I have attempted a few approaches. Initially, I tried using a $watch function within the controller:
$scope.$watch('licenceKey', function (newValue, oldValue) {
$scope.$apply(function () {
$scope.licenceKey = newValue.toUpperCase();
})
});
Additionally, I explored using a second directive 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 approach doesn't seem to have any effect, while the second one replaces the existing text after a brief delay. The HTML for my input field is as follows:
<input type="text" name="licenceKey" ng-model="licenceKey"
ng-model-options="{ debounce : { 'default' : 150 } }" licence-key-validator />
What is the most effective way to achieve the desired outcome, and what could be causing these challenges?
I have noticed that when using Batarang
to inspect the scope, the licenceKey remains null until I submit the form. Why isn't it being populated as I type into the input field?
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 just realized that when using the watch
method, the text doesn't get capitalized until a valid license key (validated by the licenceAPIservice) is entered. However, it does capitalize correctly when entering a lowercase valid key. See the code snippet 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;
};
}
}
});