angulardart / angular_components

The official Material Design components for AngularDart. Used at Google in production apps.
https://pub.dev/packages/angular_components
372 stars 122 forks source link

Using MaterialDatepickerComponent with angular form #392

Open muzuro opened 5 years ago

muzuro commented 5 years ago

I have tried to use MaterialDatepickerComponent with form, but I got error: No value accessor for (expirationDate) or you may be missing formDirectives in your directives list. Can I use MaterialDatepickerComponent with forms?

Here is source of component:

@Component(
    selector: 'create',
    templateUrl: 'create_component.html',
    directives: const [
      formDirectives,
      MaterialDatepickerComponent,
    ],
    pipes: const[]
)
class CreateComponent implements OnInit {
  ControlGroup createForm;
  @override
  void ngOnInit() {
    createForm = FormBuilder.controlGroup({
      "expirationDate": [null],
    });
  }
}

Here is template:

<form [ngFormModel]="createForm">
    <material-datepicker [minDate]="today"
                         [required]="true"
                         ngControl="expirationDate"
                         #expirationDate="ngForm">
    </material-datepicker>
</form>
alanblake commented 5 years ago

I get the same issue. Any workaround or fix would be welcome.

ltackmann commented 5 years ago

Just stumbled on this as well, would also appreciate a workaround or fix

tudor07 commented 5 years ago

It would be great to get a fix for this

grundid commented 5 years ago

A possible solution or workaround to this is to create your own ValueAccessor.

The example below is for a DateTimePicker, but you can easily adapt it to DatePicker only. Don't forget to add it to your list of directives. Hope it helps.

import 'package:angular/angular.dart';
import 'package:angular_components/material_datepicker/material_date_time_picker.dart';
import 'package:angular_forms/angular_forms.dart';

const valueAccessor = const OpaqueToken('NgValueAccessor');

@Directive(
  selector: 'material-date-time-picker[dateTime]',
  providers: const [
    const ExistingProvider.forToken(ngValueAccessor, DateTimePickerValueAccessor),
  ],
)
class DateTimePickerValueAccessor implements ControlValueAccessor, OnDestroy {
  final MaterialDateTimePickerComponent _picker;

  DateTimePickerValueAccessor(this._picker) {}

  @override
  void writeValue(newValue) {
    if (newValue is DateTime) {
      _picker.dateTime = newValue;
    }
  }

  @override
  void ngOnDestroy() {}

  @override
  void onDisabledChanged(bool isDisabled) {}

  @override
  void registerOnChange(ChangeFunction f) {}

  @override
  void registerOnTouched(TouchFunction f) {}
}