import {AfterViewInit, Component, ContentChildren, forwardRef, Input, OnChanges, QueryList, SimpleChanges} from '@angular/core'; import deepEqual from 'deep-equal'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import {DataCardService} from '../api/data-card.service'; @Component({ selector: 'app-radio-button', template: '
' }) export class RadioButtonComponent { @Input() label = ''; @Input() value: any; constructor() { } } export const APP_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RadioGroupComponent), multi: true }; @Component({ selector: 'app-radio-group', templateUrl: './radio-group.component.html', styleUrls: ['./radio-group.component.scss'], providers: [APP_RADIO_GROUP_CONTROL_VALUE_ACCESSOR], }) export class RadioGroupComponent implements ControlValueAccessor, OnChanges, AfterViewInit { @Input() label = ''; @Input() name = ''; @Input() notRelevant = false; @Input() direction = 'row'; @ContentChildren(RadioButtonComponent, {descendants: true}) options: QueryList|undefined; public innerModel: any; public disabled = false; // When notRelevant is toggled on, we store the old value, so we can re-fill it it gets turned off again private oldValue: any; private dirtyAble = false; private onChangeCallback: (newValue: string) => any = () => {}; private onTouchedCallback: () => any = () => {}; constructor(private dataCardService: DataCardService) { } public ngAfterViewInit(): void { if (!this.disabled) { this.dataCardService.isDataCardClosed.subscribe(isClosed => this.setDisabledState(isClosed)); } } ngOnChanges(changes: SimpleChanges): void { if (changes.notRelevant) { if (this.notRelevant) { this.oldValue = this.innerModel; this.writeValue(null); } else { this.writeValue(this.oldValue); } } } onClick(event: MouseEvent, value: any): void { event.preventDefault(); if (this.disabled || this.notRelevant) { return; } this.dirtyAble = true; if (deepEqual(this.value, value) ) { this.value = null; } else { this.value = value; } this.onTouchedCallback(); } get value(): any { return this.innerModel; } set value(value: any) { if (!deepEqual(value, this.innerModel)) { this.innerModel = value; if (this.dirtyAble) { this.onChangeCallback(value); } if (!(this.dirtyAble && this.innerModel === undefined)) { // We don't want to mark the field as dirty while data gets initialized this.dirtyAble = true; } } } registerOnChange(fn: any): void { this.onChangeCallback = fn; } registerOnTouched(fn: any): void { this.onTouchedCallback = fn; } setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } writeValue(newValue: any): void { this.value = newValue; } isDirty(): boolean { return this.dirtyAble; } }