Search code examples
angularangular-materialangular-formly

How do I properly integrate angular material datepicker range in formly?


I am trying to integrate angular material datepicker range in formly

To this end I am doing the following:

  1. I have created the following formally type

Component:

@Component({
  selector: 'app-formly-datepicker-range-type',
  templateUrl: './formly-datepicker-range-type.component.html',
  styleUrls: ['./formly-datepicker-range-type.component.scss'],
})
export class FormlyDatepickerRangeTypeComponent extends FieldType<any> {
  range = new FormGroup({
    start: new FormControl<Date | null>(null),
    end: new FormControl<Date | null>(null),
  });
}

Component template:

<mat-form-field class="w-full">
  <mat-label>Rango</mat-label>
  <mat-date-range-input [formGroup]="range" [rangePicker]="picker">
    <input matStartDate formControlName="start" />
    <input matEndDate formControlName="end" />
  </mat-date-range-input>
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-date-range-picker #picker></mat-date-range-picker>
</mat-form-field>
  1. Formly type registration
    FormlyModule.forRoot({
      types: [
        {
          name: "datepicker-range",
          component: FormlyDatepickerRangeTypeComponent,
          wrappers: [],
        },
      ],
    })

The new type I use as follows

in some component

form = new FormGroup({});
model: FilterModel = { category: undefined, criteria: '', range: undefined };
fields: FormlyFieldConfig[] = [
  formlyInput({ key: 'criteria', label: 'Criterio', templateOptions: {} }),
  formlySelect({
    key: 'category',
    label: 'Categoría',
    templateOptions: {
      options: this.categoriesService.getAllToFormly(),
    },
  }),
  {
    key: 'range',
    type: 'datepicker-range',
    templateOptions: {
      label: 'Rango de fechas',
    },
  },
];

in some component template

<form [formGroup]="form" (ngSubmit)="onSubmit(model)" autocomplete="off">
  <formly-form [form]="form" [model]="model" [fields]="fields"></formly-form>
  <div class="flex justify-end">
    <button type="submit" mat-icon-button>
      <mat-icon>filter_alt</mat-icon>
    </button>
  </div>
</form>

The above properly draws the form. For the category and criteria input, I obtain the values correctly, but for the range property, which is the one used by the new datepicker-range type, the value is always undefined.

How can I get the selected values in the date range in the form model?

Thanks in advance


Solution

  • Subscribe to range form group events and set the parent form control when range value changes

    export class FormlyDatepickerRangeTypeComponent extends FieldType<any> {
      range = new FormGroup({
        start: new FormControl<Date | null>(null),
        end: new FormControl<Date | null>(null),
      });
    
      constructor() {
        super();
        this.range.valueChanges.subscribe((v) => this.formControl.setValue(v));
      }
    }