Ionic date time picker update columns dynamically

Viewed 897

I have the following requirement which aim looking for some thing similar ready.

Time select where user select Hours and minutes. Hours will be provider could be any (1,5,6,13,19) etc. Each hour has its own minutes the data structure like this

[ 
  { 
    hour: 1,
    minutes: [0, 15, 30],
  },
  {
    hour: 4,
    minutes: [15, 25, 40],
  },
]

When user select hour the minute selection will change based on the structure.

Any idea if there is some thing this or similar is implemented so I can use it?

1 Answers

The "official" answer would be: No, that's not possible in the current version of Ionic (4/5). The reason why it's not possible is because the ion-datetime component doesn't emit an event when the colums are changed (only when the user clicks on 'done' or 'cancel').

Please notice that there's a Github issue for that change that was then included in a bigger Github issue that includes a lot of things that should be fixed/added to the ion-datetime picker.

Please also notice that a member of the Ionic team mentioned in this comment that they are working on a complete overhaul of the ion-datetime component as part of the next major version of Ionic Framework so this may be available very soon.


That being said, in this PR a new ionPickerColChange event was added to the date time picker component but it's not available externally (it's not emitted by the component, only handled internally).

But, since the date time picker component is not hidden behind the Shadow DOM, we can use some javascript code as a workaround to listen to changes in the columns and update the available options.

Keep in mind that the following demo is just that, a workaround, so it may stop working at anytime and may have some unexpected issues/bugs.

Please take a look at this working Stackblitz demo:

demo project

The code should be self-explanatory but the most important part of it is the handlePickerOpen() method which gets the ion-picker-column elements and adds a listener to handle what happens when the hour/minute columns are changed by the user:

public handlePickerOpen(): void {
    // Keep the current value so we can rollback the change
    // if the user clicks "cancel"
    this.selectedDateTime = this.latestSelectedDateTime;

    // Wait for the picker to be rendered so that we can
    // get its columns
    setTimeout(() => {
      try {
        const pickerCols = document.querySelectorAll("ion-picker-column");

        const hourCol = pickerCols[0];
        const minuteCol = pickerCols[1];

        hourCol.addEventListener(
          "ionPickerColChange",
          event => { this.handleColumnChange(event); },
          false
        );

        minuteCol.addEventListener(
          "ionPickerColChange",
          event => { this.handleColumnChange(event); },
          false
        );
      } catch (e) {
        console.error(e);
      }
    }, 400);
  }
Related