0
votes

How can I change the boolean(true false) to string when i click on material checkbox (mat-checkbox).

I have an example for input https://stackblitz.com/edit/angular-ng-true-false. So i use the same code but i changed input checkbox to material checkbox. I included material module.

MY CODE WITH MATERIAL CHECKBOX

import {
    Directive,
    Input,
    forwardRef,
    HostListener,
    ElementRef,
    Renderer2
} from '@angular/core';
import {
    ControlValueAccessor,
    NG_VALUE_ACCESSOR,
    NgControl
} from '@angular/forms';

@Directive({
    selector: 'input[type="checkbox"][trueFalseValue]',
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => TrueFalseValueDirective),
            multi: true
        }
    ]
})
export class TrueFalseValueDirective implements ControlValueAccessor {
    private propagateChange = (_: any) => { };
    @Input() trueValue = true;
    @Input() falseValue = false;

    constructor(private elementRef: ElementRef, private renderer: Renderer2) { }

    @HostListener('change', ['$event'])
    onHostChange(ev) {
        this.propagateChange(ev.target.checked ? this.trueValue : this.falseValue);
    }

    writeValue(obj: any): void {
        if (obj === this.trueValue) {
            this.renderer.setProperty(this.elementRef.nativeElement, 'checked', true);
        } else {
            this.renderer.setProperty(this.elementRef.nativeElement, 'checked', false);
        }
    }

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

    registerOnTouched(fn: any): void { }

    setDisabledState?(isDisabled: boolean): void { }
}
import { Component, OnInit, Inject, Input, Output, EventEmitter } from '@angular/core';
   
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';


@Component({
  selector: 'app-agreements',
  templateUrl: './agreements.component.html',
  styleUrls: ['./agreements.component.scss']
})

export class AgreementsComponent implements OnInit {

  myForm: FormGroup;

  constructor( private fb: FormBuilder, ) {
   
  }

  ngOnInit() {

    this.myForm = new FormGroup({
     
      emailAgreement: new FormControl('Y'),
     
    });

    this.myForm = this.fb.group({
      
      emailAgreement: ['']
    });

  }
 


}
<mat-checkbox class="checkbox-mat" 
              formControlName="emailAgreement" trueFalseValue trueValue="Y" falseValue="N">Agreement to be contacted</mat-checkbox>

But i want it for angular material to work. I would appreciate any help. Thanks.

2
I tried to use material checkbox and it didn't change to string - ryy77
Yes. I just change input to mat checkbox. I will put the code in 5 10 min - ryy77
use change event and toggle value based on checked property - Pranav C Balan
Do you want to add required validator for Agreement checkbox? If checked then login otherwise disable login button? - Prashant Pimpale
For this agreement it is not required - ryy77

2 Answers

2
votes

If you want to store the checkbox value as a string in the form, use the checkbox change event to apply the string value to the checkbox's form control:

HTML

<mat-checkbox (change)="checkboxChange($event.checked)" [formControl]="control">Check me!</mat-checkbox>

TS

export class CheckboxStringValueFormExample {
  setValueOptions = {
    onlySelf: true, 
    emitEvent: false, 
    emitModelToViewChange: false, 
    emitViewToModelChange: false
  }

  control = new FormControl();

  checkboxChange(checkboxValue) {
    this.control.setValue(checkboxValue ? 'Y' : 'N', this.setValueOptions);
  }
}
1
votes

To complementary my answer, make a custom form control it's easy, just implement controlValueAntecesor.

In this case it's only write

@Component({
  selector: 'true-false-value',
  template:`<mat-checkbox #id [ngModel]="valor" 
                (ngModelChange)="change(id)">
                <ng-content></ng-content>
            </mat-checkbox>`
,  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => TrueFalseValueComponent),
      multi: true
    }
  ]
})
export class TrueFalseValueComponent implements ControlValueAccessor {
  private propagateChange = (_: any) => {};
  @Input() trueValue = true;
  @Input() falseValue = false;
  valor:any;

  constructor() {}

//when change the model, call to function "propagateChange" with the correct value
change(id:any)
{
  this.valor=id.checked;
  this.propagateChange(this.valor? this.trueValue:this.falseValue)
}

 //At first, we received a value, we must change the "aparence" of our component
  writeValue(obj: any): void {
    this.valor=(obj === this.trueValue);
  }

  //here we say to Angular that we're going to use the function
  //this.propagateChange when a change happends
  registerOnChange(fn: any): void {
    this.propagateChange = fn;
  }

  registerOnTouched(fn: any): void {}

  setDisabledState?(isDisabled: boolean): void {}
}