Angular js allow alphabetical caharacters and special characters but not numbers - javascript

My directive is below. What i want is that to allow alphabetical caharacters and special characters but not numbers. How can we changed that based on my code below.Thank you.
app.directive('validEn', function () {
return {
require: '?ngModel',
link: function (scope, element, attrs, ngModelCtrl, SweetAlert) {
if (!ngModelCtrl) {
return;
}
ngModelCtrl.$parsers.push(function (val) {
var clean = val.replace(/[^a-z|^A-z|^\s]+/g, '');
console.log("sfdsfd")
if (val !== clean) {
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}
return clean;
});
element.bind('keypress', function (event) {
if (event.keyCode === 32) {
event.preventDefault();
}
});
}
};
});

You need to change your regex statement so that it replaces any numerics with empty string, as such:
var clean = val.replace(/\d*/g, '');

Related

Angular directive: Allow just numbers

Here is a sample angular directive to prevent typing non-numeric keys (StackOverflow answer).
I want to write something like this fiddle to use the is-number directive in several inputs. Please consider that since I have various different directives in my inputs, I cannot use the same template as suggested in the update of mentioned answer above.
var $scope;
var app = angular.module('myapp', []);
app.controller('Ctrl', function($scope) {
$scope.myNnumber1 = 1;
$scope.myNnumber2 = 1;
});
app.directive('isNumber', function () {
return {
require: 'ngModel',
link: function (scope, element) {
scope.$watch(element.ngModel, function(newValue,oldValue) {
newValue = String(newValue);
newValue = newValue.replace('۰', '0').replace('۱', '1').replace('۲', '2').replace('۳', '3').replace('۴', '4').replace('۵', '5').replace('۶', '6').replace('۷', '7').replace('۸', '8').replace('۹', '9');
var arr = String(newValue).split("");
if (arr.length === 0) return;
if (arr.length === 1 && (arr[0] == '-' || arr[0] === '.' )) return;
if (arr.length === 2 && newValue === '-.') return;
if (isNaN(newValue)) {
element.ngModel = oldValue;
}
});
}
};
Update:
Please consider that I need to do some processes to convert non English numbers and so on. I created a new fiddle here based on the the Angular_10's answer. Now, every thing is fine except the cursor position while typing Persian numbers. When I type A Persian Number, it is replaced with English equivalent number, but the cursor suddenly jumps to the end.
OK ! Looking at your requirement I've took liberty and wrote more customised directive.
Here is the fiddle for the same
Problem
The example from which you referred and made changes to the given directive is causing the issue.
Your $scope variable names are wrong in HTML/JS ($scope.myNnumber1 = 1;
$scope.myNnumber2 = 1; in JS and in HTML it was ng-model="myNumber1")
You are accessing element ng-model and trying to modify it through directive which is bad practice and also the root cause for directive to not to work.As you are not changing the ng-model value but in turn modifying HTML element value which angular will not recognise.
More over using $watch in directive is not always preferable for performance sake.
Solution
app.directive('isNumber', function() {
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, element, attr, ctrl) {
function inputValue(val) {
if (val) {
var numeric = val.replace(/[^- 0-9]/g, '');
if (numeric !== val) {
ctrl.$setViewValue(numeric );
ctrl.$render();
}
return numeric;
}
return undefined;
}
ctrl.$parsers.push(inputValue);
}
};
});
When controller communication is required from directive we can pass Controller as 4 param in the link function.From that Ctrl param we can modify/view things from controller scope.
Using some basic regex expression to find out what is the entered input and set it in the controller scope object view value.
ctrl.$setViewValue(numeric); //to set the value in the respective ngModdel
ctrl.$render(); //to display the changed value
More about $setViewValue
I finally used the below directive. This directive converts persian number and do not let no numbers to be typed in the text box. Special thanks to Angular_10. I awarded 50 bounties to him for his help.
app.directive('fixPersianAndNoNumberInput', function ($filter) {
return {
require: 'ngModel',
restrict: 'EA',
link: function (scope, element, attr, controller) {
function inputValue(val) {
if (val) {
let numeric = parseInt(String(val).replace('۰', '0').replace('۱', '1').replace('۲', '2').replace('۳', '3').replace('۴', '4').replace('۵', '5').replace('۶', '6').replace('۷', '7').replace('۸', '8').replace('۹', '9').replace(' ', '000').replace(/[^- 0-9]/g, ''));
if (numeric !== val) {
controller.$setViewValue(numeric);
controller.$render();
let value;
let updateOn, debounce;
if (controller.$options) {
if (controller.$options.getOption) {
updateOn = controller.$options.getOption('updateOn');
debounce = controller.$options.getOption('debounce');
} else {
updateOn = controller.$options.updateOn;
debounce = controller.$options.debounce;
}
}
if (updateOn === 'blur' || debounce) {
value = controller.$viewValue;
for (let i = controller.$parsers.length - 1; i >= 0; i--) {
value = controller.$parsers[i](value);
}
} else {
value = controller.$$rawModelValue;
}
for (let j = controller.$formatters.length - 1; j >= 0; j--) {
value = controller.$formatters[j](value);
}
controller.$viewValue = value;
controller.$render();
}
return numeric;
}
return undefined;
}
controller.$parsers.push(inputValue);
controller.$formatters.push((value) => {
if ([undefined, null, ''].indexOf(value) === -1) {
return $filter('currency')(value, '', 0);
}
return value;
});
}
};
});

Allow only comma separated numbers in input field using angular js

I am using angular js and below is my code which allows only numbers separated by comma.But regex which I used allows user to enter 1,,,2.
Is there any way so that I can restrict user to enter only one comma after each number?
Plunker - http://plnkr.co/edit/g1X9ldVuH4ZewAlumM1P?p=preview
function NumberValidator() {
return {
require: '?ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
if (!ngModelCtrl) {
return;
}
ngModelCtrl.$parsers.push(function(val) {
var clean = val.replace(/[^\d+(,\d+)*$]/g, '');
if (val !== clean) {
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}
return clean;
});
element.bind('keypress', function(event) {
if (event.keyCode === 32) {
event.preventDefault();
}
});
}
};
Remove the clean part and replace the if condition with,
if (!/^\d+(?:,\d+)*$/.test(val)) {
This code would test whether the given value is in 1,2,3 or 1 or 3,4 formats or not.
Example:
console.log(!/^f+$/.test('ff'))
console.log(!/^f+$/.test('df'))
Think you want something like this,
str.replace(/[^\d,]|^,+|,+$|,+(?=,)/gm, '')
PLNKR

angularjs Date Input only

I am trying to validate input for date (dd/mm/yyy) and then if it is not date don't allow to enter - such as strings or anything
Below is my code but not working - means allowing users to enter anything
angular.module('app')
.directive('onlyDates', function () {
return {
require: 'ngModel',
restrict: 'A',
link: function (scope, element, attr, ctrl) {
function inputValue(val) {
if (val) {
var reg = /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g;
var res = reg.test(val);
if (!res) {
ctrl.$setViewValue(val);
ctrl.$render();
return NaN;
}
return val;
}
return undefined;
}
ctrl.$parsers.push(inputValue);
}
};
});
you could try using ng-change and some function that can check "as you type" that what you are entering matches your pattern, and if not, delete the last char entered.
<input type="text" ng-model="txtValue" ng-change="TextBoxChangedCheck()">
$scope.TextBoxChangedCheck = function () {
//// enter your text validation here
};

AngularJS Restrict input to numbers does not work

I have an input box on my html page with gets databound to an ng-model. I use a directive to restrict the input field to numbers only. I cannot used the default HTML5 restrictions like type="number". The problem I have is that if a non digit char is entered twice, e.g to press 123 and then two times k, the k is added to 123 resulting in 123k. However when I press another key, the k gets removed by the directive.
Can someone help me out to fix the problem that the letter appears if you press the same key twice
The directive I use:
angular.module('app').
directive('onlyDigits', function () {
return {
restrict: 'A',
require: '?ngModel',
link: function (scope, element, attrs, ngModel) {
if (!ngModel) return;
ngModel.$parsers.unshift(function (inputValue) {
var digits = inputValue.split('').filter(function (s) { return (!isNaN(s) && s != ' '); }).join('');
ngModel.$viewValue = digits;
ngModel.$render();
return digits;
});
}
};
});
This is what we use to achieve numbers only in a directive:
directives.directive('numbersOnly', function () {
'use strict';
return {
require: 'ngModel',
link: function (scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
if (inputValue === undefined) {
return '';
}
var transformedInput = inputValue.replace(/[^0-9]/g, '');
if (transformedInput !== inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});

javascript + regular expression

I have a problem. I want to use a regular expression that let me introduce just numbers and "." (for decimals) on an input field, no letters and other special character.
I'm trying this:
option 1 => var restrict="[^\d+]"
option 2 => var restrict="[^\d+]"
iAttrs.restrict = ^(?![0-9]+([.]?[0-9]+))$
value.toLowerCase().replace(new RegExp(iAttrs.restrict, 'g'), '');
This regular expression is an angular directive
appModule.directive('restrict', function($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, iElement, iAttrs, controller) {
scope.$watch(iAttrs.ngModel, function(value) {
if (!value) {
return;
}
value = value.toString();
$parse(iAttrs.ngModel).assign(scope, value.toLowerCase().replace(new RegExp(iAttrs.restrict, 'g'), ''));
});
}
}
});
It must remove the wrong characters written on the input. But the problem is
option 1 ==> don't let me write "." character
option 2 ==> don't let me write nothing (when I have a default value example: "300.21" that must appear on the input field ... after restrict directive finish, nothing is written on the input.
Can somebody help me?
Thanks
Updated based on comments:
As the case for decimal point is very particular, I created a new directive for that.
Directive Code:
angular.module("app",[]).directive('allowOnlyDecimal', function($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, iElement, iAttrs, controller) {
// used to find out if more than one . is available
function nth_ocurrence(str, needle, nth) {
for (i=0;i<str.length;i++) {
if (str.charAt(i) == needle) {
if (!--nth) {
return i;
}
}
}
return false;
}
scope.$watch(iAttrs.ngModel, function(value) {
if (!value) {
return;
}
value = value.toString();
var temp = value.replace(/[^(\d\.)]/gi, '');
// this removes any special character and alphabets
if(nth_ocurrence(temp,".",2)) {
temp = temp.substr(0, nth_ocurrence(temp,".",2));
// removes if user enters more than one decimal point
}
scope[iAttrs.ngModel] = temp;
});
}
};
}).controller("MainController", function($scope) {
$scope.someInput = 100.400;
});
In your HTML:
<input type="text" ng-model="someInput" allow-only-decimal>
WORKING DEMO
OLD ANSWER:
This could be more generic approach which you can use for most of the restrict functionality using regex.
HTML :
<input type="text" ng-model="someInput" restrict="[^(\d\.)]">
JS:
angular.module("app",[]).directive('restrict', function($parse, $timeout) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, iElement, iAttrs, controller) {
scope.$watch(iAttrs.ngModel, function(value) {
if (!value) {
return;
}
value = value.toString();
$timeout(function() {
scope[iAttrs.ngModel] = value.replace(new RegExp(iAttrs.restrict,'gi'), '');
},10);
});
}
};
}).controller("MainController", function($scope) {
$scope.someInput = 100.400;
});
You can use a simple regex like this:
^\d+\.*\d*$
Working demo

Categories

Resources