I am new to Angular 2.
I have created a simple template which has two text field, I want to required field validate those two fields.
Login Form
<form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm)" novalidate>
<div class="container">
<div class="form-group">
ooooo <label><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="uname" required [(ngModel)]="UserData.uname" #uname="ngModel">
<div *ngIf="loginForm.invalid" class="alert alert-danger">
<div [hidden]="!uname.errors.required"> Name is required </div>
</div>
</div>
<div class="form-group">
<label><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="pwd" required [(ngModel)]="UserData.pwd" #pwd="ngModel">
<div *ngIf="UserData.pwd.errors && (UserData.pwd.dirty || UserData.pwd.touched)" class="alert alert-danger">
<div [hidden]="!UserData.pwd.errors.required">Password is required </div>
</div>
<button type="submit" >Login</button>
</div>
</div>
</form>
My Component
import { Component } from "#angular/core"
import { User } from "./UserModel"
#Component({
selector: 'my-login',
templateUrl:"app/Login/login.html"
})
export class LoginComponent
{
//alert: any("hello");
UserData: User = new User("", "");
submitted = false;
onSubmit(form: any) {
alert("dfsdfsd" + form);
if (!form.invalid) {
alert(this.UserData.uname);
alert(this.UserData.pwd);
this.submitted = true;
}
}
}
What i want to implement is-
When the form loads no validation message should appear?
When user clicks on the submit button then the required message should appear?
In both the textbox i have applied different type of checks to show the message that is inconsistent? so there should be a consistent way to solve this.
Many thanks for the help.
Maybe make use of the submitted variable, and use that in template, to not show message, until submitted is true, which we set it as in the submit function.
Also you wouldn't really need the two-way-binding here, since the object your form produces is directly assignable to your UserData.
The validation messages I'd just set then simply like this, where we are targeting the username:
<div *ngIf="uname.errors?.required && submitted"> Name is required </div>
in your submit function I'd pass loginForm.value as parameter instead of just loginForm. This way you get the form object ready to be used :)
And in your function you can assign the object to your UserData variable.
onSubmit(form: any) {
this.submitted = true;
this.UserData = form;
}
If you do want to keep the two-way-binding, it's of course totally possible! :)
DEMO
Related
I'm quite new to Angular, and I've already searched the web, without finding a correct solution for my situation.
I have a dynamic form created by a *ngFor. I need to disabled the submit button if the inputs are all empty and show the alert div; but I need to enable the submit if at least one of those forms contains something different from ''.
Here is my html code
<form class="form-inline" #form="ngForm">
<div class="form-group" *ngFor="let meta of state.metaById; let i = index" style="margin: 5px">
<label>{{meta.nome}}</label>
<input type="text" class="form-control" #nome (blur)="inputInArray(nome.value, i);">
</div>
<button type="button" class="btn btn-primary" (click)="getCustomUnitaDocumentaliRow(this.param)" [disabled]="fieldNotCompiled">invia</button>
</form>
<div class="alert-notification" [hidden]="!fieldNotCompiled">
<div class="alert alert-danger">
<strong>Va compilato almeno un campo.</strong>
</div>
</div>
and here is my Typescript code
inputInArray(nome: string, indice) {
if (this.state.controlloMetaId = true) {
this.state.metadatoForm[indice] = nome;
}
// this.fieldNotCompiled = false;
for (const i in this.state.metaById) {
console.log(this.state.metadatoForm);
if (isUndefined(this.state.metadatoForm[i]) || this.state.metadatoForm[i] === '') {
this.fieldNotCompiled = true && this.fieldNotCompiled;
} else {
this.fieldNotCompiled = false && this.fieldNotCompiled;
}
console.log(this.fieldNotCompiled);
}
With this code I can check the first time a user type something in one input, but it fails if it empty one of them (or all of them)
Thanks for your time
UPDATE
Check if any input got a change that is different from empty or space, just by doing:
<input ... #nome (input)="fieldNotCompiled = !nome.value.trim()" ....>
DEMO
You can set a listener to the form changes:
#ViewChild('form') myForm: NgForm;
....
ngOnInit() {
this.myForm.valueChanges.subscribe((value: any) => {
console.log("One of the inputs has changed");
});
}
How to validate a form in angular 4 by clicking on external link (ie out side from tag). If the form is valid do some actions with form data else show validation messages. If form is valid I don't want to submit the form just need to get the form field values.
This is my answer post to another question:
The easy way is to use reactive forms, like this:
Code:
import {ReactiveForm, FormBuilder, Validators} from '#angular/form';
export class SignupFormComponent implements OnInit {
userForm: FormGroup;
firstName: string;
constructor(private _formBuilder:FormBuilder){}
ngOnInit() {
this.userForm = this._formBuilder.group({
'firstName': ['',[Validators.required,Validators.minLength(5)]]
});
}
onSubmit() {
console.log(this.firstName);
}
}
HTML:
<form [formGroup]="userForm" (ngSubmit)="onSubmit()" name="userForm">
<div class="form-group">
<label>First Name</label>
<input type="text" [(ngModel)]="firstName" class="form-control" formControlName="firstName">
<p *ngIf="userForm.controls.firstName.invalid && (userForm.controls.firstName.dirty || userForm.controls.firstName.touched)"> Error message </p>
</div>
<button type="submit" class="btn btn-primary" [disabled]="userForm.invalid">Submit </button>
</form>
I have a template based form in my Angular2 app for user registration. There, I am passing the form instance to the Submit function and I reset the from once the async call to the server is done.
Following are some important part from the form.
<form class="form-horizontal" #f="ngForm" novalidate (ngSubmit)="onSignUpFormSubmit(f.value, f.valid, newUserCreateForm, $event)" #newUserCreateForm="ngForm">
<div class="form-group">
<label class="control-label col-sm-3" for="first-name">First Name:</label>
<div class="col-sm-9">
<input type="text" class="form-control" placeholder="Your First Name" name="firstName" [(ngModel)]="_userCreateForm.firstName"
#firstName="ngModel" required>
<small [hidden]="firstName.valid || (firstName.pristine && !f.submitted)" class="text-danger">
First Name is required !
</small>
</div>
</div>
.......
.......
<div class="form-group">
<div class="col-sm-offset-3 col-sm-12">
<button type="submit" class="btn btn-default">Submit</button>
<button type="reset" class="btn btn-link">Reset</button>
</div>
</div>
</form>
In my component file, I have written following function.
onSignUpFormSubmit(model: UserCreateForm, isValid: boolean, form: FormGroup, event:Event) {
event.preventDefault();
if (isValid) {
this._userEmail = model.email;
this._authService.signUp(this._userCreateForm).subscribe(
res => {
console.log("In component res status = "+res.status);
if(res.status == 201){
//user creation sucess, Go home or Login
console.log("res status = 201");
this._status = 201;
}else if(res.status == 409){
//there is a user for given email. conflict, Try again with a different email or reset password if you cannot remember
this._status = 409;
}else{
//some thing has gone wrong, pls try again
this._serverError = true;
console.log("status code in server error = "+res.status);
}
form.reset();
alert("async call done");
}
);
}
}
If I submit an empty form, I get all validations working correctly. But, when I submit a valid form, Once the form submission and the async call to the server is done, I get all the fields of the form invalid again.
See the following screen captures.
I cannot understand why this is happening. If I comment out form.reset(), I do not get the issue. But form contains old data i submitted.
How can I fix this issue?
I solved this By adding these lines:
function Submit(){
....
....
// after submit to db
// reset the form
this.userForm.reset();
// reset the errors of all the controls
for (let name in this.userForm.controls) {
this.userForm.controls[name].setErrors(null);
}
}
You can just initialize a new model to the property the form is bound to and set submitted = false like:
public onSignUpFormSubmit() {
...
this.submitted = false;
this._userCreateForm = new UserCreateForm();
}
You need to change the button type submit to button as following.
<div class="form-group">
<div class="col-sm-offset-3 col-sm-12">
<button type="button" class="btn btn-default">Submit</button>
<button type="reset" class="btn btn-link">Reset</button>
</div>
</div>
Reseting the form in simple javascript is the solution for now.
var form : HTMLFormElement =
<HTMLFormElement>document.getElementById('id');
form.reset();
this is how finally I had achieved this. I am using Angular5.
I have created a form group named ="firstFormGrop".
If you are not using form groups you can name the form as follow:
<form #myNgForm="ngForm">
In the html doc:
<form [formGroup]="firstFormGroup">
<button mat-button (click)='$event.preventDefault();this.clearForm();'>
<span class="font-medium">Create New</span>
</button>
</form>
In the .ts file:
this.model = new MyModel();
this.firstFormGroup.reset();
if you where using #myNgForm="ngForm then use instead:
myNgForm.reset();
// or this.myNgForm.reset()
This is a very common issue that after clicking the reset button we created the validators are not reset to its initial state, and it looks ugly.
To avoid that we have two options,the button is outside the form, or we prevent the submission when the button is tagged inside the form.
To prevent this default behaviour we need to call $event.preventDefault() before whatever method we are choosing to clear the form.
$event.preventDefault() is the key point.
The solution:
TEMPLATE:
<form
action=""
[formGroup]="representativeForm"
(submit)="register(myform)"
#myform="ngForm"
>
*ngIf="registrationForm.get('companyName').errors?.required && myform.submitted"
COMPONENT:
register(form) {
form.submitted = false;
}
Try changing the button type from "submit" to "button", e.g. :
<button type="button">Submit</button>
And move the submit method to click event of the button. Worked for me!
I want to do validation for checkboxes here without form tag. At least one checkbox should be selected.
<div *ngFor="let item of officeLIST">
<div *ngIf=" item.officeID == 1">
<input #off type="checkbox" id="off" name="off" value="1" [(ngModel)]="item.checked">
<label>{{item.officename}}</label>
</div>
<div *ngIf="item.officeID== 2">
<input #off type="checkbox" id="off" name="off" value="2" [(ngModel)]="item.checked">
<label>{{item.officename}}</label>
</div>
<div *ngIf="item.officeID== 3">
<input #off type="checkbox" id="off" name="off" value="3" [(ngModel)]="item.checked">
<label>{{item.officename}}</label>
</div>
</div>
for other field I will put required and do the error|touched|valid etc. but since checkbox is not single input, I cannot put required in every checkbox because all checkbox will be compulsory to checked. so how do I do the validation to alert user atleast one should be checked?
The accepted answer abuses stuff to use in a way they are not meant to be. With reactive forms the best, easiest and probably right way is to use a FormGroup that holds your grouped checkboxes and create a validator to check if at least one(or more) checkbox is checked within that group.
To do so just create another FormGroup inside your existing FormGroup and attach a validator to it:
form = new FormGroup({
// ...more form controls...
myCheckboxGroup: new FormGroup({
myCheckbox1: new FormControl(false),
myCheckbox2: new FormControl(false),
myCheckbox3: new FormControl(false),
}, requireCheckboxesToBeCheckedValidator()),
// ...more form controls...
});
And here is the validator. I made it so you can even use it to check if at least X checkboxes are checked, e.g. requireCheckboxesToBeCheckedValidator(2):
import { FormGroup, ValidatorFn } from '#angular/forms';
export function requireCheckboxesToBeCheckedValidator(minRequired = 1): ValidatorFn {
return function validate (formGroup: FormGroup) {
let checked = 0;
Object.keys(formGroup.controls).forEach(key => {
const control = formGroup.controls[key];
if (control.value === true) {
checked ++;
}
});
if (checked < minRequired) {
return {
requireCheckboxesToBeChecked: true,
};
}
return null;
};
}
In your template don't forget to add the directive 'formGroupName' to wrap your checkboxes. But don't worry, the compiler will remind you with an error-message if you forget. You can then check if the checkbox-group is valid the same way you do on FormControl's:
<ng-container [formGroup]="form">
<!-- ...more form controls... -->
<div class="form-group" formGroupName="myCheckboxGroup">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" formControlName="myCheckbox1" id="myCheckbox1">
<label class="custom-control-label" for="myCheckbox1">Check</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" formControlName="myCheckbox2" id="myCheckbox2">
<label class="custom-control-label" for="myCheckbox2">At least</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" formControlName="myCheckbox3" id="myCheckbox3">
<label class="custom-control-label" for="myCheckbox3">One</label>
</div>
<div class="invalid-feedback" *ngIf="form.controls['myCheckboxGroup'].errors && form.controls['myCheckboxGroup'].errors.requireCheckboxesToBeChecked">At least one checkbox is required to check</div>
</div>
<!-- ...more form controls... -->
</ng-container>
*This template is very static. Of course you could create it dynamically by using an additional array that holds the the form-data(key of FormControl, label, required, etc.) and create the template automatically by use of ngFor.
Please don't abuse hidden FormControl's like in the accepted answer. A FormControl is not meant to store data like id, label, help-text etc. and doesnt even have a name/key. All this, and much more, should be stored separate, e.g. by a regular array of objects. A FormControl only holds an input-value and provides all this cool state's and functions.
I created a working example you can play with: https://stackblitz.com/edit/angular-at-least-one-checkbox-checked
consider creating a FormGroup which contains your check-box group and bind the group's checked value to a hidden formcontrol with a required validator.
Assume that you have three check boxes
items = [
{key: 'item1', text: 'value1'}, // checkbox1 (label: value1)
{key: 'item2', text: 'value2'}, // checkbox2 (label: value2)
{key: 'item3', text: 'value3'}, // checkbox3 (label: value3)
];
Step1: define FormArray for your check boxes
let checkboxGroup = new FormArray(this.items.map(item => new FormGroup({
id: new FormControl(item.key), // id of checkbox(only use its value and won't show in html)
text: new FormControl(item.text), // text of checkbox(show its value as checkbox's label)
checkbox: new FormControl(false) // checkbox itself
})));
*easy to show via ngFor
Step2: create a hidden required formControl to keep status of checkbox group
let hiddenControl = new FormControl(this.mapItems(checkboxGroup.value), Validators.required);
// update checkbox group's value to hidden formcontrol
checkboxGroup.valueChanges.subscribe((v) => {
hiddenControl.setValue(this.mapItems(v));
});
we only care about hidden control's required validate status and won't show this hidden control in html.
Step3: create final form group contains below checkbox group and hidden formControl
this.form = new FormGroup({
items: checkboxGroup,
selectedItems: hiddenControl
});
Html Template:
<form [formGroup]="form">
<div [formArrayName]="'items'" [class.invalid]="!form.controls.selectedItems.valid">
<div *ngFor="let control of form.controls.items.controls; let i = index;" [formGroup]="control">
<input type="checkbox" formControlName="checkbox" id="{{ control.controls.id.value }}">
<label attr.for="{{ control.controls.id.value }}">{{ control.controls.text.value }}</label>
</div>
</div>
<div [class.invalid]="!form.controls.selectedItems.valid" *ngIf="!form.controls.selectedItems.valid">
checkbox group is required!
</div>
<hr>
<pre>{{form.controls.selectedItems.value | json}}</pre>
</form>
refer this demo.
I had the same problem and this is the solution I ended up using with Angular 6 FormGroup because I had few checkboxes.
HTML
Note: I'm using Angular Material for styling, change as needed.
<form [formGroup]="form">
<mat-checkbox formControlName="checkbox1">First Checkbox</mat-checkbox>
<mat-checkbox formControlName="checkbox2">Second Checkbox</mat-checkbox>
<mat-checkbox formControlName="checkbox3">Third Checkbox</mat-checkbox>
</form>
TypeScript
form: FormGroup;
constructor(private formBuilder: FormBuilder){}
ngOnInit(){
this.form = this.formBuilder.group({
checkbox1: [''],
checkbox2: [''],
checkbox3: [''],
});
this.form.setErrors({required: true});
this.form.valueChanges.subscribe((newValue) => {
if (newValue.checkbox1 === true || newValue.checkbox2 === true || newValue.checkbox3 === true) {
this.form.setErrors(null);
} else {
this.form.setErrors({required: true});
}
});
}
Basically, subscribe to any changes in the form and then modify the errors as needed according to the new form values.
On validation (i.e for example some click event) iterate over your array and check whether at least one item is true.
let isSelected: any = this.officeLIST.filter((item) => item.checked === true);
if(isSelected != null && isSelected.length > 0) {
//At least one is selected
}else {
alert("select at least one");
}
Add (ngModelChange)="onChange(officeLIST)" to your checkbox and have below code in your .ts file.
onChange(items) {
var found = items.find(function (x) { return x.checked === true; });
if (found)
this.isChecked = true;
else
this.isChecked = false;
}
Use isChecked variable any places you want.
I implemented a similar solution to the current accepted version proposed by Mick(using FormGroup and a custom Validator), but if you're like me and aren't going to need to handle showing an error for quantities checked > 0, you can simplify the Validator a lot:
export function checkboxGroupValidator(): ValidatorFn {
return (formGroup: FormGroup) => {
const checkedKeys = Object.keys(formGroup.controls).filter((key) => formGroup.controls[key].value);
if (checkedKeys.length === 0) { return { requireCheckboxesToBeChecked: true }; }
return null;
};
}
You should be checking the touched and dirty conditions of the form element
<form #myForm="ngForm" *ngIf="active" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" class="form-control"
required name="name" [(ngModel)]="myform.name"
#name="ngModel" >
<div *ngIf="name.errors && (name.dirty || name.touched)"
class="alert alert-danger">
<div [hidden]="!name.errors.required">
Name is required
</div>
</div>
</div>
</form>
You can combine the previous and my answer for both scenarios
I'm using this method: http://plnkr.co/edit/A6gvyoXbBd2kfToPmiiA?p=preview to only validate fields on blur. This works fine, but I would also like to validate them (and thus show the errors for those fields if any) when the user clicks the 'submit' button (not a real submit but a data-ng-click call to a function)
Is there some way to trigger validation on all the fields again when clicking that button?
What worked for me was using the $setSubmitted function, which first shows up in the angular docs in version 1.3.20.
In the click event where I wanted to trigger the validation, I did the following:
vm.triggerSubmit = function() {
vm.homeForm.$setSubmitted();
...
}
That was all it took for me. According to the docs it "Sets the form to its submitted state." It's mentioned here.
I know, it's a tad bit too late to answer, but all you need to do is, force all forms dirty. Take a look at the following snippet:
angular.forEach($scope.myForm.$error.required, function(field) {
field.$setDirty();
});
and then you can check if your form is valid using:
if($scope.myForm.$valid) {
//Do something
}
and finally, I guess, you would want to change your route if everything looks good:
$location.path('/somePath');
Edit: form won't register itself on the scope until submit event is trigger. Just use ng-submit directive to call a function, and wrap the above in that function, and it should work.
In case someone comes back to this later... None of the above worked for me. So I dug down into the guts of angular form validation and found the function they call to execute validators on a given field. This property is conveniently called $validate.
If you have a named form myForm, you can programmatically call myForm.my_field.$validate() to execute field validation. For example:
<div ng-form name="myForm">
<input required name="my_field" type="text" ng-blur="myForm.my_field.$validate()">
</div>
Note that calling $validate has implications for your model. From the angular docs for ngModelCtrl.$validate:
Runs each of the registered validators (first synchronous validators and then asynchronous validators). If the validity changes to invalid, the model will be set to undefined, unless ngModelOptions.allowInvalid is true. If the validity changes to valid, it will set the model to the last available valid $modelValue, i.e. either the last parsed value or the last value set from the scope.
So if you're planning on doing something with the invalid model value (like popping a message telling them so), then you need to make sure allowInvalid is set to true for your model.
You can use Angular-Validator to do what you want. It's stupid simple to use.
It will:
Only validate the fields on $dirty or on submit
Prevent the form from being submitted if it is invalid
Show custom error message after the field is $dirty or the form is submitted
See the demo
Example
<form angular-validator
angular-validator-submit="myFunction(myBeautifulForm)"
name="myBeautifulForm">
<!-- form fields here -->
<button type="submit">Submit</button>
</form>
If the field does not pass the validator then the user will not be able to submit the form.
Check out angular-validator use cases and examples for more information.
Disclaimer: I am the author of Angular-Validator
Well, the angular way would be to let it handle validation, - since it does at every model change - and only show the result to the user, when you want.
In this case you decide when to show the errors, you just have to set a flag:
http://plnkr.co/edit/0NNCpQKhbLTYMZaxMQ9l?p=preview
As far as I know there is a issue filed to angular to let us have more advanced form control. Since it is not solved i would use this instead of reinventing all the existing validation methods.
edit: But if you insist on your way, here is your modified fiddle with validation before submit. http://plnkr.co/edit/Xfr7X6JXPhY9lFL3hnOw?p=preview
The controller broadcast an event when the button is clicked, and the directive does the validation magic.
One approach is to force all attributes to be dirty. You can do that in each controller, but it gets very messy. It would be better to have a general solution.
The easiest way I could think of was to use a directive
it will handle the form submit attribute
it iterates through all form fields and marks pristine fields dirty
it checks if the form is valid before calling the submit function
Here is the directive
myModule.directive('submit', function() {
return {
restrict: 'A',
link: function(scope, formElement, attrs) {
var form;
form = scope[attrs.name];
return formElement.bind('submit', function() {
angular.forEach(form, function(field, name) {
if (typeof name === 'string' && !name.match('^[\$]')) {
if (field.$pristine) {
return field.$setViewValue(field.$value);
}
}
});
if (form.$valid) {
return scope.$apply(attrs.submit);
}
});
}
};
});
And update your form html, for example:
<form ng-submit='justDoIt()'>
becomes:
<form name='myForm' novalidate submit='justDoIt()'>
See a full example here: http://plunker.co/edit/QVbisEK2WEbORTAWL7Gu?p=preview
Here is my global function for showing the form error messages.
function show_validation_erros(form_error_object) {
angular.forEach(form_error_object, function (objArrayFields, errorName) {
angular.forEach(objArrayFields, function (objArrayField, key) {
objArrayField.$setDirty();
});
});
};
And in my any controllers,
if ($scope.form_add_sale.$invalid) {
$scope.global.show_validation_erros($scope.form_add_sale.$error);
}
Based on Thilak's answer I was able to come up with this solution...
Since my form fields only show validation messages if a field is invalid, and has been touched by the user I was able to use this code triggered by a button to show my invalid fields:
// Show/trigger any validation errors for this step
angular.forEach(vm.rfiForm.stepTwo.$error, function(error) {
angular.forEach(error, function(field) {
field.$setTouched();
});
});
// Prevent user from going to next step if current step is invalid
if (!vm.rfiForm.stepTwo.$valid) {
isValid = false;
}
<!-- form field -->
<div class="form-group" ng-class="{ 'has-error': rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched && rfi.rfiForm.stepTwo.Parent_Suffix__c.$invalid }">
<!-- field label -->
<label class="control-label">Suffix</label>
<!-- end field label -->
<!-- field input -->
<select name="Parent_Suffix__c" class="form-control"
ng-options="item.value as item.label for item in rfi.contact.Parent_Suffixes"
ng-model="rfi.contact.Parent_Suffix__c" />
<!-- end field input -->
<!-- field help -->
<span class="help-block" ng-messages="rfi.rfiForm.stepTwo.Parent_Suffix__c.$error" ng-show="rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched">
<span ng-message="required">this field is required</span>
</span>
<!-- end field help -->
</div>
<!-- end form field -->
Note: I know this is a hack, but it was useful for Angular 1.2 and earlier that didn't provide a simple mechanism.
The validation kicks in on the change event, so some things like changing the values programmatically won't trigger it. But triggering the change event will trigger the validation. For example, with jQuery:
$('#formField1, #formField2').trigger('change');
I like the this approach in handling validation on button click.
There is no need to invoke anything from controller,
it's all handled with a directive.
on github
You can try this:
// The controller
$scope.submitForm = function(form){
//Force the field validation
angular.forEach(form, function(obj){
if(angular.isObject(obj) && angular.isDefined(obj.$setDirty))
{
obj.$setDirty();
}
})
if (form.$valid){
$scope.myResource.$save(function(data){
//....
});
}
}
<!-- FORM -->
<form name="myForm" role="form" novalidate="novalidate">
<!-- FORM GROUP to field 1 -->
<div class="form-group" ng-class="{ 'has-error' : myForm.field1.$invalid && myForm.field1.$dirty }">
<label for="field1">My field 1</label>
<span class="nullable">
<select name="field1" ng-model="myresource.field1" ng-options="list.id as list.name for list in listofall"
class="form-control input-sm" required>
<option value="">Select One</option>
</select>
</span>
<div ng-if="myForm.field1.$dirty" ng-messages="myForm.field1.$error" ng-messages-include="mymessages"></div>
</div>
<!-- FORM GROUP to field 2 -->
<div class="form-group" ng-class="{ 'has-error' : myForm.field2.$invalid && myForm.field2.$dirty }">
<label class="control-label labelsmall" for="field2">field2</label>
<input name="field2" min="1" placeholder="" ng-model="myresource.field2" type="number"
class="form-control input-sm" required>
<div ng-if="myForm.field2.$dirty" ng-messages="myForm.field2.$error" ng-messages-include="mymessages"></div>
</div>
</form>
<!-- ... -->
<button type="submit" ng-click="submitForm(myForm)">Send</button>
I done something following to make it work.
<form name="form" name="plantRegistrationForm">
<div ng-class="{ 'has-error': (form.$submitted || form.headerName.$touched) && form.headerName.$invalid }">
<div class="col-md-3">
<div class="label-color">HEADER NAME
<span class="red"><strong>*</strong></span></div>
</div>
<div class="col-md-9">
<input type="text" name="headerName" id="headerName"
ng-model="header.headerName"
maxlength="100"
class="form-control" required>
<div ng-show="form.$submitted || form.headerName.$touched">
<span ng-show="form.headerName.$invalid"
class="label-color validation-message">Header Name is required</span>
</div>
</div>
</div>
<button ng-click="addHeader(form, header)"
type="button"
class="btn btn-default pull-right">Add Header
</button>
</form>
In your controller you can do;
addHeader(form, header){
let self = this;
form.$submitted = true;
...
}
You need some css as well;
.label-color {
color: $gray-color;
}
.has-error {
.label-color {
color: rgb(221, 25, 29);
}
.select2-choice.ui-select-match.select2-default {
border-color: #e84e40;
}
}
.validation-message {
font-size: 0.875em;
}
.max-width {
width: 100%;
min-width: 100%;
}
To validate all fields of my form when I want, I do a validation on each field of $$controls like this :
angular.forEach($scope.myform.$$controls, function (field) {
field.$validate();
});