I'm creating a custom form element using Angulars ControlValueAccesor. I have three buttons in my toggle-group, one is selected by default. When I'm submitting without doing anything the form should be returning the value from the default field. Insted it returns null if I'm implementing it in an reactive form and "" out of a template-driven form.
If I'm selecting another value and then the one that was selected by default it returns the right value.
HTML
<div class="nullableBoolWrapper" fxLayout="row">
<mat-button-toggle-group class="selection-button"
[disabled]="isDisabled"
(change)="changed($event)"
value=null>
<mat-button-toggle value=true>Yes</mat-button-toggle>
<mat-button-toggle value=false>No</mat-button-toggle>
<mat-button-toggle value=null [disabled]="!selectableNull">Maybe</mat-button-toggle>
</mat-button-toggle-group>
</div>
TS
import { Component, forwardRef, Input, OnInit } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
export const NULLABLE_BOOL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NullableBoolComponent),
multi: true
};
@Component({
selector: 'nullable-bool',
templateUrl: './nullable-bool.component.html',
styleUrls: ['./nullable-bool.component.scss'],
encapsulation: ViewEncapsulation.Emulated,
providers: [NULLABLE_BOOL_VALUE_ACCESSOR]
})
export class NullableBoolComponent implements ControlValueAccessor, OnInit {
constructor() { }
@Input('selectableNull') selectableNull = false;
public selectedValue: boolean | null = null;
public isDisabled = false;
private onChange: (val: boolean | null) => void;
private onTouch: () => void;
writeValue(val: boolean | null): void { this.selectedValue = val; }
registerOnChange(fn: any): void { this.onChange = fn; }
registerOnTouched(fn: any): void { this.onTouch = fn; }
setDisabledState?(isDisabled: boolean): void { this.isDisabled = isDisabled; }
ngOnInit() { this.descriptionList === undefined ? this.descriptionList = this.defaultList : null; }
changed($event: any): void {
this.onTouch();
this.onChange($event);
}
}
Greeting
Found a solution, I had to initialize my FormControl like this:
private reactiveNullableBool = new FormControl({ value: null });
and not like this:
private reactiveNullableBool = new FormControl();
But is there a way to get around the { value: null }
? I don't like the style.
And for template-driven forms I had to do [ngModel]="{value: null}"
to get it work.
Maybe I should have send you the component that calls the element as well.