Tips for setting up a listener for when the month changes in an ion-datetime object

When the user selects a different month, I need to update the highlightedDates by calling a query to retrieve all the dates of that specific month. This currently works if the user manually chooses a month and year using the top button, but not when they click on the arrows "<" and ">"


  <div class="calendar">
    <ion-datetime
      [(ngModel)]="selectedDate"
      presentation="date"
      locale="it-IT"
      [highlightedDates]="allAppointments"
      (ionChange)="createAppointmentList()"
    >
    </ion-datetime>

Essentially, I am looking for an event listener to trigger when the user clicks on the calendar arrows.

Answer №1

Managed to find a resolution with the guidance of Misha Mashina's comment

  initializeCalendarObserver(){
    const calendarHeader = document.querySelector('ion-datetime')?.shadowRoot?.querySelector('.calendar-header')?.querySelector('ion-label');
    const elementToWatch = document.querySelector('ion-datetime')?.shadowRoot?.querySelector('.calendar-body')

    if (elementToWatch) { 
      const observer = new MutationObserver((mutationsList, observer) => {

        this.monthString = calendarHeader?.textContent;
        let parts = this.monthString.split(" ")
        let monthIndex = this.monthNames.indexOf(parts[0].toLowerCase())
        let monthNumber = monthIndex + 1
        let year = parts[1]

        if(this.monthString){
          this.monthToDate = new Date(year, monthNumber).toISOString()
          this.queryDataForMonth(this.monthToDate)
        }

      })
      const observerConfig = {
        childList: true, 
        subtree: true, 
      };
      observer.observe(elementToWatch, observerConfig)
    }
  }

Retrieved the calendar element using:

 document.querySelector('ion-datetime')?.shadowRoot?.querySelector('.calendar-body')

Utilized MutationObserver to monitor changes in it

Answer №2

This particular approach assumes that the starting month is the one currently displayed.

To implement this, you would need to create a customized component as shown below:

@Component({
  selector: 'app-custom-datetime',
  templateUrl: './custom-datetime.component.html',
  styleUrls: ['./custom-datetime.component.scss'],
})
export class CustomDatetimeComponent implements OnInit {
  @Input() presentation: string = 'date';
  @Input() firstDayOfWeek: number = 0;

  @Output() monthChange: EventEmitter<{ month: number }> = new EventEmitter();

  private month: number = new Date().getMonth();

  ngOnInit(): void {

  }

  ngAfterViewInit() {
    this.createNextMonthObserver();
    this.createPreviousMonthObserver();
  }

  createNextMonthObserver() {
    const interval = setInterval(() => {
      const ionDatetime = document.querySelector('ion-datetime');
      const ionButtons = ionDatetime?.shadowRoot?.querySelectorAll('ion-button');
      if (ionButtons?.length === 2) {
        ionButtons[1].addEventListener('click', () => {
          this.month = this.month === 11 ? 0 : this.month + 1;
          this.monthChange.emit({ month: this.month });
        });
        clearInterval(interval);
      }
    }, 100);
  }

  createPreviousMonthObserver() {
    const interval = setInterval(() => {
      const ionDatetime = document.querySelector('ion-datetime');
      const ionButtons = ionDatetime?.shadowRoot?.querySelectorAll('ion-button');
      if (ionButtons?.length === 2) {
        ionButtons[0].addEventListener('click', () => {
          this.month = this.month === 0 ? 11 : this.month - 1;
          this.monthChange.emit({ month: this.month });
        });
      clearInterval(interval);
    }, 100);
  }

}

With this setup, we have established direct observers for the button interactions that modify the calendar's month.

Included in your HTML code should be the following snippet:

<ion-datetime
  [presentation]="presentation"
  [firstDayOfWeek]="firstDayOfWeek"
>

</ion-datetime>

By doing this, you are able to monitor any changes through the monthChange output property.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with readonly is preventing the ability to alter the font color of the input

I need to change the font color of a disabled input. When it is disabled, it appears gray and I want it to be black instead. I attempted to use readonly but that did not have the desired effect, and now the input is showing [object Object]. Below is my HTM ...

The flow union type operates smoothly without any errors occurring

In the code snippet below, I have defined a type 'Something' which can have three possible values: 'A', 'B', or 'C'. The function 'f' takes an object of type Something as input and returns a string based on ...

`It is important to note that in Tailwind CSS, `h-8` does not supersede `h-4

I developed an Icon component that looks like this: import { IconProp, library } from "@fortawesome/fontawesome-svg-core"; import { far } from "@fortawesome/free-regular-svg-icons"; import { fas } from "@fortawesome/free-solid-svg- ...

Why isn't the Mat error functioning properly in this Angular code?

Could someone explain why the Mat error does not seem to be functioning properly in this Angular code snippet? <div class="form-group"> <mat-form-field class="row-styling"> <mat-label for="aplctnName"> Application Name <sp ...

Sorting problem with date formats in ReactJS

Having an issue with sorting in my current project. After sorting, the result I'm getting is displayed in the following image: https://i.sstatic.net/7ZmEK.png <td className="dashboard_table-cell" title={'Created Date: ' + Queue.Create ...

Footer remains fixed to the bottom of the page even when there is not enough content to

It seems like there are already many discussions on this topic, so I apologize if this is a duplicate. I searched for it but couldn't find anything similar. I am currently working on an angular application using the Ionic framework for testing purpos ...

What is the best way to standardize complex nested data within the ngrx/store?

Currently, I am utilizing ngrx/store with Angular 6. Within the store, there exists a deeply nested structure which I have concerns about in terms of its organization: const state = [ { aliases: ['alias1', 'alias2'], isRequir ...

Array of objects not being shown in select dropdown

I have a component with a dropdown feature. Below is the code snippet from the component: export class MyComponent { MyObjectArray: MyObject[] = []; constructor(private _service: MyService) } ngOnInit() { this._service.get().do((response): MyObjec ...

The attribute 'date' is not found within the class 'EmployeeScheduleExceptionModel', however, it is present in the parent class from which it inherits

I am working on a TypeScript project and I have defined my configurations in the tsconfig.json file as shown below: { "include": ["src*"], "compilerOptions": { "target": "es2021", &q ...

Parameters in Typescript decorators

Can someone help me understand the various parameters of a Typescript decorator? function myDecorator(target) { // do something with 'target' ... } In the given example, I am aware that 'target' represents the function/class to wh ...

Using Typescript generics within a callback function

I am currently working on developing a versatile service that can fetch data from a remote source and create objects based on that data. @Injectable() export class tService<T> { private _data: BehaviorSubject<T[]> = new BehaviorSubject([]) ...

The type '{}' cannot be assigned to type 'IntrinsicAttributes & FieldsProp'. This error message is unclear and difficult to understand

"The error message "Type '{}' is not assignable to type 'IntrinsicAttributes & FieldsProp'.ts(2322)" is difficult to understand. When I encountered this typeerror" import { useState } from "react"; import { Card } fr ...

Exploring observables for querying the OMDB API and obtaining information on movies

Hey everyone, I'm currently working on implementing a live search feature using Observables in Angular2 to fetch Movie data from the OMDB API. While I can see that it is functioning correctly in the Chrome Network tab, the results aren't showing ...

Refresh Chart Information using Ng2-Charts in Charts.js

Utilizing chart.js and ng2-charts, I am developing gauge charts for my platform to monitor the fluid levels inside a machine's tank. The values are retrieved from an external API, but I am encountering an issue where the charts are rendered before I ...

Implementing TypeScript type declarations for merging core types

Is there a way to perform type declaration merging in TypeScript for built-in types when using imports? I am currently attempting to merge interfaces as per the guidelines outlined in this documentation: https://www.typescriptlang.org/docs/handbook/declar ...

What is the best way to determine the highest value?

How can I ensure that the data is displayed based on the condition c.date <= this.selectedReport.report_date? The current code snippet if (Math.max(...this.costs.map(c => c.date))){} seems to be causing an issue where no data is being displayed. What ...

Angular - obtain a secure reference to a lazily loaded DOM element

In my project, I have a specific template section that should only be present in the DOM when its corresponding object exists. In addition to this requirement, I need to access the form reference and attach an Observable using fromEvent('change') ...

Ensuring a Generic Type in Typescript is a Subset of JSON: Best Practices

I am interested in achieving the following: interface IJSON { [key: string]: string | number | boolean | IJSON | string[] | number[] | boolean[] | IJSON[]; } function iAcceptOnlyJSON<T subsetof IJSON>(json: T): T { return json; ...

Ways to relay messages from `Outlet` to web pages

My Layout.tsx: import { FC, useState } from 'react'; import * as React from 'react'; import { Outlet } from 'react-router-dom'; export const Layout: FC = () => { const [username, setUsername] = useState('John') ...