0

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.

9
  • I tried to use material checkbox and it didn't change to string Commented Apr 30, 2019 at 9:20
  • Yes. I just change input to mat checkbox. I will put the code in 5 10 min Commented Apr 30, 2019 at 9:21
  • use change event and toggle value based on checked property Commented Apr 30, 2019 at 9:27
  • Do you want to add required validator for Agreement checkbox? If checked then login otherwise disable login button? Commented Apr 30, 2019 at 9:32
  • For this agreement it is not required Commented Apr 30, 2019 at 9:34

2 Answers 2

2

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);
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

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 {}
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.