1
votes

I have created a basic form that contains various input elements (mainly text) all of the text boxes have the 'Required' attribute set plus a simple regex pattern. Using Angular 2's Form directive I am disabling a button if the field text inputs are empty or the regex is not met. This works as expected. However, thrown into the mix is a 'Select' element with 2 'Option' child elements. The first is my default and the second my data bound list. I would like to set the form.invalid property to true if the initial:

<option value="default">Select a department...</option>

is selected from the combo box.

My issue as it stands is that if I enter valid data into all of my text boxes but leave the combo box as 'Select a department...' the form.invalid property is false and the button is enabled. As 'Select a department...' is not a valid value I need the button to become disabled if that is selected?

Current HTML select code as it stands

    <form class="form-inline" #form="ngForm" novalidate>
      <div class="col-sm-12">          
        <div class="form-group" [class.has-error]="AddfirstName.invalid && AddfirstName.touched">
          <label class="col-sm-12 control-label" for="AddfirstName">First Name:</label>
          <div class="col-sm-12">
            <input class="form-control" #AddfirstName="ngModel" required pattern="\D+" placeholder="First Name" [ngModel]="firstName" (ngModelChange)="firstLetterOfFirstNameToUpperCase($event)"
              name="firstName">
            <div class="alert alert-danger" *ngIf="AddfirstName.invalid && AddfirstName.touched ">First Name Is mandatory and cannot contain numbers</div>
          </div>
        </div>
       <div class="form-group" [class.has-error]="AddlastName.invalid && AddlastName.touched">
          <label class="col-sm-12 control-label" for="AddlastName">Last Name:</label>
          <div class="col-sm-12">
            <input class="form-control" #AddlastName="ngModel" required pattern="\D+" placeholder="Last Name" [ngModel]="lastName" (ngModelChange)="firstLetterOfLastNameToUpperCase($event)"
              name="lastName" />
            <div class="alert alert-danger" *ngIf="AddlastName.invalid && AddlastName.touched ">Last Name Is mandatory and cannot contain numbers </div>
          </div>
        </div>
      </div>
      <div class="col-sm-12">
        <div class="form-group" [class.has-error]="AdduserName.invalid && AdduserName.touched">
          <label class="col-sm-12 control-label" for="AdduserName">User Name:</label>
          <div class="col-sm-12">
            <input class="form-control" #AdduserName="ngModel" required placeholder="User Name" ngModel name="userName" />
            <div class="alert alert-danger" *ngIf="AdduserName.invalid && AdduserName.touched">User Name Is mandatory</div>
          </div>
        </div>
        <div class="form-group"[class.has-error]="Addpassword.invalid && Addpassword.touched">
          <label class="col-sm-12 control-label" for="Addpassword">Password:</label>
          <div class="col-sm-12">
            <input type="password" class="form-control" #Addpassword="ngModel" required placeholder="Password" ngModel name="password" />
            <div class="alert alert-danger" *ngIf="Addpassword.invalid && Addpassword.touched ">Password Is mandatory</div>
          </div>
        </div>
      </div>
     <div class="col-sm-12">
        <div class="form-group" [class.has-error]="hasDepartmentError">
          <label class="col-sm-12 control-label" for="Department">Department:</label>
          <div class="col-sm-12">
            <select class="form-control" id="Department" #AddDepartment="ngModel" [(ngModel)]="addDepartment"
            [ngModelOptions]="{standalone: true}"
            (change)="validateDepartment(AddDepartment.value)"  
            (blur)="validateDepartment(AddDepartment.value)">
            <option value="default">Select a department...</option>
             <option *ngFor="let department of departmentList">{{department.name}}</option>
          </select>
          <div class="alert alert-danger" *ngIf="hasDepartmentError">Department Is mandatory</div>
          </div>
        </div>
      </div>
    <div class="col-sm-12">
      <button class="btn btn-primary" (click)="addUser(AddfirstName.value, AddlastName.value, AdduserName.value, Addpassword.value, AddDepartment.value);
        AddfirstName.value=null;AddlastName.value=null;Addpassword.value=null;AdduserName.value=null;" [disabled]="form.invalid">Add</button>
    </div>
  </form>
    </div>
     </div>
2

2 Answers

1
votes

Remove the value from your first option and mark your select required:

<select class="form-control" id="Department" #AddDepartment="ngModel" [(ngModel)]="addDepartment"
        [ngModelOptions]="{standalone: true}"
        (change)="validateDepartment(AddDepartment.value)"  
        (blur)="validateDepartment(AddDepartment.value)"
        required>
        <option>Select a department...</option>
         <option *ngFor="let department of departmentList">{{department.name}}</option>
      </select>
0
votes

Seems you have forgotten to put required on your select. Your two-way binding also seems to take away the default value of the drop down list, so I would loose that and just use ngModel instead. You really don't need to use two-way binding in forms, the form names take care of that, and when you submit the form, you have a nice object to work with.

when you loose the ngModel, you also drop the ngModelOptions and use the name attribute instead, which would be needed for the form.

I'm also unsure about the validateDepartment method. You wouldn't need it, as you can validate this in the template.

So all in all the final snippet of your select could look like this:

<select required #addDepartment="ngModel" name="addDepartment" ngModel>
  <option value="">Select a department...</option>
  <option *ngFor="let department of departmentList">{{department.name}}</option>
</select> 

<div *ngIf="addDepartment.errors?.required">
  Department required!
</div>

Here's a

Plunker

to play with, where you can also see the object created from the form! :)