$scope.var giving undefined in angularjs - angularjs

I am using angularjs to do client side validation on a textbox where I need input as alphanumeric chars only. If the textbox is left empty or non-alphanumeric char is entered, the submitform sends 'false' to JS which is desired but the problem is it doesn't pass the non-alphnumeric char itself (in the scope).
JSP file:
<form name="addressForm" method="post"
ng-submit="submitform(addressForm.$valid)" novalidate>
..
<input ng-model="address" type="text"
**ng-pattern**="/^[a-zA-Z0-9 ]*$/" required="true"/>
JS file:
$scope.submitform= function(isValid){
var inputAddr = $scope.address;
alert(inputAddr); //coming as undefined
...
Now when I input an alphanumeric character in input box 'address' in jsp it gives me undefined on alerting it in JS (probably because of pattern which filters the char being non-alphanumeric). If I remove ng-pattern, it passes the submitForm passes 'true' as if every input is "as expected". The reason I want to access $scope.address is to check and value and display different error message for "empty" and a "non-alphanumeric" validation.
Any help is appreciated !

When the model is not valid, the value is not assigned to the model. If you want to see what the user has typed, you need to check $viewValue:
You must to add name attribute to input, so change your input html to:
<input ng-model="address" type="text" name="address"
ng-pattern="/^[a-zA-Z0-9 ]*$/" required="true"/>
And change your submit function to
$scope.submitform = function(isValid) {
console.log($scope.addressForm.address.$viewValue);
}

It sounds like you just need to know what the validation error is.
You can check the $error property the FormController (addressForm in your case) to see what validations passed or failed.
For example, if the input is empty, then the "required" validation will have failed and addressForm.$error.required will be an Array containing the inputs that failed this validation.
If the "required" validation succeeded, then addressForm.$error.required will just be false.
You can use this in angular expressions quite easily:
<p ng-show="addressForm.$error.required">This field is required.</p>
Or you can access the form through the $scope object that is associated with the view:
if ($scope.addressForm.$error.required) {
// required validation failed
}
Check out the documentation for FormController and ngModelController.

Related

How to get validation info of an input outside of a form?

We can get the validation info if the input is in a form: $scope.myForm.myField.$invalid etc..
What if input is outside of a form? How can we access the info?
I guess that field data (properties of the form object) is not same thing with ngModel. I tried something like this but didn't worked: (the model only contains string value of the input)
<input ng-model="myFakeForm.myField">
How can I achieve this?
Use the ng-form directive:
<div ng-form="set1">
<input name="field1" ng-model="myFakeForm.myField" ng-required="true" />
</div>
The input's ngModelController will be bound to $scope.set1.field1:
console.log($scope.set1.field1.$valid);
console.log($scope.set1.field1.$viewValue);
//... etc
For more information, see
AngularJS ng-form Directive API Reference

how to validate on form submit using AngularJS

I am very much new in angular js.I want to validate and post the form data using angular js on submit.I searched google but most of them was
disable the button on load ,after completing the form with valid data the button enable but I want to show error messages on form submit.
Here is My form snapshoot
I have tested with two text fields one is name and other is email but I want to proper messages for each fields e.g for email,phone no (valid format) and empty fields now I get only empty field message.
<span class="error-message"
ng-show="showMessage(frmReg.name)">
Please complete this field.</span>
var app=angular.module('regForm',[]);
app.controller('FormController',function($scope,$http){
$scope.frmRegField={};
$scope.frmSubmit=function(){
angular.forEach($scope.frmReg.$error.required, function(field) {
field.$setDirty();
});
// $http({
// method:"POST",
// url:"form_submit.php",
// data:$scope.frmRegField
// }).success(function(data){
// });
};
$scope.showMessage=function(input){
console.log(input.$$attr.name);
var show = input.$invalid && (input.$dirty || input.$touched);
return show;
};
});
You could use either class or state to do what you need
Input fields have the following states:
$untouched The field has not been touched yet
$touched The field has been touched
$pristine The field has not been modified yet
$dirty The field has been modified
$invalid The field content is not valid
$valid The field content is valid
They are all properties of the input field, and are either true or false.
Forms have the following states:
$pristine No fields have been modified yet
$dirty One or more have been modified
$invalid The form content is not valid
$valid The form content is valid
$submitted The form is submitted
The following classes are added to, or removed from, input fields:
ng-untouched The field has not been touched yet
ng-touched The field has been touched
ng-pristine The field has not been modified yet
ng-dirty The field has been modified
ng-valid The field content is valid
ng-invalid The field content is not valid
ng-valid-key One key for each validation. Example: ng-valid-required, useful when there are more than one thing that must be validated
ng-invalid-key Example: ng-invalid-required
The following classes are added to, or removed from, forms:
ng-pristine No fields has not been modified yet
ng-dirty One or more fields has been modified
ng-valid The form content is valid
ng-invalid The form content is not valid
ng-valid-key One key for each validation. Example: ng-valid-required, useful when there are more than one thing that must be validated
ng-invalid-key Example: ng-invalid-required
The classes are removed if the value they represent is false.
Give the form a name:
<form name="myForm">
And a name for the input to:
<input type="text" name="myName">
Then use ng-show/ng-if in your span:
<span class="error-message" ng-show="myForm.myName.$touched && myForm.myName.$invalid">
Please complete this field.
</span>
You can use ng-disabled to validate submit too:
<input type="submit" value="Submit" ng-disabled="myForm.$invalid">
Hope this helps. Good luck!

AngularJS Form Validation - Bind input to model eventhough there is input error

I have a form using the built in angularjs form validation and ng-messages. Look at this code.
<div class="form-group" ng-class="{ 'has-error': form1.firstName.$invalid && form1.firstName.$touched }">
<label class="control-label">* First Name</label>
<input name="firstName" ng-model="applicant.firstName" required ng-pattern="alpha" ng-minlength="2" ng-maxlength="30" type="text" class="form-control" />
<div class="help-block has-error" ng-messages="form1.firstName.$error" ng-if="form1.firstName.$touched">
<div ng-messages-include src="/worktrustedV2/app/modules/core/templates/errorMessages.template.html"></div>
<div ng-message="pattern" class="error" style="color:red">This field requires letters only</div>
</div>
If the input doesnt trigger an error, then if you console.log($scope.applicant.firstName);, it prints the value, but if the input has an error, console.log($scope.applicant.firstName); becomes undefined.
Is there a way to make angular(or maybe it because of ng-messages) bind the input's value even if it has error? I want to make console.log($scope.applicant.firstname); to print the value even if the input has error.
EDIT: After you rephrased the question
I remember I was facing the same problem when writing an application; when you have 10000+ lines of code, you can imagine the situation. Now, if I understand it clearly, you WANT applicant.firstName to have SOME value even if the validation fails? If that's the case, let me explain to you how Angular works.
Whenever you define a field as an ng-model, the internals of Angular manage two values for this field:
$modelValue
$viewValue
As you might have guessed from the names of these variables, $modelValue is the value of the input instance to be used by the model, and the $viewValue is used for displaying it, etc. (AngularJS ngModel)
Our good friends at Angular have done something pretty useful: whenever the input field doesn't pass the test, the $modelValue is set to undefined. So, when you try to get the value of that model, Angular sees that it's empty and so returns an undefined. Also, when the validation fails, <parentForm>.$invalid is switched to true.
For your case, you can give it a default value; so, even if the validation fails, you'll get SOME value.
Simple add:
$scope.applicant.firstName = "example#gmail.com";
in the controller to get a value even after the validation fails.
Yeah! You can check if the value if undefined and break out of the function. That's the best method.
...
$scope.submit = function() {
if( $scope.firstName === undefined ||
$scope.firstName === null ) { return; }
... // Continue normal execution
}

bind email containing apostrophes to angular model

I have an input type email that I validate against my own custom regular expression. It in turn is bound to an angular model something like:
js
$scope.user = {};
html
<input type="email" ng-model="user.email" />
I would like for the email to allow apostrophes but the email doesn't bind to the model unless it passes the built in html5 validation. I'd like to override or switch off this validation since I have my own custom regex in place.
I've tried adding the novalidate tag to the form wrapper and also adding a pattern to the input but not getting anywhere. Please see jsfiddle:
http://jsfiddle.net/HB7LU/19499/
Any ideas greatly appreciated
C
EDIT: The reason I'm not using type="text" is because I want the email keyboard set to be there when accessing from mobile.
Angular do not support the apostrophe(') in email Id , if need to valid the apostrophe in angular, need to change in angular file regular expr
(/^[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)
to
/^[A-Za-z0-9._%+'-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/.
It will Work perfectly.
If you already have a regex for validation, you could set the type of the input tag to "text" so that then it would not do any validation and then the regex you have already created could be used to do the validation you want. Also, this will allow you to change the validation method if you ever decide to change how you want validation to work.
Here's the tag:
<input type="text" ng-model="user.email" />

Why does an invalid form is valid at first and right after turns out invalid?

In order to simplify things I made up a sample form to describe my question:
<form novalidate name="form">
<input required name="foo" ng-model="my.foo">
</form>
And also a controller:
angular.module('sample', []).controller('MainController', function($scope) {
$scope.$watch('form.$valid', function (valid) {
console.log(valid);
});
});
Expected result:
> false
Actual result:
> true
> false
Can anybody tell me why at first the form is valid and then becomes invalid (what it is supposed to be, by the way)?
Working demo
I'm actually sure this is due to directives priority.
In angularJS <form> is actually a directive. required is another one.
Let supose we have a form without validation. The form is always valid. I'm pretty sure that now we can say that a form is valid by default.
The "form" directive have a higher priority than "required". It mean that at a point. Angular apply the "form" directive, and not the "required" one. This result in a valid form with an input with an unknown attribute "required". Next digest will analyze the "required" directive. It find that the input is empty and set valid to false.
As Omri said, it's a mater of directives priority and digest cycles.

Resources