19

If I submit a form using button type="submit" the form validation messages appear and everything is fine. However if I have a button (or link) with (click)="myhandler()" then the validations do not appear.

How can I either:

  • tag the element as requiring validators to run, or
  • programatically run and show validation messages.

Note: These are simple validations like required on input fields.

Sample Code:

<form (ngSubmit)="save()">                       
  <input required type='text' [(ngModel)]="name">
  <!-- Shows validation messages but still calls save() -->
  <button (click)="save()">Click</button>  
  <!-- Only submits if valid and shows messages -->       
  <button type="submit">Submit</button>         
</form>
<!-- does not even show validation messages, just calls save -->
<button (click)="save()">Click 2</button>  
3
  • please provide code. I think problem is with your code. Commented Apr 12, 2016 at 10:03
  • its button type 'submit' or its an simple button, does related with validation, provide your code work we will help you Commented Apr 12, 2016 at 10:16
  • ans is short hope helps, add a hidden div based on form.validate i.e <div [hidden]="!form.validate">{{warningMessage}}</div> Commented Apr 12, 2016 at 11:51

7 Answers 7

24

Please note: this approach is for reactive forms.

I used markAsTouched() property to run validations on a button click.

Suppose the following button is outside the form:

<button type="button" (click)="validateForm()">Submit</button>

Now, in the validateForm method if the form is invalid, you can set markAsTouched() property for each of the form controls and angular will show validation messages.

validateForm() {
    if (this.myformGroup.invalid) {
      this.myformGroup.get('firstName').markAsTouched();
      this.myformGroup.get('surname').markAsTouched();
      return;
    }
    // do something else
}

provided you have validation messages setup in your html like

<mat-error *ngIf="myformGroup.get('firstName').hasError('required')">
  first name is required
</mat-error>

and you have required field validation setup in your form group builder like

firstName: ['', Validators.required]
Sign up to request clarification or add additional context in comments.

Comments

3

Below Code Will Help You .. Tested with Angular 4 Latest version 4.2.4

<form method="post" #f="ngForm" name="form" novalidate="novalidate" class="form">
   <div class="row">
      <div class="form-group col-sm-12" [ngClass]="{'has-error':!listname.valid && (listname.dirty || listname.touched || f.submitted)}">
         <label for="listname">Name</label>
         <input id="listname" name="listname" type="text" [(ngModel)]="listData.title"
         required="true" placeholder="List Name" #listname="ngModel" class="form-control"/>
      </div>
   </div>
   <div class="row">
      <div class="form-group text-right col-md-12 visible-md visible-lg">
         <button type="button"  name="save"  (click)="f._submitted = true;saveAndPublish=false;saveList(f.valid)" class="btn btn-default">Save
         Save List
         </button>
         <button type="button"  name="saveandpublish" (click)="f._submitted = true;saveAndPublish=true;saveList(f.valid);" class="btn btn-primary">Save
         & Publish  List
         </button>
      </div>
   </div>
</form>

in Your .ts File

saveList(isValid: boolean) {
    if (isValid) {
      console.log(this.listData)
    }

  }

1 Comment

should be (click)="f.submitted...' instead of (click)="f._submitted...' Best answer.Thanks
2

Button with type submit triggers form submit automatically, i guess you have to trigger form submit manually:

<form (ngSubmit)="save()" #form="ngForm">

<button (click)="form.onSubmit()">Click 2</button> 

Why "ngForm"? A directive's exportAs property tells Angular how to link local variable to the directive. We set name to ngForm because the NgControlName directive's exportAs property happens to be "ngForm".

documentation

3 Comments

I tried <form... #myform> and on the button <button (click)="myform.submit()" and this did not run the validators.
nope, that gives error: 'onSubmit is not a function'
lets add #form="ngForm".
1

You should keep the button disabled until the form is valid. So in your case change your form element opening tag to create a variable for the form:

<form (ngSubmit)="save()" #myForm="ngForm">  

and disable the button when the form isn't valid

<button (click)="save()" [disabled]="!myForm.form.valid">Click 2</button>

Let me know if that works. As the form itself will validate automatically and constantly in anycase, you dont need to call for it to be done.

1 Comment

This looks promising but I dont want to disable the button, I want it to trigger the nice pop up messages. Does NgForm have a runValidatorsAndSubmit or something? Would like to do: <button (click)="myForm.runValidatorsAndSubmit()" if its available. I dumped the ngForm to the console but found nothing like that.
1

put conditions in [hidden] directive and change submitted property to true on submit!

<div [hidden]="email.valid || (email.untouched && !submitted) || !submitted" class="alert callout">
    <span [hidden]="!email.hasError('required')">Required</span>
</div>

onSubmit(){
   this.submitted = true
}

2 Comments

Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this". We make an effort here to be a resource for knowledge.
onSubmit() will not be called if the form is invalid.
0

Put your click2 button within form tag. It will start working !

<form (ngSubmit)="save()">                       
  <input required type='text' [(ngModel)]="name">
  <!-- Shows validation messages but still calls save() -->
  <button (click)="save()">Click</button>  
  <!-- Only submits if valid and shows messages -->       
  <button type="submit">Submit</button>     
  <!-- this will work now -->
  <button (click)="save()">Click 2</button>      
</form>

4 Comments

I have it outside on purpose, moving it inside however still calls save (as shown in the first button)
FYI...In your example you are not using angular2 for validation. The way you do it , it uses HTML5 for the validation. To validate for with Angular2, you have to deal with ngFormModel,formBuilder,ngControl directives. this might help you - plnkr.co/edit/oP0A8vWFHsZ4y5A7uUQP?p=preview.
Well that could be where I'm going wrong, perhaps the 'nice pop up' messages are HTML5!! Thanks, at least an avenue for investigateion
Thanks, I looked at your example a find out that I accidentally has added <a> instead of <button> to submit form, and validations were not executed
0

Programatically check and disable using validation

<form class="form-horizontal" id='myForm' role="form" [ngFormModel]="CreateGroup">
  <div class="col-md-7">
    Name: <input type="text" [(ngModel)]='demoInfo.name' class="form-control" ngControl='name'>
  </div>
  Form Valid : {{CreateGroup.valid}} 
</form>
<br>
<div class='text-center'>
  <button type="button" [disabled]='!CreateGroup.valid' (click)="addNewGroup(demoInfo)" class="btn btn-primary">Create</button>
</div>

working example http://plnkr.co/edit/aoHHw709VeMlP8Qfgnp6?p=preview

2 Comments

the problem with disabling the button is that the nice pop up messages do not show.
Yes if a required field is empty and you submit the form a nice 'Please fill in this field' pop up appears. I like that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.