Search code examples
angulardatepickerngforangular-template-variableowl-date-time

How to use unique reference in a loop


With Angular I am using this date time picker in loop and I need to assign a unique reference. So far I hardcode it to req_d1 but it creates some problem. I would like to know how could I set a dynamic unique reference in the loop with Angular, thanks! Remarks: the number of rows is dynamic also, it could be 0, 1 or 20, or even more.

<tr *ngFor="let row of rows; let i = index">
    <td>{{ row.name }}</td>
    <td>
        <input
            type="text"
            name="date{{i}}"
            [value]="row.planned_date"
            (blur)="updatePlannedDate(row, $event)"
            [owlDateTime]="req_d1"
            [owlDateTimeTrigger]="req_d1"
        />
        <owl-date-time
            #req_d1
            [pickerType]="'calendar'"
        ></owl-date-time>
    </td>
<td>

Solution

  • It's due to some wierd bug related to using [value], instead go for [(ngModel)] of template driven angular forms. The bug does not happen, when we use this directive and it does the same thing.

            <input
                type="text"
                name="date{{i}}"
                [(ngModel)]="row.planned_date"
                *ngIf="req_d1.formatString"
                [owlDateTime]="req_d1"
                [owlDateTimeTrigger]="req_d1"
            />
    

    Full Code:

    import { Component, importProvidersFrom } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import { provideAnimations } from '@angular/platform-browser/animations';
    import { CommonModule } from '@angular/common';
    import {
      OwlDateTimeModule,
      OwlNativeDateTimeModule,
    } from '@danielmoncada/angular-datetime-picker';
    import { ReactiveFormsModule, FormsModule } from '@angular/forms';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [
        CommonModule,
        OwlDateTimeModule,
        OwlNativeDateTimeModule,
        ReactiveFormsModule,
        FormsModule,
      ],
      template: `
        <div *ngFor="let row of rows;trackBy: trackByFn; let i = index">
        <div>{{ row.name }}</div>
        <div>
            <owl-date-time
                #req_d1="owlDateTime"
                [pickerType]="'calendar'"
            ></owl-date-time>
            <input
                type="text"
                name="date{{i}}"
                [(ngModel)]="row.planned_date"
                *ngIf="req_d1.formatString"
                [owlDateTime]="req_d1"
                [owlDateTimeTrigger]="req_d1"
            />
        </div>
    <div>
      `,
    })
    export class App {
      rows = [
        { name: 1, planned_date: new Date() },
        { name: 2, planned_date: new Date() },
        { name: 3, planned_date: new Date() },
        { name: 4, planned_date: new Date() },
      ];
    
      trackByFn(index: number) {
        return index;
      }
    }
    
    bootstrapApplication(App, {
      providers: [
        provideAnimations(),
        importProvidersFrom([OwlDateTimeModule, OwlNativeDateTimeModule]),
      ],
    });
    

    Stackblitz Demo