How to conditionally require form inputs in angular 4?

Viewed 33604

I am using template driven forms for adding the task, and there are 2 input fields of type number for estimated mins to complete task,

  • one field is for estimated number of hrs and
  • another is for estimated minutes to complete the task

since the task estimate can be done either in hours like 1hrs , or in hours and minutes like 1Hrs 30Mins , so i want to set attribute required to inputs conditionally. So one of the 2 inputs must be set or form validation error will occur if both inputs are empty when submitting form.

so far i have done this but validation is not working

<form class="add-task" (ngSubmit)="onSubmit(newtask)" #newtask="ngForm">  
    <div class="estimate-container">
        <input 
            type="number" 
            min="0" 
            max="10" 
            id="estimate_hrs" 
            ngModel 
            name="estimate_hrs"
            mdInput 
            [required]="!estimateMins.valid" 
            placeholder="Estimated Hours" 
            #estimateHrs="ngModel"
        >
        <div class="error-msg" *ngIf="!estimateHrs.valid && !estimateMins.valid">
            Please enter estimated hours 
        </div>
        <input 
            type="number" 
            min="0" 
            max="60" 
            id="estimate_min" 
            ngModel 
            name="estimate_min" 
            mdInput 
            [required]="!estimateHrs.valid" 
            placeholder="Estimated Minutes" 
            #estimateMins="ngModel"
        >
        <div class="error-msg" *ngIf="!estimateMins.valid && !estimateHrs.valid">
            Please enter estimated minutes
        </div>   
    </div>
    <button type='submit' [disabled]="!newtask.valid" >Submit</button>
</form>
6 Answers

This is my working solution for Angular 5:

In component:

@Input()
required: boolean;

In template on the input (or select) element that:

[required]="required"

On the selector:

[required]="true"

Like @DeborahK double checked, no need for single quotes :-)

In angular2 or above you can use ngNativeValidate directive for template driven form. And also object to reserved and sending data(though it's your personal choice but i love this way) to api.

<form class="add-task" #newtask="ngForm" ngNativeValidate (ngSubmit)="onSubmit()">  

    <div class="estimate-container">
        <input 
            type="number" 
            min="0" 
            max="10" 
            id="estimate_hrs" 
            name="estimate_hrs"
            mdInput 
            [required]="!taskModel.estimateMins" 
            placeholder="Estimated Hours" 
            [(ngModel)]="taskModel.estimateHrs">

        <div class="error-msg" *ngIf="!taskModel.estimateHrs && !taskModel.estimateMins">
            Please enter estimated hours 
        </div>
        <input 
            type="number" 
            min="0" 
            max="60" 
            id="estimate_min" 
            name="estimate_min" 
            mdInput 
            [required]="!taskModel.estimateHrs" 
            placeholder="Estimated Minutes" 
            [(ngModel)]="taskModel.estimateMins">

        <div class="error-msg" *ngIf="!taskModel.estimateMins && !taskModel.estimateHrs">
            Please enter estimated minutes
        </div>   
    </div>
    <button type='submit' [disabled]="!newtask.valid" [isFormValid]="!newtask.valid">Submit</button>
</form>

In .ts file

taskModel: any;

onSubmit(){
    
    console.log(this.taskModel) // this object has all data.
}

You can also achieve the same with in AngularJS (version 1.x)

<form id="form" name="form" class="add-task" ng-init="taskModel={}">

    <div class="estimate-container">
        <input 
            type="number" 
            min="0" 
            max="10" 
            id="estimate_hrs" 
            name="estimate_hrs"
            mdInput 
            ng-required="!taskModel.estimateMins" 
            placeholder="Estimated Hours" 
            ng-model="taskModel.estimateHrs">

        <div class="error-msg" ng-if="!taskModel.estimateHrs && !taskModel.estimateMins">
            Please enter estimated hours 
        </div>
        <input 
            type="number" 
            min="0" 
            max="60" 
            id="estimate_min" 
            name="estimate_min" 
            mdInput 
            ng-required="!taskModel.estimateHrs" 
            placeholder="Estimated Minutes" 
            ng-model="taskModel.estimateMins">

        <div class="error-msg" ng-if="!taskModel.estimateMins && !taskModel.estimateHrs">
            Please enter estimated minutes
        </div>   
    </div>
    <button ng-disabled="form.$valid" ng-click="form.$valid && onSubmit()" >Submit</button>
</form>

Hope it's helpful to you!

Related