Skip to content

Commit

Permalink
Scroll to first invalid element
Browse files Browse the repository at this point in the history
  • Loading branch information
Lubosky committed Aug 30, 2023
1 parent b95f85b commit 17d0e71
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions app/javascript/controllers/appraisal_form_controller.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { scrollToElement } from '../helpers';

export default class extends ApplicationController {
static values = {
success: String,
Expand Down Expand Up @@ -39,11 +41,15 @@ export default class extends ApplicationController {
detail: { responseJSON: errors },
} = event;
const panel = target.closest('.panel-body');
let form;

this.resetErrors(panel);

Object.entries(errors).forEach(([key, values]) => {
const field = panel.querySelector(`[name*='[${key}]']`);
if (!form) {
form = field.closest('form');
}
const container = field.closest('.form-container');

if (field && this.shouldValidateField(field)) {
Expand All @@ -60,6 +66,19 @@ export default class extends ApplicationController {
}
}
});

const firstInvalidField = Array.from(form.elements).find((field) => field.ariaInvalid == 'true');

if (this.visible(firstInvalidField)) {
scrollToElement(firstInvalidField);
firstInvalidField.focus();
} else {
const altTarget = firstInvalidField.closest('.form-container').querySelector('label button');
if (altTarget) {
scrollToElement(altTarget);
altTarget.focus();
}
}
};

stash = (event) => {
Expand Down Expand Up @@ -140,6 +159,7 @@ export default class extends ApplicationController {
element.querySelectorAll('.field-with-errors').forEach((el) => el.classList.remove('field-with-errors'));
element.querySelectorAll('.rag-error').forEach((el) => el.classList.remove('rag-error'));
element.querySelectorAll('[aria-errormessage]').forEach((el) => el.removeAttribute('aria-errormessage'));
element.querySelectorAll('[aria-invalid]').forEach((el) => el.removeAttribute('aria-invalid'));
element.querySelectorAll('.alert').forEach((el) => el.remove());
}

Expand All @@ -163,6 +183,7 @@ export default class extends ApplicationController {
return errors.forEach((message) => {
const [alert, identifier] = this.createAlert('danger', message);
field.setAttribute('aria-errormessage', identifier);
field.setAttribute('aria-invalid', true);
return container.insertAdjacentHTML('afterbegin', alert);
});
}
Expand Down

0 comments on commit 17d0e71

Please sign in to comment.