User Control

Creating a user control in Angular

User controls are created when a common control or layout has to be used in multiple screens. In Angular, we can create a user control and consume in the views using the component interaction @Input, @Output/@EventEmitter.

Let’s get started with the project structure first:

Created MyGridView.html and MyGridUserControl.ts as user controls to be consumed in the calling views.

MyGridView.html

<table class="gradienttable">
    <tr>
        <td *ngFor="let col of cols">
            {{ col.colName }}
        </td>
    </tr>

    <tr *ngFor="let row of data"> 
        <td *ngFor="let col of cols">
            {{row[col.colName]}}
        </td>

        <td>
            <a (click)="SelectRow(row)" [routerLink]="['/Illinois/View']">Select</a>
        </td>
    </tr>
</table>

In the view, just created A Simple grid with select button on each row which will route the values to ‘/Illinois/View/’.

MyGridUserControl.ts

import{ Component, Input, Output, EventEmitter} from '@angular/core'

@Component({
    selector: "my-grid-uc",
    templateUrl: './MyGridView.html'
})

export class GridComponent{
    cols: Array<Object> = new Array<Object>();
    data: Array<Object> = new Array<Object>();

    @Input("uc-columns")
    set SetMyGridColumnAttribute(_gridColumns: Array<Object>)
    {
        this.cols = _gridColumns;
    }
    
    @Input("uc-data")
    set SetMyGridDataAttribute(_gridData: Array<Object>)
    {
        this.data = _gridData;
    }

    @Output("row-selected")
    eventEmitter: EventEmitter<Object> = new EventEmitter<Object>();
    SelectRow(_selected:Object){
        this.eventEmitter.emit(_selected);
    }
}

So in the MyGridView.html we created button click event:

(click)="SelectRow(row)" 

This selectRow is the event emitter which will emit the output. The @OutPut directive with name as “row-selected”  above the event emitter can be referred in the calling view below.

The @input directive with name ‘uc-data’ and ’uc-columns’ are setting the row and column objects respectively.

IllinoisView.html

<!-- Toolbar -->

  <ng-template [ngIf]="city === 'Chicago'" [ngIfElse]="NotFound">
    <div>
      <img width="500" alt="No Img" src="../assets/WelcomeToChicago.PNG">
    </div>
  </ng-template>
  
  <ng-template #NotFound>
    <div>
      Image not found in collection.
    </div>
  </ng-template>



  <div [ngSwitch]="county">
    <div *ngSwitchCase="'Chicago'">
      <ul>
        <li>Cook</li>
        <li>DuPage</li>
        <li>DeKalb</li>
      </ul>
    </div>
    <div *ngSwitchCase="'Galena'">
      <ul>
        <li>Jo Davies</li>
      </ul>
    </div>
    <div *ngSwitchDefault>County not found</div>
  </div>
  
  
<my-grid-uc    
    [uc-columns]="[{'colName':'City'},{'colName':'County'},{'colName':'Zip'}]"
    [uc-data]="arrModel"
    (row-selected)="SelectCustomer($event)">
</my-grid-uc>


<table>
  <tr>
      <td>
          City: <input  [(ngModel)]="model.City" type="text" /> /br>
      </td>
      <td>
          County: <input  [(ngModel)]="model.County" type="text" /> /br>
      </td>
      <td>
          Zip: <input  [(ngModel)]="model.Zip" type="text" /> /br>
      </td>
  </tr>
</table>

In the consuming view IllinoisView.html we can consume the MyGridUserControl with the selector tags and input/output with  emitters accordingly.

<my-grid-uc    
    [uc-columns]="[{'colName':'City'},{'colName':'County'},{'colName':'Zip'}]"
    [uc-data]="arrModel"
    (row-selected)="SelectCustomer($event)">
</my-grid-uc>

IllinoisComponent.ts

import { Component } from '@angular/core';
import { MyModelClass } from 'src/Helpers/MyModel';

@Component({
  templateUrl: './IllinoisView.html'
})

export class IllinoisComponent 
{
  city = 'Chicago';
  county='Chicago';

  model : MyModelClass = new  MyModelClass();

  arrModel: Array<MyModelClass> = new Array<MyModelClass>();

  SelectCustomer(_selected: MyModelClass){
    this.model = _selected;
  }

constructor(){
  this.model.City= "Chicago";
  this.model.County="Cook";
  this.model.Zip=60660;

  this.arrModel.push(this.model);
  
  this.model = new MyModelClass();
  this.model.City= "Naperville";
  this.model.County="DuPage";
  this.model.Zip=60540;

  this.arrModel.push(this.model);
  
}
}

The event emitter will just set the model object to the selected row and the data will bind and display on the screen accordingly

SelectCustomer(_selected: MyModelClass){
    this.model = _selected;
  }

IllinoisModule.ts

import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';

import { IllinoisComponent } from './IllinoisComponent'
import { IllinoisRoutes } from '../Routing/IllinoisRouting'

import { IllinoisRouteModule } from '../Routing/IllinoisRouting'
import{ GridComponent } from '../Helpers/MyGridUserControl'

@NgModule({
  declarations: [
    IllinoisComponent, GridComponent
  ],
  imports: [
    CommonModule,
    RouterModule.forChild(IllinoisRoutes),
    FormsModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [IllinoisComponent]
})
export class IllinoisModule { }

In the IllinoisModule.ts, we must import the GridComponent form the helper file so as to use it in the IllinoisComponent.ts file

Ng serve –port

From the UI, as you can see in the grid below which shows City/County/Zip, we have a select button on each row. Clicking select will display the values in the city, county and zip textbox fields accordingly.