Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scroll invalid form element to top if it's hidden by form navigation buttons #307

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
scroll to invalid form element if it's behind form navigation buttons
A form element may be in view port but hidden by form navigation buttons
with have a fixed position on mobile. In that case the form element should
still be scrolled to top of view port to make it visible.
  • Loading branch information
jelhan committed Nov 16, 2019
commit ef95683387af7b62ce03e1b53d0330be430f899a
24 changes: 19 additions & 5 deletions app/helpers/scroll-first-invalid-element-into-view-port.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@ import { helper } from '@ember/component/helper';
import { next } from '@ember/runloop';
import { assert } from '@ember/debug';

function elementIsNotVisible(element) {
let elementPosition = element.getBoundingClientRect();
let windowHeight = window.innerHeight;

// an element is not visible if
return false ||
// it's above the current view port
elementPosition.top <= 0 ||
// it's below the current view port
elementPosition.bottom >= windowHeight ||
// it's in current view port but hidden by fixed navigation
(
getComputedStyle(document.querySelector('.cr-steps-bottom-nav')).position === 'fixed' &&
elementPosition.bottom >= windowHeight - document.querySelector('.cr-steps-bottom-nav').offsetHeight
);
}

function scrollFirstInvalidElementIntoViewPort() {
// `schedule('afterRender', function() {})` would be more approperiate but there seems to be a
// timing issue in Firefox causing the Browser not scrolling up far enough if doing so
Expand All @@ -16,11 +33,8 @@ function scrollFirstInvalidElementIntoViewPort() {
// focus first invalid control
invalidInput.focus({ preventScroll: true });

// scroll to label or legend of first invalid control
if (
invalidInput.getBoundingClientRect().top <= 0 ||
invalidInput.getBoundingClientRect().bottom >= window.innerHeight
) {
// scroll to label or legend of first invalid control if it's visible yet
if (elementIsNotVisible(invalidInput)) {
// Radio groups have a label and a legend. While the label is per input, the legend is for
// the whole group. Croodle should bring the legend into view in that case.
// Due to a bug in Ember Bootstrap it renders a `<label>` instead of a `<legend>`:
Expand Down