1. Create Custom Controls In Angular 5, 6 ,7 — Custom Component as Radio Button

Most of time, the need of functionality/requirement is being fulfilled by framework or third party libraries controls e.g material.angular.com, ng-prime etc.

Narendra Singh Rathore
3 min readDec 23, 2018

But there are some situations where we requires to build our custom tool or control ( to be specific).

In such cases Angular help to fulfilling such requirements. Let us start how we can achieve that.

import {ControlValueAccessor} from ‘@angular/forms’;

ControlValueAccessor

Defines an interface that acts as a bridge between the Angular forms API and a native element in the DOM.

So as per description by angular doc, it state that we can built a bridge between native HTML elements e.g input, select etc and angular forms api which allows to bind forms api e.g formContorlName, ngModel etc.

Let’s start first building our radio button. Below is snapshot of final output.

Our HTML

<div class=”workout-type”><div class=”workout_pane” ><div *ngFor=”let selector of selectors” class=”pane” (click)=”selectType(selector);” [class.active]=”selector === value”><img src=”assets/svg-icons/{{selector}}.svg” /><span>{{selector | uppercase}}</span><mat-icon [class.icon-active]=”selector === value” class=”icon”>check_circle</mat-icon></div></div></div>

Our SCSS

.workout_pane {display: flex;flex-direction: column;flex-wrap: wrap;}.pane {padding: 10px;margin: 10px;background-color: #f6f6f6;display: flex;align-items: center;justify-content: space-between;box-sizing: border-box;box-shadow: 4px 5px 14px -3px #b3b3b3;border-radius: 4px;position: relative;img {width: auto;height: 10vh;max-width: 120px;}span {font-weight: 700;font-family: monospace;font-size: 1.5em;}}.active {background-color: #dedede;position: relative;}.icon {position: absolute;right: 5px;top: 5px;display: none;}.icon-active {display: inline-flex;}

Our Component .ts file

// IMPORTS
import { Component, forwardRef, OnInit, ChangeDetectionStrategy } from ‘@angular/core’;
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from ‘@angular/forms’;
const TYPE_CONTROL_ACCESSOR = {provide: NG_VALUE_ACCESSOR,useExisting: forwardRef(() => WorkoutTypeComponent),multi: true};@Component({selector: ‘app-workout-type’,templateUrl: ‘./workout-type.component.html’,styleUrls: [‘./workout-type.component.scss’],changeDetection: ChangeDetectionStrategy.OnPush,providers: [TYPE_CONTROL_ACCESSOR]})export class WorkoutTypeComponent implements OnInit, ControlValueAccessor {value = ‘endurance’;selectors = [‘strength’, ‘endurance’];private onTouch: Function;private onModelChange: Function;

Writes a new value to the element.

This method is called by the forms API to write to the view when programmatic changes from model to view are requested.

writeValue(obj: string): void {this.value = obj; }

Registers a callback function that is called when the control's value changes in the UI.

This method is called by the forms API on initialization to update the form model when values propagate from the view to the model.

When implementing the registerOnChange method in your own value accessor, save the given function so your class calls it at the appropriate time.

registerOnChange(fn: any): void {this.onModelChange = fn;}

Registers a callback function is called by the forms API on initialization to update the form model on blur.

When implementing registerOnTouched in your own value accessor, save the given function so your class calls it when the control should be considered blurred or "touched".

registerOnTouched(fn: any): void {this.onTouch = fn;}

Function to update selected value of our component

selectType(value: string) {this.value = value;this.onModelChange(value);this.onTouch();}

Constructor

constructor() { }}

Calling our custom component control in reactive form template.

<div><h3>Type</h3><app-workout-type formControlName=”type”></app-workout-type></div>

You can get or set value as below:

this.form.patchValue({type: ‘some-value’});get type() {
return this.form.type; }

Hope, you get an idea how we can create a custom control using components.

Stay tuned as it will be a series of custom components.

Thanks.

--

--