Saturday 2 February 2019

Generate unique id value for dynamically created form controls in angular

Generate unique id value for dynamically created form controls in angular


In this this we will discuss how to generate unique id value for the dynamically created form controls in Angular. 


If you are wondering, why is there a need to generate unique id values 

Well, first of all, IDs on an HTML page are meant to be unique. Having duplication IDs is a terrible idea. Although it may work in some cases, it is semantically incorrect to do so. 

In our case the application behaves erratically, because of duplicate element IDs. When we click on a label, we expect it's corresponding input element to receive focus, but, in our case, a different element receives focus. To fix this we have to generate unique ID values for the input elements.

<div formArrayName="skills"
      *ngFor="let skill of employeeForm.get('skills').controls; let i = index">
  <div [formGroupName]="i">

    <div class="form-group" [ngClass]="{'has-error': formErrors.skillName}">
      <label class="col-sm-2 control-label" attr.for="{{'skillName'+i}}">
        Skill
      </label>
      <div class="col-sm-4">
        <input type="text" class="form-control" id="{{'skillName'+i}}"
                formControlName="skillName" (blur)="logValidationErrors()"
                placeholder="C#, Java, Angular etc...">
        <span class="help-block" *ngIf="formErrors.skillName">
          {{formErrors.skillName}}
        </span>
      </div>
    </div>

    <!-- Experience Label & Form Control HTML
         Proficiency Label & Form Control HTML -->

  </div>
</div>

Code Explanation 
  • *ngFor directive on the formArrayName <div> element loops through all the dynamically generated form groups.
  • The variable i value will be ZERO when we are looping through the first FormGroup in the skills form array.
  • The value of i will be ONE, for the second FormGroup, TWO for the third FormGroup so on and so forth.
  • Notice the id attribute of the skillName textbox. We are dynamically computing it's ID, by appening i variable value to the string skillName
    id="{{'skillName'+i}}"
  • This will generate an ID of skillName0 for the first skillName input element, ID of skillName1 for the second skillName input element, so on so forth, to ensure unique ID values are assigned to all the dynamically generated skillName input elements.
  • In the above expression we are using interpolation. We could also achieve the same using property binding syntax instead of interpolation.
    [id]="'skillName'+i"
  • If you are new to property binding, please check out our previous topic on property binding in Angular
  • Also notice, we are dynamically setting the value of the for attribute of the Skill label.
    attr.for="{{'skillName'+i}}"
  • Since the for attribute does not have a corresponding DOM property, we are using Angular's attribute binding.
  • If you are new to attribute binding, please check out our previous topic on Attribute binding in Angular
  • With the attribute binding, we are using interpolation. We could also achieve the same using property binding syntax.
    [attr.for]="'skillName'+i"
Similarly set a unique value for the experienceInYears input element ID and it's associated label for attribute. 

<div class="form-group" [ngClass]="{'has-error': formErrors.experienceInYears}">
  <label class="col-sm-2 control-label" attr.for="{{'experienceInYears'+i}}">
    Experience
  </label>
  <div class="col-sm-4">
    <input type="text" class="form-control" id="{{'experienceInYears'+i}}"
            formControlName="experienceInYears"
            placeholder="In Years" (blur)="logValidationErrors()">
    <span class="help-block" *ngIf="formErrors.experienceInYears">
      {{formErrors.experienceInYears}}
    </span>
  </div>
</div>

No comments:

Post a Comment