Using Angular ControlValueAccessor interface



This topic will go over how to use Smart CheckBox component and use ngModel forms and Reactive Forms.

1. Creating the Component smart-input.component.ts

import { Component, Input, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl, Validator } from '@angular/forms';

@Component({
    selector: 'smart-input',
    template:
        `
        <smart-check-box
          [checked]="value" 
          (change)="onChange($event)" 
          (keyup)="onChange($event)">
        
        </smart-check-box>
        `,
    providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => SmartInputComponent),
      multi: true,
    },
    {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => SmartInputComponent),
      multi: true,
    }]        
})
export class SmartInputComponent implements ControlValueAccessor, Validator {
    private value: boolean;
    private data: any;

    // this is the initial value set to the component
    public writeValue(obj: any) {
        if (obj) {
            this.data = obj;
			
	        this.value = this.data;
        }
    }

    // registers 'fn' that will be fired wheb changes are made
    // this is how we emit the changes back to the form
    public registerOnChange(fn: any) {
        this.propagateChange = fn;
    }

    // validates the form, returns null when valid else the validation object
    // in this case we're checking if the smart parsing has passed or failed from the onChange method
    public validate(c: FormControl) {
        return true;
    }

    // not used, used for touch input
    public registerOnTouched() { }

    // change events from the checkbox
    private onChange(event) {
        // get value from checkbox
        let newValue = event.target.checked;
		this.data = newValue;
	    
        // update the form
        this.propagateChange(this.data);
    }

    // the method set in registerOnChange to emit changes back to the form
    private propagateChange = (_: any) => { };
}


2. Creating smart-input.module.ts
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { SmartInputComponent }   from './smart-input.component';

@NgModule({
    imports: [
        CommonModule,
        FormsModule,
    ],
	schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
   
    exports: [
        SmartInputComponent,
    ],
    declarations: [
        SmartInputComponent,
    ],
    providers: [],
})
export class SmartInputModule { }

3. Creating app.module.ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA  } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; 
import { FormsModule,ReactiveFormsModule } from '@angular/forms';
import { SmartInputModule } from './smart-input.module';

import { AppComponent } from './app.component';
import '@smarthtmlelements/smart-core/source/smart.core.js';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, FormsModule, ReactiveFormsModule, SmartInputModule],
	schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
    providers: [],
    bootstrap: [AppComponent]
})

export class AppModule { }
        

4. Creating app.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';

export class Hero {
  id: number;
  name: string;
}

@Component({
  selector: 'app-root',
  template: `
   <h1>NgModel</h1>  
    <form #form="ngForm">  
     <smart-input [(ngModel)]="result" name="result"></smart-input>  
    </form>  
    <p>form is valid: {{ form.valid ? 'true' : 'false' }}</p>  
    <p>Value:</p>  
    <pre>{{ result}}</pre>  
    <h1>Reactive Form</h1>  
    <form [formGroup]="reactiveForm">  
     <smart-input formControlName="result"></smart-input>  
    </form>  
    <p>form is valid: {{ reactiveForm.valid ? 'true' : 'false' }}</p>  
    <p>Value:</p>  
    <pre>{{ reactiveForm.value | json}}</pre>  
    `
})
export class AppComponent {
  
  public result = {};
  public reactiveForm: FormGroup;
  
  constructor(private fb: FormBuilder) {
    this.result = true;
    
    this.reactiveForm = this.fb.group({
      result: true;
    })
  }
}

Result:
controlvalueaccessor
Note: In the package.json, you should include a dependency to Smart’s npm package. Ex: “@smarthtmlelements/smart-core”: “2.0.0”

Download our example from here:

angular-controlvalueaccessor-sample.zip.