Angular 2 - Custom Form Control - Disable

angular, forms, javascript

Solution

Your component needs to implement the `setDisabledState` function which is defined in the `ControlValueAccessor` interface (see docs).

E.g. (assuming the renderer has been injected in the constructor):

setDisabledState(isDisabled: boolean) {
    this.renderer.setElementProperty(this.textInput.nativeElement, 'disabled', isDisabled);
    // disable other components here
}

Problem

I have created a custom control using ControlValueAccessor that is composed of an `input[type=text]` and a datepicker. When I use it in template-driven forms everything works fine. But when I use the model-driven approach (reactive forms), the `disable()` method on the form control doesn't seem to have any effect whatsoever. Is it possible to disable/enable my custom control programmatically as I do with every other form control in model-driven forms EDIT I should note that I'm using Angular v2.1.0 and that my methodology is pretty much the same as this as I have been using it as a guide. EDIT This is my custom control: ``` @Component({ selector: 'extended-datepicker', templateUrl: './extended-datepicker.component.html', styleUrls: ['./extended-datepicker.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ExtendedDatepickerComponent), multi: true } ] }) export class ExtendedDatepickerComponent implements OnInit, ControlValueAccessor { isDatepickerActive: boolean = false; _selectedDate: Date; selectedDateString: string = ""; @Input() disabled: boolean; @Input() mask: any; @Input() required: boolean; @ViewChild('textInput') textInput: ElementRef; get selectedDate(): Date { return this._selectedDate; } set selectedDate(value: Date) { this.selectedDateString = moment(value).format(STANDARD_DATE_FORMAT); this._selectedDate = value; } propagateChange: Function; @ViewChild(DatePickerComponent) datepicker: DatePickerComponent; constructor() { } writeValue(value: Date) { if (value) { this.selectedDate = value; this.selectedDateString = moment(value).format(STANDARD_DATE_FORMAT); } } registerOnTouched(): void { } registerOnChange(fn: Function) { this.propagateChange = fn; } // ... ``` This is the control's template: ``` <div class="calendar-wrapper row-small-margin" (clickOutside)="isDatepickerActive = false;"> <div class="col-xs-10 col-small-padding"> <div class="input-group"> <span class="input-group-addon" role="button" (click)="prevDay()" *ngIf="selectedDate"> <i class="fa fa-chevron-left"></i> </span> <input #textInput [textMask]="{mask: mask}" [(ngModel)]="selectedDateString" (ngModelChange)="inputChange()" class="form-control" [required]="required" [disabled]="disabled" (keyup)="onKeyPressed($event)"> <span class="input-group-addon" role="button" (click)="nextDay()" *ngIf="selectedDate"> <i class="fa fa-chevron-right"></i> </span> </div> <div *ngIf="isDatepickerActive" class="datepicker-wrapper"> <datepicker [(ngModel)]="selectedDate" (ngModelChange)="dateChange()" [showWeeks]="false" [required]="required" [formatDay]="dd" [formatMonth]="MM" [formatYear]="yyyy" [disabled]="disabled"> </datepicker> </div> </div> <div class="col-xs-2 col-small-padding"> <button class="btn btn-sm btn-datepicker" [disabled]="disabled" (click)="toggleDatePicker()" type="button"> <img src="/assets/img/image.png"> </button> </div> </div> ``` And this is what I do in my form component: ``` this.myForm.controls['pickDate'].valueChanges.subscribe(val => { if (!val) { this.myForm.controls['date'].disable(); // This line here does nothing } }); ``` How is it possible to respond to that `disable()` call inside my extended-datepicker and act accordingly?

Original source