material icon indicating copy to clipboard operation
material copied to clipboard

radio-group: does not scroll into view when changed

Open NilsAtGoogle opened this issue 7 years ago • 3 comments

Bug

When the user changes a radio group, the radio group should be scrolled into view if it's not currently visible (i.e. mimic the behavior of standard HTML inputs).

CodePen and steps to reproduce the issue:

AngularJS material demo

Detailed Reproduction Steps:

  1. set focus on a radio group
  2. scroll out of view
  3. use keyboard up/down to change selected radio button

What is the expected behavior?

radio group is scrolled into view, so the user is aware their action has changed the input

What is the current behavior?

radio group remains off screen

What is the use-case or motivation for changing an existing behavior?

conformance with HTML input behavior

Which versions of AngularJS, Material, OS, and browsers are affected?

  • AngularJS: any
  • AngularJS Material: 1.1.10
  • OS: any
  • Browsers: Chrome, Firefox (probably all browsers)

Is there anything else we should know? Stack Traces, Screenshots, etc.

NilsAtGoogle avatar Nov 02 '18 21:11 NilsAtGoogle

I created a CodePen to demonstrate how this behavior compares to the default HTML radio input.

Splaktar avatar Nov 03 '18 01:11 Splaktar

Hi! Is anyone working on this?

kylecjo avatar Feb 16 '19 05:02 kylecjo

I've implemented a (somewhat limited) workaround in a local codebase, in case anyone's need is urgent (requires scrollIntoViewIfNeeded and doesn't support model-less radio groups)

This is a postLink function that decorates the original postLink


const scrollFixLink = (scope, element, attrs, [radioGroup, ngModel]) => {
  if (!ngModel) {
    // Do nothing when there is no model
    return;
  }
  const scrollIfNeededOnChange = () => {
    // Experimental: https://caniuse.com/#feat=scrollintoviewifneeded
    if (element[0].scrollIntoViewIfNeeded) {
      element[0].scrollIntoViewIfNeeded(/* opt_center */ false);
    }
  };
  ngModel.$viewChangeListeners.push(scrollIfNeededOnChange);
  scope.$on(
      '$destroy',
      () => remove(ngModel.$viewChangeListeners, scrollIfNeededOnChange));
};

const mdRadioGroupDecorator = ($delegate) => {
  const mdRadioGroup = $delegate[0];
  mdRadioGroup.link.post = scrollFixLink;
  return $delegate;
};

NilsAtGoogle avatar Feb 16 '19 05:02 NilsAtGoogle