How to limit the user not to enter number greater than four? - angularjs

I have a input text box,where only numbers are allowed to enter.numbers="numbers-only" is the directive that prevents users to enter anything rather than numbers.Now I should not allow the user to enter the number with value more than 4.Plz help
HTML:
<input type='text' name='pat' id='pat' ng-model='dpmArr.pt_no' class='form-control' numbers-only="numbers-only">

There are 2 attributes that allow you to add a minimum and maximum to your input they are minand max
so just add max ="4" into your tags

Your Own directive
You can add another directive like this:
in html:
<input with-max-limit max-limit="9" type="text" ng-required="true" name="search" ng-model="value">
And in your js:
.directive("withMaxLimit", function () {
return {
require: ["ngModel"],
restrict: "A",
link: function ($scope, $element, $attrs) {
var modelName = $attrs.ngModel;
var maxLimit = parseInt($attrs.maxLimit, 10);
$scope.$watch(modelName, function (newValue, oldValue) {
if (newValue && (newValue.length > maxLimit || newValue.indexOf(' ') >= 0)) {
$scope[modelName] = oldValue;
}
});
}
}
})
Take into account that it is draft version and you could easily modify it.
Also pay attention to Angular's naming convention that directive has name withMaxLimit but in html it will be with-max-limit.
AngularJS Filter
Also take a look at Angular's limitTo filter.

Use an input with type="number" and an max=4 attribute:
<input type="number" max="4" name="input" ng-model="example.value">
Ref. https://docs.angularjs.org/api/ng/input/input%5Bnumber%5D

how are you applying the behavior with the numbers? I ask because maybe you could try to follow the same pattern. Otherwise, I think there are more than one option according to your needs. For instance, if the user introduces one number greater than 4, what should be the expected behavior? Return an error, block and donĀ“t write anything in the input,...
Depending on it, you could choose to add $parsers to the ngModelController or simply block the default behavior of the key by checking what is the key that has been pressed.

Related

Get value from input type email with Angular

How can I pass the value of an <input type='email'> using angularjs. I need to validate the email address on the input of my form and need to generate a key with this. The only thing I need to know is how should I get the value from the input.
angular.module('myApp', [])
.controller('EmailController', function($scope) {
$scope.hash = "";
$scope.generateKey = function () {
var resultKey = $scope.email;
// TODO: generate key
// Assing value to hash
$scope.hash = resultKey;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="EmailController">
<form>
<p>Email: <input type="email" ng-model="email" ng-keyup="generateKey()"></p>
<p><b>Hash: </b>{{hash}}</p>
</form>
</div>
Edit 1
I could use <input type='text'> and validate with a regex but I want to use type='email' as in the cellphone display more options on the keyboard. Does exist a way to get the input value using angular even if it isn't a valid email?
Use ng-model-options="{ allowInvalid: true }" if you want invalid email addresses to be bound to your controller:
<input type="email" ng-model="email" ng-keyup="generateKey()" ng-model-options="{ allowInvalid: true }">
Edit: You usually shouldn't data-bind to a primitive because prototypal inheritance can sometimes lead to binding to the wrong scope. Try binding to an object instead, like data.email.
Edit: Live example
The way angular handles input values and validations is via $parsers. you can intercept the default parsers and therefore get the value before it get to the email validation. Created this little snippet to further illustrate my point. Notice that I am not using .push to add my parser but instead I am using .unshift. I use unshift rather than push because I want to make sure my parser is the first on the list. or at least, the first at the moment i added to the list. This will guarantee that it runs before the default parsers which are already in the list by the time my code runs.
var app = angular.module('myApp', []);
app.controller('EmailController', function($scope) {
$scope.hash = "";
});
app.directive('generateKey', function(){
return {
require: ['ngModel'],
link: function(scope, element, attr, ctrls){
var ngModel = ctrls[0];
ngModel.$parsers.unshift(function(text){
scope.hash = text;
return text;
});
}
};
});
for a complete snippet, please visit: https://jsbin.com/vabofapigo/edit?html,js,output

compare two input field values in a table using angular

I am a beginner in angularjs and I am trying to make a dynamic table but with custom validations. for instance, I have 2 input fields namely totalSalary and pension paid. The pension paid entered should not be greater than the totalSalary. I am trying to build a custom directive for the pension paid field but how to get the value of the totalSalary field to do the comparison?
Thanks to help.
Ashley
Updated:
This is the table I have made so far as per the next link. Dynamic table made so far
Below are two fields I need to compare.
<td><input type="text" class="form-control" ng-model="employee.details.salary" fcsa-number required/></td>
<td><input type="text" class="form-control" ng-model="employee.details.pension" fcsa-number not-greater-than-yearly-sal required/></td>
The directive so far I have worked on is as per below. I got the value of pension1 but now how to get the value of salary. On leaving the input for pension1, if the amount is greater than the salary, it should prompt the user and clear the value.
angular.module('app').directive("notGreaterThanYearlySal", function () {
return {
restrict: "A",
require: "?ngModel",
link: function (scope, element, attributes, ngModel) {
element.bind('blur', function(event){
alert(element.val());
});
}
};
});
One way you achieve with custom directives
for example here i match email :
<p>Email:<input type="email" name="email1" ng-model="emailReg">
Repeat Email:<input type="email" name="email2" ng-model="emailReg2" ng-match="emailReg"></p>
<span data-ng-show="myForm.emailReg2.$error.match">Emails have to match!</span>
Without using custom Directives :
<button ng-click="add()></button>
<span ng-show="IsMatch">Emails have to match!</span>
$scope.add = function() {
if ($scope.emailReg != $scope.emailReg2) {
$scope.IsMatch=true;
return false;
}
$scope.IsMatch=false;
}
I think this is a really neat way of doing this. You could set something like ng-max to the second input and set it's value as the other inputs ng-model. Then according to this you could show a error message.
<form name="numberForm">
First input:
<input type="number" name="number1" ng-model="number1">
Second input:
<input type="number" name="number2" ng-model="number2" ng-max="number1">
<span ng-show="numberForm.number2.$error.max">This field should not be larger than the other</span>
</form>
Here's a JSFiddle: https://jsfiddle.net/thepio/dpgfuy06/
No need for directive!
Make the following changes in your code:-
Use ng-repeat to iterate over your array of elements in the employee details like this:-
<div ng-repeat ="details in employee.details">
</div>
where all your elements should be put in the employee.details array
Accordingly change your ng-model to "details.pension" and "details.salary"
Make a div below your input fields and specify the condition you want in ng-show
and display an error message for the same.
For instance, in your case it would look like:-
<div ng-show="details.pension > details.salary">Pension cannot be greater than salary!
</div>
This should do the validations there and then itself.
Using custom directive:
.directive("compareTo", function () {
return {
require: "ngModel",
scope: {
otherModelValue: "=compareTo"
},
link: function (scope, element, attributes, ngModel) {
ngModel.$validators.compareTo = function (modelValue) {
return modelValue == scope.otherModelValue;
};
scope.$watch("otherModelValue", function () {
ngModel.$validate();
});
}
};
})

Unable to use ng-minlength for input with custom directive in Angular

I've based a phone number formatting directive on this gist. Everything generally works great. But if I add a ng-minlength or ng-maxlength validation requirement, the input won't accept any input at all.
.directive('phonenumberDirective', ['$filter', function($filter) {
function link(scope, element, attributes) {
scope.inputValue = scope.phonenumberModel;
scope.$watch('inputValue', function(value, oldValue) {
value = String(value);
var number = value.replace(/[^0-9]+/g, '');
scope.phonenumberModel = number;
scope.inputValue = $filter('phonenumber')(number);
});
}
return {
link: link,
restrict: 'E',
scope: {
phonenumberPlaceholder: '=placeholder',
phonenumberModel: '=model'},
template: '<input ng-model="inputValue" type="tel" id="phone" name="phone" ng-minlength="7" class="phonenumber form-control" placeholder="{{phonenumberPlaceholder}}" required /> '
}
}]);
HTML:
<label class="control-label" for="phone">Phone</label>
<phonenumber-directive placeholder="'(000) 000-0000'" model='contactForm.contact.phone'></phonenumber-directive>
<span ng-show="myForm.phone.$error.required && !myForm.phone.$untouched
|| myForm.phone.$error.required && !myForm.phone.$untouched
|| myForm.phone.$error.minlength && !myForm.phone.$untouched" class="help-block">
Enter your phone number</span>
If I understand your question correctly, this behavior is expected. Your ng-model won't be updated if the input does not pass through the validation pipeline.
In this case, you won't see your watcher get fired until ng-minlength is met.
As an aside, you may want to consider using ngModelController on an attribute-level directive (yours is an element directive) as a more "Angular" way to maintain differences between the view value and its underlying model value. You are currently updating inputValue inside a watcher that is looking for updates to inputValue, which may lead to unexpected behavior.

Setting ngTrueValue and ngFalseValue to numbers

Update: question is obsolete for latest Angular version, see tsh's comment on this post
I have bound a checkbox to a value:
<input type="checkbox" ng-model="checkbox" ng-true-value="1" ng-false-value="0" />
The value of the checkbox is set to 1 in the controller:
function Controller($scope) {
$scope.checkbox = 1
}
However, initially the checkbox does not appear checked. If I change the initial value of $scope.checkbox to "1", it does. (jsfiddle demo)
I have tried all kinds of variations:
ng-true-value="{{1}}"
ng-true-value="{{Number(1)}}"
ng-true-value="{{parseInt('1')}}"
None of them work. How can I make angular treat the arguments as a number?
You can use ngChecked, If the expression is truthy, then special attribute "checked" will be set on the element
<input type="checkbox"
ng-model="checkbox"
ng-true-value="1"
ng-false-value="0"
ng-checked="checkbox == 1" />
And you can use $scope.$watch to convert it to number
$scope.$watch(function(){
return $scope.checkbox;
}, function(){
$scope.checkbox = Number($scope.checkbox);
console.log($scope.checkbox, typeof $scope.checkbox);
},true);
DEMO
I have created directive for that, seems to work fine:
angular.module('app').directive('cdTrueValue', [function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(v){
return v ? scope.$eval(attrs.cdTrueValue) : scope.$eval(attrs.cdFalseValue);
});
ngModel.$formatters.push(function(value) {
return value === scope.$eval(attrs.cdTrueValue);
});
}
};
}]);
Usage:
<input type="checkbox" ng-model="checkbox" cd-true-value="1" cd-false-value="0" />
DEMO
HTML attributes do not have any types. They can not contain anything else, then a string, so it is always a string. End of story.
You can not differentiate between between 1 and "1" in an HTML attribute. Angular tries to keep up with that, so only strings will work.
The first approach above is great. That's works fine. You can also use ng-change directive if you need use dynamic model (e.g. linked with ID or number - in case you wanna work with ID you don't know ahead). Just pass model as parameter: ng-change="fooBar(model[ID])" , catch in controller function and use Number(model[ID]) re-type. That's convert true as 1, false as 0 and you can work with this.

Input field number format AngularJS

I have the following input field:
<input type="text" class="span2" ng-model="mynumber">
mynumber has the value 0.55 which is loaded on pageload from a rest service. My problem is now, how can I format the number for different languages/countries? For example, in German, the value should be formatted with a comma (,) instead of a period (.). And if the user changes the number the number should be converted to . instead of ,, if I send it back to the rest service.
This should also work for larger numbers like 90,000.00, which should be 90.000,00 in German...
If I use the angular-locale_de-at.js, I can format the number on a normal output with this:
{{mynumber | number}}
but that does not work for an input field.
How can I handle this? The values should be (printed) formatted in the input field.
If I canage the type of the input field to number
<input type="number" class="span2" ng-model="mynumber">
it works in chrome but not in IE or FF. in chrome i get 0,55. but not in other browsers.
any ideas?
I've written the directive you are looking for. See the code on GitHub.
Also see this answer on SO
Using AngularJS directive to format input field while leaving scope variable unchanged
It will probably not work with <input type="number"/>, use <input type="text"/> instead
Mh,
my first idea would be to separate the concerns here. You're having the model mynumber on the one side and the representation on the other side. Those are distinct from my point of view.
So what you can do is to introduce a directive (I once did this for date values in AngularJS 1.1.5, so bit a bit of additional hacking could be necessary):
First we introduce a directive:
<input type="text" class="span2" ng-model="mynumber" number-format>
with the code:
var app = angular.module("your.directives", ['your.filters']);
app.directive("numberFormat", [
'$filter', function(filter) {
return {
replace: false,
restrict: "A",
require: "?ngModel",
link: function(scope, element, attrs, ngModel) {
var numberFormat;
if (!ngModel) {
return;
}
ngModel.$render = function() {
return element.val(ngModel.$viewValue);
};
var numberFilter = filter('myNumberFilter');
return ngModel.$formatters.push(function(value) {
return numberFilter(value);
});
}
};
}
]);
What you need for this, is a working myNumberFilter filter present, which could decide based on the language given (however you determine this) how to format the input value.
EDIT: I noticed, that AngularJS has it's own number filter, so i changed the name called. Let's add our own:
var app = angular.module("your.filters", []);
app.filter("myNumberFilter", ['SiteLanguage',
function(siteLanguage) {
return function(number) {
var language = siteLanguage.getLanguage(); //I assume you have a service that can tell you the current language
switch(language) {
case "de":
// return the variant of number for "de" here
break;
case "fr":
// return the variant of number for "fr" here
break;
default:
// return english variant here.
break;
};
}
]
});
You'll probably need a formatter function for the individual countries (instead of blindly relying on angular locale. And you probably need a service SiteLanguage which will give you the language on the current site.
Hope this helps :)

Resources