Directive to accept numbers greater than 0 and less than 100 - javascript

I am trying to create an angular Directive which returns an error when the input of the textfield is less than 5 and greater than 200 i am trying with this code and for some reason it isnt working any help would be appreciated.
JS
app.directive('numbersOnly', function(){
return {
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
// this next if is necessary for when using ng-required on your input.
// In such cases, when a letter is typed first, this parser will be called
// again, and the 2nd time, the value will be undefined
if (inputValue == undefined) return ''
var transformedInput = inputValue.replace(/[^0-9]/g, '');
console.log("inputValue"+inputValue);
if(parseInt(inputValue) > 200 || parseInt(inputValue) < 5){
return '';
}
if (transformedInput!=inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});
HTML
<div ng-controller="MyCtrl">
<input type="text" ng-model="number" required="required" numbers-only="numbers-only" />
</div>
The plunker that i created is this (http://plnkr.co/edit/QKifStiFmHBF8GhcH3Ds?p=preview)
Any help would be appreciated!

I have given a directive that takes care of your model value to always contain int values between 5 and 200. A 'ng-invalid' class will be added when you do setValidity to false. Using that you can use css to display error to the user. In case you want your input to be updated with the correct model value in case of error, you can do it in the blur event.
app.directive('numbersOnly', function(){
return {
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
if(parseInt(inputValue) <= 200 && parseInt(inputValue) >= 5){
modelCtrl.$setValidity('numbersOnly', true);
return inputValue;
} else {
modelCtrl.$setValidity('numbersOnly', false);
return modelCtrl.$modelValue;
}
});
}
};
});

angular already has perfect directives for that. all you need is a form and use Min Max inside input tag
<form name="ue.form">
<input type="number" ng-model="ue.num" name="num" min="5" max="200" >
</form>
<p ng-if="ue.form.$error">
number must be less than 200 and greater than 5
</p>
or you can handle each error separately:
<p ng-if="ue.form.num.$error.min">
number must be greater than 5
</p>
<p ng-if="ue.form.num.$error.max">
number must be less than 200
</p>
if number is not in range 5-200 then form validotor throw an error.
min and max work only with input type="number".
https://plnkr.co/edit/?p=preview

Here's what I would suggest:
Use ng-model-options="{ updateOn: 'blur' }" so that model gets updated only on blur.
Try this code in directive:
app.directive('numbersOnly', function(){
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, element, attrs, ngModel) {
element.on('blur', function() {
if (ngModel.$viewValue < 5 || ngModel.$viewValue > 200) {
ngModel.$setViewValue('');
element.val('');
}
});
}
};
});

You can use ng-messages for these kind of validation purposes
We always can customize ng-messages with our needs.
you can create two directives for min and max. In your case your minimum value is 5 and max is 200, we dont need to hardcode our values inside the directives.
You dont need to worry for adding error messages in your directive. ng-messages will do it for you. You just need to put your messages inside ng-messages div.
Directive
module.directive("min", function () {
return {
restrict: "A",
require: "ngModel",
link: function (scope, element, attributes, ngModel) {
ngModel.$validators.min = function (modelValue) {
if (!isNaN(modelValue) && modelValue !== "" && attributes.min !== "")
return parseFloat(modelValue) >= attributes.min;
else
return true;
}
}
};
});
module.directive("max", function () {
return {
restrict: "A",
require: "ngModel",
link: function (scope, element, attributes, ngModel) {
ngModel.$validators.max = function (modelValue) {
if (!isNaN(modelValue) && modelValue !== "" && attributes.max !== "")
return parseFloat(modelValue) <= attributes.max;
else
return true;
}
}
};
});
Usage
<form name="myform">
<input type="text" name="minmax" ng-model="number" required="required" min="5" max="200"/>
<div data-ng-messages="myform.minmax.$error" class="error-messages">
<div data-ng-message="min">YOu cant enter below 5</div>
<div data-ng-message="max">You cant enter above 200</div>
</div>
</form>
Here is my pluker example

Related

Angular material input number change format

In my angular-material app I have a field with validation:
<input type="number" ng-model="myValue"
name="myValue"
min="0" max="100"
ng-pattern="/^[0-9]\d*(\.\d+)?$/" required>
It works fine. But now I need to make it to allow user to type .75 and get instead of 0.75
So the question how to apply my filter:
if( myValue.substring(0,1) == "." ){
myValue = "0" + myValue;
}
before angular material ng-pattern and type="number" validation
You can write some directive with $filter, $formatters and $parsers:
app.directive('parser', ['$filter',
function($filter) {
return {
restrict:'A',
require: 'ngModel',
link: function(scope, element, attrs, ctrl) {
ctrl.$formatters.unshift(function (a) {
return $filter('myFilter')(ctrl.$modelValue)
});
ctrl.$parsers.unshift(function (viewValue) {
element[0].value = $filter('myFilter')(element[0].value);
return element[0].value;
});
}
};
}
]);
app.filter('myFilter', [
function() {
return function(input) {
if( input && input.substring(0,1) == "." ){
input = "0" + input;
}
return input;
};
}
]);
DEMO Plunkr
However you cannot use type number because as I remember . not supported and doesn't parses as integer
Hope it will give you direction

custom directive is not validating form. why not?

What code changes need to be made to get the custom countparens directive below to provide the extra custom string validation shown below during form validation? The code below DOES successfully alert the user when the input field is empty, but it IS NOT alerting the user when the number of open parens ( and close parens ) is not equal.
I am using AngularJS. I used the documentation at this link (scroll to bottom) to design the code below.
Here is the html for the form:
<table>
<tr>
<td width=200>
<form name="userForm" ng-submit="rectangularForm(userForm.$valid)" novalidate>
<input type="text" name="fieldname" ng-model="nameofjsontype.fieldname" required />
<p ng-show="userForm.fieldname.$invalid && !userForm.fieldname.$pristine" class="help-block">Function is a required field.</p>
<span ng-show="userForm.nameofjsontype.fieldname.$error.countparens">The #( != #) !</span>
<br>
<button type="submit" ng-disabled="userForm.$invalid" >Click to submit</button>
</form>
</td>
</tr>
</table>
The javascript file containing the directive includes:
// create angular app
var myApp = angular.module('myApp', []);
// create angular controller
myApp.controller('myController', ['$scope', '$http', function($scope, $http) {
$scope.nameofjsontype = {type:"nameofjsontype", fieldname: 'some (value) here.'};
$scope.rectangularForm = function(isValid) {
// check to make sure the form is completely valid
if (isValid) {
var funcJSON = {type:"nameofjsontype", fieldname: $scope.nameofjsontype.fieldname};
$http.post('/server/side/controller', funcJSON).then(function(response) {
$scope.nameofjsontype = response.data;
});
}
};
}]);
myApp.directive('countparens', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.countparens = function(modelValue, viewValue) {
if (ctrl.$isEmpty(modelValue)) {
// consider empty models to be valid
return true;
}
if (
($scope.nameofjsontype.fieldname.match(/\)/g).length) == ($scope.nameofjsontype.fieldname.match(/\(/g).length)
) {
// it is valid
return true;
}
// it is invalid
return false;
};
}
};
});
Your markup should be using userForm.fieldname.$error.countparens to show the error. The field bound to the userForm is NOT the same as your ngModel value. See plunker for what I mean
<span ng-show="userForm.fieldname.$error.countparens" class="help-block">The #( != #) !</span>
You are also not using your directive on your input element:
<input type="text" name="fieldname" ng-model="nameofjsontype.fieldname" required data-countparens=""/>
In your directive
you should be using modelValue and not the scope value when doing your matching AND
you need to cater for when there are no matches to ( or )
.
myApp.directive('countparens', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.countparens = function(modelValue, viewValue) {
return ctrl.$isEmpty(modelValue) ||
((modelValue.match(/\)/g) || []).length == (modelValue.match(/\(/g) || []).length);
};
}
};
});

Input allow only 6 digits and after comma seperated and allow another 6 digits in angular js

Hi i am new to angularjs we want to implement a input text box which will allow only six digits and after entering six digits a comma separated will add and enter another six digits . Can you please help me. The sample code we have now is
**html**
<div ng-controller="MyCtrl">
<input type="text" ng-model="number" required="required" numbers-
only="numbers-only" />
</div>
Angular js controller
angular.module('myApp', []).directive('numbersOnly', function(){
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;
});
}
};
});
function MyCtrl($scope) {
$scope.number = ''
}
fiddler link we found
http://jsfiddle.net/thomporter/DwKZh/
have a look at ui-mask, set the mask as 999999-999999 or you can also use angular-input-mask
Edit your angular directive and bind a key press event to the textbox element. Inside the event check length. If length is 6 add a comma and rebind new value to your text box.
All you got to do is attach a key press event inside the directive link and check for input length and act accordingly. Instead of modifying your code, I pretty much wrote my own. Here is a DEMO
Here is the HTML code:
<div ng-app="myApp" ng-controller="MyCtrl">
<input type="text" ng-model="number" number-only required="required" />
</div>
Here is the modified directive code:
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', function($scope) {
}])
app.directive('numberOnly', function() {
return {
restrict: 'A',
link: function(scope, elem, attrs) {
// Attach key press event
elem.bind('keypress', function(e) {
// Check if its a number
if (e.which >= 48 && e.which <= 57) {
var ar = scope.number.split(',');
if (ar[ar.length - 1].length >= 6) {
scope.number = scope.number + ',';
}
scope.$apply();
}
else {
e.preventDefault();
}
});
}
}
});

Angular JS validation

I'm trying to validate my text area:
<form id="contact_form" name="contactform" ng-submit="submit(contactform)" role="form">
<textarea class="form-control" id="Message" ng-model="formData.message" ng-trim="false" placeholder="Your message" required="required" rows="8"></textarea>
</form>
For max word count, so I added a filter :
app.filter('wordCounter', function () {
return function (value) {
if (value && typeof value === 'string') {
return value.trim().split(/\s+/).length;
} else {
return 0;
}
};
});
And when this filter is met I print out an error :
<span class="help-block" ng-show="(formData.message|wordCounter) > 200">
Max 200 words please!
</span>
But still when I check in my controller contactform.$valid is always true, how do I make form invalid if the filter wordcounter is more than 200?
You need to create a custom validation directive. With Angular 1.3 $validators it's very easy.
For example, simple one:
.directive('maxWords', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModelController) {
ngModelController.$validators.maxWords = function(viewValue, modelValue) {
if (!ngModelController.$isEmpty(modelValue)) {
return modelValue.trim().split(/\s+/).length <= attrs.maxWords;
}
};
}
};
});
Demo: http://jsfiddle.net/m3pp71o4/

Angular Data Binding - Input type="number"

I'm having problems binding a number value using AngularJS.
I've put a simplified example on JSFiddle: http://jsfiddle.net/treerock/ZvdXp/
<div ng-controller="MyCont" ng-app>
<input type="number" min="0" max="50" value="{{value}}" ng-model="value" />
<input type="text" value="{{value}}" ng-model="value" />
<input type="range" min="0" max="50" value="{{value}}" ng-model="value" />
{{value}}
</div>
This should be three different types of input fields, and if you update one, then all values should update. That's working except for the number input. e.g. If I type 20 in the first number box, it updates all other instances of value. But if I update the text or range inputs, the number input goes blank.
I was wondering if the issue was with how the number is represented/converted between fields. e.g. the number input is a float and the text input is a string?
You're right, it has to do with string vs number types. I used a $scope.watch statement to fix it: http://jsfiddle.net/ZvdXp/6/
You can also fix this with a directive. I created a directive to force input bound to numeric fields to be numeric.
Html:
myApp.directive('numericbinding', function () {
return {
restrict: 'A',
require: 'ngModel',
scope: {
model: '=ngModel',
},
link: function (scope, element, attrs, ngModelCtrl) {
if (scope.model && typeof scope.model == 'string') {
scope.model = parseInt(scope.model);
}
}
};
});
You can add it to your numeric field like this:
<input data-ng-model="stringnumber" numericbinding type="number"/>
full example: http://jsfiddle.net/tdjager/cMYQ3/1/
I've expanded on Tim's answer to make it correct the data type after the user updates the control value as well.
myApp.directive('numericbinding', function () {
return {
restrict: 'A',
require: 'ngModel',
scope: {
model: '=ngModel',
},
link: function (scope, element, attrs, ngModelCtrl) {
if (scope.model && typeof scope.model == 'string') {
scope.model = parseInt(scope.model);
}
scope.$watch('model', function(val, old) {
if (typeof val == 'string') {
scope.model = parseInt(val);
}
});
}
};
});
If you prefer to save a numeric value in the model, you can use a directive that convert the string generated by the text input and by the range input in a numeric value through the angular parser, like so:
myApp.directive('numericsaving', function () {
return {
restrict: 'A',
require: '?ngModel',
scope: {
model: '=ngModel'
},
link: function (scope, element, attrs, ngModelCtrl) {
if (!ngModelCtrl) {
return;
}
ngModelCtrl.$parsers.push(function (value) {
if (!value || value==='' || isNaN(parseInt(value)) || parseInt(value)!==value) {
value=0;
}
return parseInt(value);
});
}
};
});
In the HTML, leave the number input as is and add the directive in the others inputs this way:
<input type="number" min="0" max="50" value="{{value}}" ng-model="value" />
<input type="range" min="0" max="50" value="{{value}}" ng-model="value" numericsaving/>
<input type="text" value="{{value}}" ng-model="value" numericsaving/>
The angular parser will translate the string input in a numeric value before saving it in model, so the numeric input will automatically work.
Here the complete fiddle.
Moreover, if the user inserts letters or any strange character in the text input, they will not be saved in the model, preventing invalid value in the single source of truth of your application.
Only '+' and '-' character at the begin of the text will be correctly parsed, so even negative value are allowed.
I hope this helps! :)
TypeScript version inspired ainos984, for the sake of posterity
export class ngIntegerDirective implements ng.IDirective {
static directiveKey: string = 'ngInteger';
require: string = 'ngModel';
link = (scope, ele, attr, ctrl: ng.INgModelController) => {
ctrl.$parsers.unshift(function (viewValue) {
let result: number = parseInt(viewValue,10);
if (isNaN(result)) {
result = 0;
}
return result;
});
}
public static Factory(): ng.IDirectiveFactory {
const directive = () => new ngIntegerDirective();
directive.$inject = []; //injecter les dépendances ici
return directive;
}
}

Categories

Resources