In the most primitive angular app I am trying to create a directive for an input field which changes parent's ng-model value.
HTML:
<form novalidate>
<input ng-model="ctrl.myvalue" mydirective minlength="19" />
{{ ctrl.myvalue }}
</form>
JS:
var app = angular.module('app', []);
app.directive('mydirective', function(){
return {
scope: { ngModel: '=' },
link: function(scope, el) {
el.on('input', function(e) {
this.value = this.value.replace(/ /g,'');
scope.ngModel = this.value;
})
}
}
})
app.controller('MyController', function(){
this.myvalue = '';
})
Plunker
The problem is that if I use this directive together with minlength or pattern for an input validation it gets a specific behavior: every second letter you type in the input disappears; also ng-model gets undefined value. Without validations the code works perfectly.
I also tried to create a custom validation as a workaround but it has the same effect.
Could you explain that or propose the way to go?
You can use unsift, as well render for the first iteration.
Usually you can use ctrl.$setViewValue but you can be sure no relaunch when the value don;t change...
var testModule = angular.module('myModule', []);
testModule.controller('testCntrl', ['$scope', function ($scope) {
$scope.test = 'sdfsd fsdf sdfsd sdf';
}]);
testModule.directive('cleanSpaces', [function () {
return {
require: '?ngModel',
link: function (scope, $elem, attrs, ctrl) {
if (!ctrl) return;
var filterSpaces = function (str) {
return str.replace(/ /g, '');
}
ctrl.$parsers.unshift(function (viewValue) {
var elem = $elem[0],
pos = elem.selectionStart,
value = '';
if (pos !== viewValue.length) {
var valueInit = filterSpaces(
viewValue.substring(0, elem.selectionStart));
pos = valueInit.length;
}
//I launch the regular expression,
// maybe you prefer parse the rest
// of the substring and concat.
value = filterSpaces(viewValue);
$elem.val(value);
elem.setSelectionRange(pos, pos);
ctrl.$setViewValue(value);
return value;
});
ctrl.$render = function () {
if (ctrl.$viewValue) {
ctrl.$setViewValue(filterSpaces(ctrl.$viewValue));
}
};
}
};
}]);
http://jsfiddle.net/luarmr/m4dmz0tn/
UPDATE I update the fiddle with the last code and a validation example in angular and update the html with ng-trim (ngModel.$parsers ingore whitespace at the end of ng-model value).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With