简体   繁体   中英

Angular 2 - Custom Form Control - Disable

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?

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

Eg (assuming the renderer has been injected in the constructor):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM