Sunday, October 31, 2021

Angular 12 select box with default value, required validator and state-city dependency



import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-mycomponent',
  templateUrl: './mycomponent.component.html',
  styleUrls: ['./mycomponent.component.css']
})
export class MycomponentComponent implements OnInit {

  masterSexList = [{id : 1 , name : "Male"} , {id : 2 , name : "Female"}];
  masterStateList = [{id : 1 , name : "Maharashtra"} , {id : 2 , name : "Rajasthan"}];
  masterCityList  = [
      {id : 1 , name : "Mumbai" , stateId : 1},
      {id : 2 , name : "Pune", stateId : 1},
      {id : 3 , name : "Jaipur" , stateId : 2},
      {id : 4 , name : "Udaipur" , stateId : 2}
    ];
  cityList : any;
  frm  = this.fb.group({
    firstName : ["" ,
      [Validators.required , Validators.minLength(3) , Validators.maxLength(6)]
    ],
    lastName : ["" ,[Validators.required]],
    sex : [2 , [Validators.required]],  //Default value of 2 corresponds to Female
    state : ["" , [Validators.required]],
    city : ["" , [Validators.required]]
  });

  selectedStateId : number = 0;  
  selectedCityId : number = 0;
  selectedSexId : number = 0;

  constructor(private fb : FormBuilder) { }

  ngOnInit(): void {
    //THIS ALSO WORKS => you should pass the id of the object you want to be selected.
    //this.frm.get('sex')?.patchValue(1);
  }

  submit()
  {
    alert(
      this.frm.get('firstName')?.value + " " +
      this.frm.get('lastName')?.value + " " +
      this.selectedStateId + " " +
      this.selectedCityId + " " +
      this.selectedSexId
      );
  }

  onSexChange(sexChangeEvent: any)
  {
    this.selectedSexId = sexChangeEvent.target.value;
  }


  onCityChange(cityChangeEvent: any)
  {
    this.selectedCityId = cityChangeEvent.target.value;
  }

  onStateChange(stateChangeEvent: any)
  {
    this.selectedStateId = stateChangeEvent.target.value;
    if ( this.selectedStateId != undefined && this.selectedStateId != null
    && this.selectedStateId > 0)
      this.cityList = this.masterCityList.filter(x=>x.stateId == this.selectedStateId)
  }
}



<p>mycomponent works!</p>

<form [formGroup] = "frm" (ngSubmit)="submit()">
    <table>
        <tr>
            <td>
                <label>First Name</label>
            </td>
            <td>
                <input type="text" formControlName="firstName" />
            </td>
        </tr>

        <tr>
            <td>
                <label>Last Name</label>
            </td>
            <td>
                <input type="text" formControlName="lastName" />                
            </td>
        </tr>

        <tr>
            <td>
                <label>Sex</label>
            </td>
            <td>
                <select formControlName="sex" (change)="onSexChange($event)">
                    <option *ngFor="let sex of masterSexList; let  i = index" [value]="sex.id" >{{sex.name}}</option>
                </select>
            </td>
        </tr>

        <tr>
            <td>
                <label>State</label>
            </td>
            <td>
                <select formControlName="state" (change)="onStateChange($event)">
                    <option value="">Choose your state</option>
                    <option *ngFor="let state of masterStateList" [value]="state.id">{{state.name}}</option>
                </select>
            </td>
        </tr>

        <tr>
            <td>
                <label>City</label>
            </td>
            <td>
                <select formControlName="city" (change)="onCityChange($event)">
                    <option value="">Choose your city</option>
                    <option *ngFor="let city of cityList" [value]="city.id">{{city.name}}</option>
                </select>
            </td>
        </tr>

        <tr>
            <td colspan="2">
                <button type="submit"  [disabled] = "!frm.valid">Submit</button>
            </td>
        </tr>

    </table>
</form>






 

Angular 12 select box binding to an object list

 In this sample the city field binds with CityList which is a list of objects consisting of id and names.

Required field validator is applied.



import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-mycomponent',
  templateUrl: './mycomponent.component.html',
  styleUrls: ['./mycomponent.component.css']
})
export class MycomponentComponent implements OnInit {

  CityList  = [
      {id : 1 , name : "Mumbai"},
      {id : 2 , name : "Pune"},
      {id : 3 , name : "Delhi"},
      {id : 4 , name : "Calcutta"}
    ];
  frm  = this.fb.group({
    firstName : ["" ,
      [Validators.required , Validators.minLength(3) , Validators.maxLength(6)]
    ],
    lastName : ["" ,[Validators.required]],
    city : ["" , [Validators.required]]
  });

  selectedCityId : number = 0;

  constructor(private fb : FormBuilder) { }

  ngOnInit(): void {
  }

  submit()
  {
    alert(
      this.frm.get('firstName')?.value + " " +
      this.frm.get('lastName')?.value + " " +
      this.selectedCityId
      );
  }

  onCityChange(event: any)
  {
    this.selectedCityId = event.target.value;
  }

}



<p>mycomponent works!</p>

<form [formGroup] = "frm" (ngSubmit)="submit()">
    <table>
        <tr>
            <td>
                <label>First Name</label>
            </td>
            <td>
                <input type="text" formControlName="firstName" />
            </td>
        </tr>

        <tr>
            <td>
                <label>Last Name</label>
            </td>
            <td>
                <input type="text" formControlName="lastName" />                
            </td>
        </tr>


        <tr>
            <td>
                <label>City</label>
            </td>
            <td>
                <select formControlName="city" (change)="onCityChange($event)">
                    <option value="">Choose your city</option>
                    <option *ngFor="let city of CityList" [value]="city.id">
                    {{city.name}}</option>
                </select>
            </td>
        </tr>

        <tr>
            <td colspan="2">
                <button type="submit"  [disabled] = "!frm.valid">Submit</button>
            </td>
        </tr>

    </table>
</form>







Angular 12 select box with a simple string list binding


Most Basic angular select box which binds to a list of strings. It has a "Choose" option and a required validator applied.

 

<p>mycomponent works!</p>

<form [formGroup] = "frm" (ngSubmit)="submit()">
    <table>
        <tr>
            <td>
                <label>First Name</label>
            </td>
            <td>
                <input type="text" formControlName="firstName" />
            </td>
        </tr>

        <tr>
            <td>
                <label>Last Name</label>
            </td>
            <td>
                <input type="text" formControlName="lastName" />                
            </td>
        </tr>


        <tr>
            <td>
                <label>City</label>
            </td>
            <td>
                <select formControlName="city">
                    <option value="">Choose your city</option>
                    <option *ngFor="let city of CityList" [ngValue]="city">{{city}}</option>
                </select>
            </td>
        </tr>

        <tr>
            <td colspan="2">
                <button type="submit"  [disabled] = "!frm.valid">Submit</button>
            </td>
        </tr>

    </table>
</form>


import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-mycomponent',
  templateUrl: './mycomponent.component.html',
  styleUrls: ['./mycomponent.component.css']
})
export class MycomponentComponent implements OnInit {

  CityList  = ["Mumbai" , "Pune" , "Delhi" , "Calcutta"]
  frm  = this.fb.group({
    firstName : ["" , [Validators.required , Validators.minLength(3) , Validators.maxLength(6)]],
    lastName : ["" ,[Validators.required]],
    city : ["" , [Validators.required]]
  });

  constructor(private fb : FormBuilder) { }

  ngOnInit(): void {
  }

  submit()
  {
    alert(this.frm.get('firstName')?.value + " " + this.frm.get('lastName')?.value + " " + this.frm.get("city")?.value);
  }

}




Remember that in html, "value" attribute binds to a scalar value while "ngValue" attribute binds to an object.








Sunday, October 24, 2021

 frmabc = this.fb.group({

    firstName : ['', [Validators.required , Validators.minLength(4) , Validators.maxLength(10)]],
    lastName : ['' , [Validators.required , Validators.minLength(4) , Validators.maxLength(10)]],
    email : ['' , [Validators.required, Validators.pattern('^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$')]],
    age :['' , [Validators.required, Validators.pattern('^[0-9]+$'), Validators.max(100)]],
    password : ['', [Validators.required , Validators.minLength(4) , Validators.maxLength(10)]],
    confirmPassword : ['', [Validators.required , Validators.minLength(4) , Validators.maxLength(10)]]
  }, { validators: passwordMatchingValidatior });

Basic Angular Reactive Form Validation with Validation messages

 1. app.component.html 



<form [formGroup] = "frmabc" (ngSubmit) = "submit()" >
  <input type="text" formControlName="firstName" maxlength="10"/>
  <div *ngIf="frmabc.controls.firstName.invalid &&
  (frmabc.controls.firstName.dirty || frmabc.controls.firstName.touched)"
  class="alert">
 
  <div *ngIf="frmabc.controls.firstName.errors?.required">
    First Name is required.
  </div>
  <div *ngIf="frmabc.controls.firstName.errors?.minlength">
    First Name must be at least 4 characters long.
  </div>
 
 
</div>
<input type="text" formControlName="lastName"/>
<div *ngIf="frmabc.controls.lastName.invalid &&
(frmabc.controls.lastName.dirty || frmabc.controls.lastName.touched)"
class="alert">

<div *ngIf="frmabc.controls.lastName.errors?.required">
  Last Name is required.
</div>
<div *ngIf="frmabc.controls.lastName.errors?.minlength">
  Last Name must be at least 4 characters long.
</div>

</div>

<button type="submit" [disabled]= "!frmabc.valid">dfdsf</button>
</form>


2. app.component.ts 


import { Component} from '@angular/core';
import { FormsModule , FormBuilder , FormControl, Validators , FormGroup } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent  {
  title = 'angform1';
  // Patterns
  //readonly PAT_NAME = "^[a-zA-Z ]{2,20}$";
  //readonly PAT_EMAIL = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+[.][a-zA-Z]{2,4}$";
 
  frmabc = this.fb.group({
    firstName : ['', [Validators.required , Validators.minLength(4) , Validators.maxLength(10)]],
    lastName : ['' , [Validators.required , Validators.minLength(4) , Validators.maxLength(10)]]
  });
 
  constructor(private fb : FormBuilder) {}
  submit()
  {
    alert ( this.frmabc.get('firstName')?.value + " " + this.frmabc.get('lastName')?.value );
  }
 
}


NOTES : 

1. maxLength validator put in ts file will not by itself restrict the input to max length. To restrict the input to maxlength, use the maxlength attribute in .html also, in addition to the one in .ts. 

<input .... maxlength = "10" /> 

2.  If you get "possible null value" error, do not forget to use the "?" operator. 



How to check local and global angular versions

 Use the command ng version (or ng v ) to find the version of Angular CLI in the current folder. Run it outside of the Angular project, to f...