PickerController Dynamic Options

I have a custom calendar header element for conferences. It has the Month title and each day of the month appears below in a scrollable row. You can change the month by tapping the Month title which brings up a date picker via the PickerController. I need to update it so it allows selecting the year as well, but each year may have different months associated with it.

When I change the year I have two problems.

  1. The first time I change the year the ionChange observable does not emit a change event. I have to change the year multiple times to get it to fire.

  2. When I change the months dynamically, the view doesn’t reevaluate and the new months in the column are squashed together.

Here is a gif showing what I’m looking at-

Here is my code-

  public openDatePicker() {

    this.updatePickerMonthOptions(this.years[0].year);

    let columns: PickerColumn[] = [];

    if(this.years.length > 1) {
      columns.push(this.pickerYearColumn);
    }

    columns.push(this.pickerMonthColumn);

    var picker = this.pickerController.create({
      columns: columns,
      buttons: [
        {
          text: 'Cancel',
          role: 'cancel'
        },
        {
          text: 'Done',
          handler: (data: any) => {
            this.setActiveMonth(data.Month.value);
          }
        }
      ]
    });

    let yr = this.activeYear;

    picker.ionChange.subscribe((change) => {
      if(change.Year.value !== yr) {
        yr = change.Year.value;
        this.updatePickerMonthOptions(yr);
        picker.refresh();
      }
    });

    picker.present();
    picker.refresh();

  }

  private updatePickerMonthOptions(year: number) {
    this.pickerMonthColumn.options.length = 0;
    
    this.getYear(year).months.forEach((mn) => {
      this.pickerMonthColumn.options.push({
        value: mn.month,
        text: mn.monthName
      });
    });
  }

There wasn’t much information about this service in the docs so I’m wondering if they expected anyone to try using it outside of their components.

I hacked it and got it working the way I wanted it to. Obviously I would prefer not hacking so let me know if this is open to pull requests or I’m missing some api.

  picker.ionChange.subscribe((change) => {
      if(change.Year.value !== yr) {

        yr = change.Year.value;

        this.updatePickerMonthOptions(yr);

        setTimeout(() => {
          (<any>picker)._cmp._component._cols._results.forEach(r => {
            r.col.prevSelected = null
          });

          picker.refresh();
        });
      }
    });

    picker.present();
    

    setTimeout(() => {
      (<any>picker)._cmp._component._cols._results.forEach(r => {
        r.lastIndex = 0;
        r.col.selectedIndex = 0;
        r.col.prevSelected = null
      });
      
      picker.refresh();
    });

Here it is working-

https://www.npmjs.com/package/ionic-conference-calendar-header

1 Like

Thank you for sharing your resolution. This saved me hours of frustration.