Why won't this ng-pattern filter numbers? - angularjs

I have an AngularJS single page application. One view has a textbox that I want to only accept numbers for an integer field. I have entered this code in the controller and this textbox in the view, but when I run the view it accepts any keyboard characters. Can you tell me how I need to modify this to work?
$scope.FilterNumbersOnly = /^\d+$/;
<input ng-model="x.COLUMN_VALUE" ng-pattern="FilterNumbersOnly" />

From the AngularJS documentation, ng-pattern will set the pattern key on the error object when the values input into the text-based field do not pass the specified regex test.
This says nothing about prohibiting users from inputting text. If you would like to add that behavior, you need to listen to the pattern key on the error object and attach handlers to it. When the input is invalid, the error object will reflect this, and you should respond by preventing user input. Or you can take whatever such action you deem necessary.
To prevent user input, you can set the disabled attribute on the input field when the pattern key on the error object is set.
One simple way to accomplish this is with the ng-if directive.
<input disabled ng-if="!form.input.$valid" />
<input ng-if="form.input.$valid" />
Here is a link to a working example.

You can do it using:
ngChange directive;
ngMask module (Always I need handle inputs with masks I use it).
I made this snippet showing both ways:
(function() {
"use strict";
angular.module('app', ['ngMask'])
.controller('mainCtrl', function($scope) {
$scope.checkNumber = function() {
$scope.input = $scope.input.replace(/\D+/, '');
}
})
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngMask/3.1.1/ngMask.min.js"></script>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body ng-controller="mainCtrl">
<form name="form" novalidate>
<label for="withoutMask">Input without mask: </label>
<input type="text" id="withoutMask" ng-model="input" ng-change="checkNumber()">
<hr>
<label for="mask">Input with mask: </label>
<input type="text" id="mask" mask="d" repeat="15" restrict="reject" limit="false" ng-model="otherInput">
</form>
</body>
</html>

why not use the built-in HTML support?
<input type="number">
supported - http://caniuse.com/#search=input%20type%3D%22number%22

Related

Nested md-checkbox not working [duplicate]

I referred to this before asking this question: AngularJs doesn't bind ng-checked with ng-model
If ng-checked is evaluated to true on the html side, the ng-model is not updated. I can't ng-repeat as suggested in the above question because I have to use some styling for each checkbox.
Here is the plunker that I have created to illustrate my problem.
http://plnkr.co/edit/YsOsPh3vjkPMUUDa6r2t
To see what I want, please open the console, and just click on Submit button. Please don't check any checkboxes.
ngModel and ngChecked are not meant to be used together.
ngChecked is expecting an expression, so by saying ng-checked="true", you're basically saying that the checkbox will always be checked by default.
You should be able to just use ngModel, tied to a boolean property on your model. If you want something else, then you either need to use ngTrueValue and ngFalseValue (which only support strings right now), or write your own directive.
What is it exactly that you're trying to do? If you just want the first checkbox to be checked by default, you should change your model -- item1: true,.
Edit: You don't have to submit your form to debug the current state of the model, btw, you can just dump {{testModel}} into your HTML (or <pre>{{testModel|json}}</pre>). Also your ngModel attributes can be simplified to ng-model="testModel.item1".
http://plnkr.co/edit/HtdOok8aieBjT5GFZOb3?p=preview
You can use ng-value-true to tell angular that your ng-model is a string.
I could only get ng-true-value working if I added the extra quotes like so (as shown in the official Angular docs - https://docs.angularjs.org/api/ng/input/input%5Bcheckbox%5D)
ng-true-value="'1'"
What you could do is use ng-repeat passing in the value of whatever you're iterating on to the ng-checked and from there utilising ng-class to apply your styles depending on the result.
I did something similar recently and it worked for me.
Can Declare As the in ng-init also getting true
<!doctype html>
<html ng-app="plunker" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl" ng-init="testModel['item1']= true">
<label><input type="checkbox" name="test" ng-model="testModel['item1']" /> Testing</label><br />
<label><input type="checkbox" name="test" ng-model="testModel['item2']" /> Testing 2</label><br />
<label><input type="checkbox" name="test" ng-model="testModel['item3']" /> Testing 3</label><br />
<input type="button" ng-click="submit()" value="Submit" />
</body>
</html>
And You Can Select the First One and Object Also Shown here true,false,flase
The ng-model and ng-checked directives should not be used together
From the Docs:
ngChecked
Sets the checked attribute on the element, if the expression inside ngChecked is truthy.
Note that this directive should not be used together with ngModel, as this can lead to unexpected behavior.
— AngularJS ng-checked Directive API Reference
Instead set the desired initial value from the controller:
<input type="checkbox" name="test" ng-model="testModel['item1']" ̶n̶g̶-̶c̶h̶e̶c̶k̶e̶d̶=̶"̶t̶r̶u̶e̶"̶ />
Testing<br />
<input type="checkbox" name="test" ng-model="testModel['item2']" /> Testing 2<br />
<input type="checkbox" name="test" ng-model="testModel['item3']" /> Testing 3<br />
<input type="button" ng-click="submit()" value="Submit" />
$scope.testModel = { item1: true };
You don't need ng-checked when you use ng-model. If you're performing CRUD on your HTML Form, just create a model for CREATE mode that is consistent with your EDIT mode during the data-binding:
CREATE Mode: Model with default values only
$scope.dataModel = {
isItemSelected: true,
isApproved: true,
somethingElse: "Your default value"
}
EDIT Mode: Model from database
$scope.dataModel = getFromDatabaseWithSameStructure()
Then whether EDIT or CREATE mode, you can consistently make use of your ng-model to sync with your database.
I had this issue while i am working with the angular js migration from 1.2 to 1.3.
The input type checkbox was not triggered if it was initiated from controller as well as the ng change event also not triggered. I tried with all types since ng model along with ng checked wont work.
Then ended with simple thing it worked for me like removing the ng change event by replacing with ng click.

ng-disabled and form validation

When using angular's (1.5) forms support, I would expect that when a field is disabled, it should not be marked as invalid, because the user cannot possibly change the value.
However, as seen in the plunker below, where a field is required, but can be switched from enabled to disabled and visa versa by the checkbox, the form validation result does not change, the whole form is still invalid, although the value cannot be changed if the field is disabled.
http://plnkr.co/edit/OMZkoPgPZcHjO67JF88c?p=preview
Together with showing validation messages and submitting the form this poses a problem in UX and flexibility to use the angular validations to determine the state of the form and if it is ok to "submit it" (send AJAX to the server).
(the code below is in the plunker, I just pasted it here, because the code is required when linking plunker)
<form name="vm.form" novalidate>
<input ng-model="vm.model" ng-disabled="vm.disabled" required />
<label><input type="checkbox" ng-model="vm.disabled" />Disable field</label>
</form>
Form is invalid: {{vm.form.$invalid}}
Ok preety much here you dont normally do ng-disabled on the fields just on like the submit button as shown:
<input ng-model="vm.model" ng-minlength="4" ng-required="true"/>
<label><input type="checkbox" ng-model="vm.disabled" ng-required="true"/>Disable field</label>
<br><input type="submit" ng-disabled="vm.form.$invalid"/>
</form>
Form is invalid: {{vm.form.$invalid}}
</body>
</html>
Now if you try this it will work correctly as shown in Plunker.
you can manipulate the value of ng-required value based on whether the checkbox value is checked or not
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angularjs#1.5.0" data-semver="1.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="Asd as vm">
<form name="vm.form" novalidate>
<input ng-model="vm.model" ng-disabled="vm.checkbox" ng-required="vm.checkbox===false" />
<label><input type="checkbox" ng-model="vm.checkbox" />Disable field</label>
<input ng-model="vm.other" required/>
</form>
Form is invalid: {{vm.form.$invalid}}
</body>
</html>

Min/Max Currency Field

Take a look at this jsbin
I have one field that is properly checking the range of the user's input. This is a number field.
I have another field that is changing the input into a currency format. This is a text field.
My issue is that I cannot do both of these ideas on one field. One field needs it to be text while the other requires it to be a number.
Is there something out there that can accomplish the marriage of both fields?
Instead of creating your own directive look into ng-currency: http://ngmodules.org/modules/ng-currency
<input type="text" model="yourModel" ng-currency min="1" max="1337" />
angular.module('myApp', ['ng-currency'])
.controller('CurrencyController', function($scope) {
$scope.myData = 8;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://rawgit.com/aguirrel/ng-currency/master/src/ng-currency.js"></script>
<!-- PLEASE CHANGE AS YOU WISH THIS LOCALE JS -->
<script src="https://code.angularjs.org/1.4.3/i18n/angular-locale_es-us.js"></script>
<div ng-app="myApp" ng-controller="CurrencyController">
<input type="text" ng-model="myData" ng-currency min="1" max="10" currency-symbol="$" /><br/>
{{ myData }}
</div>

Work with multiple Forms and its values

Assume an certain amount of forms created by ng-repeat, which allows the user to sum something up like a+b and display the result instantly.
How would the Controller look like?
<div data-ng-repeat="form in forms">
<form name={{form.name}}>
<input type="text" name="a" ng-modal="?">
<input type="text" name="b" ng-modal="?">
</form>
<p>{{?.result}}</p>
</div>
The question marks within the html should be something unique I guess. And the controller may access something like an array of forms from scope ... but maybe someone has a suggestion
If I understand your question correctly and assuming you have defined the forms in an array for example, below code should work for you:
<!DOCTYPE html>
<html data-ng-app="formApp">
<head>
<script type="text/javascript" src="https://code.angularjs.org/1.2.26/angular.js"></script>
<script type="text/javascript">
var formApp = angular.module("formApp",[]);
formApp.controller("formController", function($scope)
{
$scope.forms = [{name: "Foo"}, {name: "Bar"}];
});
</script>
</head>
<body data-ng-controller="formController">
<div data-ng-repeat="form in forms">
<form name={{form.name}}>
<input type="text" name="a" data-ng-model="form.someField">
<input type="text" name="b" data-ng-model="form.someOtherField">
</form>
<p>{{form.someField + form.someOtherField}}</p>
</div>
</div>
</html>
So basically you were right when mentioning "array of forms from scope".
The important thing to know is that angular creates a new scope for every item in the collection when using ng-repeat. This means, you do not need to use unique member names. "form.someField" for example always references the member of the current scope.
The calculation you would like to perform could be done inline as in my example or you could move it to an own method on a "class" from which all items in the form collection will inherit.
By the way: it's "data-ng-model" and not "data-ng-modal" ;)

How to create an angular validation message directive

I am new to angular and maybe trying to do the wrong thing.
What I am trying to, is to create a validation message directive, which can show validation message for a specific input field in a form. It should only show the validation message for required fields in case the input field is missing a value.
I've tried with the following HTML:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<form name="myForm">
<input name="myInput" type="text" x-ng-model="object.input" required/><br/>
<span ng-show="myForm.myInput.$error.required" >Value required (working)</span><br/>
<span x-msg-required="myForm.myInput"></span>
</form>
</body>
</html>
and the JS:
var app = angular.module('myApp', []);
app.directive('msgRequired', function() {
return {
link : function(scope, element, attrs) {
element.text('Value required');
attrs.$set('ngShow', attrs.msgRequired + '.$error.required' );
}
};
});
The first span element with out directive shows the validation message as expected. The span element with my directive seems to always show the validation message. I am for sure not understanding the directives in angular. What am I missing or is there better ways of streamlining validation messages in angular?
There is a plunker: http://plnkr.co/edit/Gjvol8inw1DlWjHomZQw
I was also bothered by this with Angular and created a directive suite in AngularAgility called Form Extension to fix this very issue. It automatically generates validation messages for you based on whats on your element. It is also very configurable and even will generate labels for you if you'd like.
Consider normally having to type something like this to get validation:
<div ng-form="exampleForm">
<label for="firstName">First Name *</label>
<div>
<input type="text" id="firstName" name="firstName" ng-model="person.firstName"
ng-minlength="2" />
<div ng-show="exampleForm.firstName.$dirty && exampleForm.firstName.$error.minlength">
First Name must be at least 2 characters long.
</div>
</div>
</div>
That's a pain. With the plugin you can do something like this instead:
<div ng-form="exampleForm">
<div>
<input type="text" aa-auto-field="person.firstName" ng-minlength="2" />
</div>
</div>
Here are some relevant links:
Extensive demo
Blog post explaining it
Source on GitHub
So I see this is a couple months old, but in case anyone is looking for something that works:
I updated your Javascript to this:
var app = angular.module('myApp', []);
app.directive('msgRequired', function($compile) {
return {
//transclude: true,
restrict: "A",
link: function(scope, element, attrs) {
element[0].innerHTML = 'Value required in angular directive';
attrs.$set('ngShow', attrs.msgRequired + ".$error.required");
$compile(element)(scope)
}
};
});
which seems to work. I am however doing something VERY similar in another project, and getting an infinite compile loop :( Investigating that...
plnkr lives here.

Resources