Reputation: 4782
Question Update: How can I prevent all characters except for the ones specified in a char array from being typed into an input field using AngularJS (or jQuery)?
I have a simple <input type="text" />
field in my AngularJS application and I want the user to only be able to enter the following characters into the field:
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~
I know that I can add ng-pattern="allowed"
to the <input>
and then set $scope.allowed
to some regex pattern and that will mark the input invalid if any invalid characters are entered, but I also want to prevent restricted characters from being input into the field AT ALL.
So my question is composed of two questions:
Upvotes: 13
Views: 19716
Reputation: 9108
The Angular way to do this is to make use of Angular's ngModelController.$parsers See the documentation:
$parsers
Array of functions to execute, as a pipeline, whenever the control reads value from the DOM. Each function is called, in turn, passing the value through to the next. The last return value is used to populate the model. Used to sanitize / convert the value as well as validation. For validation, the parsers should update the validity state using $setValidity(), and return undefined for invalid values.
Here is an example of a re-usable directive using this approach:
app.directive('inputRestrictor', [
function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attr, ngModelCtrl) {
var pattern = /[^0-9A-Z !\\"#$%&'()*+,\-.\/:;<=>?@\[\]^_`{|}~]*/g;
function fromUser(text) {
if (!text)
return text;
var transformedInput = text.replace(pattern, '');
if (transformedInput !== text) {
ngModelCtrl.$setViewValue(transformedInput);
ngModelCtrl.$render();
}
return transformedInput;
}
ngModelCtrl.$parsers.push(fromUser);
}
};
}
]);
Here is a plnkr demo.
*Regex pattern for the above directive taken from Viktor Bahtev answer.
You can obviously extend this directive to take an input parameter as well. I'll leave that for your exersize.
Upvotes: 11
Reputation: 4908
To 'restrict some characters from being typed in' what comes in my mind is to attach event handlers for 'keyup', 'change', 'paste' events on inputs and when they are triggered to 'clean' their values against your pattern. I implemented the logic as jQuery plugin but you can adapt it to angular, use better naming or whatever you want.
The plugin:
$.fn.restrictInputs = function(restrictPattern){
var targets = $(this);
// The characters inside this pattern are accepted
// and everything else will be 'cleaned'
// For example 'ABCdEfGhI5' become 'ABCEGI5'
var pattern = restrictPattern ||
/[^0-9A-Z !\\"#$%&'()*+,\-.\/:;<=>?@\[\]^_`{|}~]*/g; // default pattern
var restrictHandler = function(){
var val = $(this).val();
var newVal = val.replace(pattern, '');
// This condition is to prevent selection and keyboard navigation issues
if (val !== newVal) {
$(this).val(newVal);
}
};
targets.on('keyup', restrictHandler);
targets.on('paste', restrictHandler);
targets.on('change', restrictHandler);
};
Usage:
$('input').restrictInputs();
// Or ...
$('.my-special-inputs-decorated-with-this-class').restrictInputs();
Here is a JsFiddle Demo
Note: you can try to change the implementation to accept string with forbidden characters instead of regular expression and create the regex dynamically. Also you may find others events which are appropriate for triggering the 'cleaning'.
Upvotes: 7
Reputation: 71
Try to use regExp to filter unnecessary characters on ng-keypress by passing $event.
#
It'll be more clear in plnk!
Upvotes: 5