ionic-framework icon indicating copy to clipboard operation
ionic-framework copied to clipboard

bug: <ion-datetime-button> not rendered inside modal

Open DwieDima opened this issue 8 months ago • 10 comments

Prerequisites

Ionic Framework Version

v8.x

Current Behavior

When using <ion-datetime-button> inside a modal page (created via ModalController), the component does not render anything unless the linked <ion-datetime> and <ion-datetime-button> (e.g. with ID calendar-trigger) is already present in the DOM before the button is initialized.

This seems related to Web Component hydration timing in dynamically loaded views.

However, if a <ion-datetime> with the same ID is rendered earlier (inside a routed page) (even with display: none), the button suddenly works inside the modal, but is rendered from parent page without the possibility to use value binding from modal.

Expected Behavior

<ion-datetime-button> should correctly render and bind to its matching target, regardless of where in the component it appears, as long as the referenced element exists in the DOM at the time of rendering.

Hydration/timing should not cause the component to silently fail.

Steps to Reproduce

  1. open stackblitz
  2. click on "open" button
  3. modal is visible without the ion-datetime-button visible
  4. comment in the html inside example.component.html
  5. safe changes
  6. click on "open" button
  7. modal is visible with ion-datetime-button displaying the date

Code Reproduction URL

https://stackblitz.com/edit/vnczfh3u?file=src%2Fapp%2Fmodal-example.component.ts,src%2Fapp%2Fmodal-example.component.html,src%2Fapp%2Fexample.component.html,src%2Fapp%2Fexample.component.ts

Ionic Info

see stackblitz

Additional Information

My current workaround is to render ion-datetime-button after the lifecycle ngAfterViewInit() is resolved:

  public afterInit = signal(false);

  public ngAfterViewInit(): void {
    this.afterInit.set(true);
  }
 @if (afterInit()) {
     <ion-datetime-button datetime="calendar-trigger">
         <span slot="date-target"> {{ selectedDate() | date: 'fullDate' }} </span>
      </ion-datetime-button>
   }

DwieDima avatar Jun 20 '25 14:06 DwieDima

I have the same problem, generally affecting all parts that somehow interfere with the DOM. This includes ion-datetime itself, but it is most noticeable with ion-datetime-button. What I also found out is that if the browser loads the data fast enough (which rarely happens), everything works fine, but if the data in the DOM is rendered more slowly, the problem occurs.

As you mentioned above, it is impossible to display this when activated via ID. Your fix works, but it is definitely not a solution for this to work. I noticed this problem since version 8.7.x.

Sometimes the fix didn't work, but this one did:

public willEnter = signal(false);

    public ionViewWillEnter(): void {
        this.willEnter.set(true);
    }

EDIT: The problem occurs in many more places. It also happens to me with ion-icon, which I use wrapped in my own component (app-place-icon) and display inside a modal. The ion-icon is rendered, but the SVG inside is not rendered either. (when rendered in @for or other async method works perfectly) Tested on Angular 20. In order to draw it, I have to use a fix. It is also possible that this is only related to Angular, specifically the transition to Zoneless and Signals.

without afterInit()

Image

With afterInit() fix

@if (afterInit()) {
    <ion-icon class="category-icon" [color]="color" [name]="name"></ion-icon>
}
Image

jakubforman avatar Aug 08 '25 13:08 jakubforman

I can confirm this problem on multiple places in my app in conjunction with ion-datetime-button. The component is logging an error like ion-datetime-button No ion-datetime instance found for ID xxx.

This happens on Angular 20.1.5 and @ionic/angular 8.7.x. I'm not using Zoneless.

maatien avatar Aug 12 '25 14:08 maatien

I have the same issue with ion-datetime-button. It doesn't show in ion-modal. I didn't find the solution to fix it. Solutions that render this component after entering it are also not working for me. So I just did it like that:

    <ion-button id="dateFrom">{{ form.controls.dateFrom.value | date: "dd.MM.yyyy" }}</ion-button>
    <ion-popover trigger="dateFrom">
      <ng-template>
        <ion-datetime
          [formControl]="form.controls.dateFrom"
          presentation="date-time"
        ></ion-datetime>
      </ng-template>
    </ion-popover>

Instead of a popover, you can use a modal, but a popover looks better.

Environments:

  • Angular 18.2
  • Ionic 8.6.5

k-scherbitsky avatar Sep 09 '25 08:09 k-scherbitsky

I solved it by using @defer :/

<ion-modal>
  <ng-template>
    @defer {
      <ion-datetime></ion-datetime>
    }
  </ng-template>
</ion-modal>

HyperLife1119 avatar Sep 10 '25 08:09 HyperLife1119

@HyperLife1119 I had to use @defer on the <ion-datetime-button> instead of on the <ion-datetime>.

troywweber7 avatar Sep 30 '25 17:09 troywweber7

I tried defer for all of my modal html and it still does not show the icons. 😢

Eraldo avatar Oct 04 '25 10:10 Eraldo

It did seem like maybe the "@if" approach was more consistent than the "@defer" approach in working around the issue.

troywweber7 avatar Oct 04 '25 16:10 troywweber7

I left my templates as they were and instead created a patch that re-renders the icons after the first load in modals. This is obviously just a workaround, but better than not having icons show up or migrating all my modal templates. If there is a need for it, I can come back and share it here.

Eraldo avatar Oct 04 '25 21:10 Eraldo

we have that on multiple places in modal with newest ionic version and angular 20. things like translated labels icon src fetched with a pipe etc. are not rendered. they are rendered as soon as if block is around the template.

edit: This only occurs when built and run on a phone, not when serving the app locally in the browser. edit2: This does not seem to be a problem with inline modal, only when using modalController.create() it seems like

Spinnenzunge avatar Oct 20 '25 11:10 Spinnenzunge

@HyperLife1119 I had to use @defer on the <ion-datetime-button> instead of on the <ion-datetime>.

Using @defer around ion-datetime-button work!

IAmCatch avatar Oct 22 '25 02:10 IAmCatch