2

I'm using ionic 4.7.0.

The problem I'm reporting happens on Chrome and Firefox.

Actual Behaviour:

Using ion-select with a big list of options, when you open the alert, ion-select does not automatically scroll to the selected value. The user sees the first value in the list of options and he might think that nothing is selected

Expected Behaviour:

When the alert is open, the view automatically center on the selected value

I created this stackblitz to highlight the behaviour, we can see on the stackblitz that on loading the view, the selected value is 11:00 but when you open the alert (by clicking on ion-select), I would expect the view to be automatically scrolled on the selected value.

Is that expected behaviour with ion-select?

I found a few questions talking about the same subject but nothing that really answers the question:

Tonio
  • 4,082
  • 4
  • 35
  • 60

2 Answers2

6

This is currently not a feature in Ionic but there is an open issue. Give it a thumbs up to increase its priority.

For the moment you can use a workaround:

window.addEventListener('ionAlertDidPresent', e => {
  const selected = (e.target as HTMLElement).querySelector('[aria-checked="true"]');
  selected && selected.scrollIntoView();
});

This listener will fire each time an alert is preseted. It then looks for the (first) selected element using the aria-checked HTML attribute and scrolls it into view.

You might want to take a look at the parameters for scrollIntoView(), e.g. to scroll so the selected item is at the bottom.

To only affect the ion-select alerts you can check if the alert has the select-alert (or single-select-alert) class. To only affect a single alert you can give the alert an ID by passing it in the interfaceOptions property of ion-select.

As mentioned, this is a workaround and might stop working if the component changes.

Thomas
  • 8,426
  • 1
  • 25
  • 49
  • OMG, I should have found the github issue/feature request/bug. I did not want to believe that this was not working by default, I really thought I was doing something wrong. – Tonio Jan 28 '20 at 16:13
2

I recently rewrote our autoscroll directive, so I thought I'd share it here. It works for all IonSelect interfaces (Alert, Popover and ActionSheet).

import { Directive, HostListener } from '@angular/core';
import { IonSelect } from '@ionic/angular';

/**
 * Autoscroll to the selected option of an ion-select when opened.
 */
@Directive({
  selector: 'ion-select[autoscroll]'
})
export class AutoscrollSelectDirective {

  constructor(
    private ionSelect: IonSelect
  ) {}

  @HostListener('click')
  scrollSoon(): void {
    let keBab = '';
    switch (this.ionSelect.interface) {
      case 'alert': keBab = 'Alert'; break;
      case 'action-sheet': keBab = 'ActionSheet'; break;
      case 'popover': keBab = 'Popover'; break;
    }

    if (keBab) {
      window.addEventListener(
        `ion${keBab}DidPresent`,
        e => {
          const parent: Element = <any>e.target;
          const scrollTarget = keBab === 'ActionSheet'
              ? parent.querySelector('.action-sheet-selected')
              : parent.querySelector('[aria-checked=true]')?.closest('.select-interface-option');
          if (scrollTarget) {
            scrollTarget.scrollIntoView();
          }
        },
        {once: true}
      );
    }
  }

}
Sygmoral
  • 7,021
  • 2
  • 23
  • 31