Skip to content
Snippets Groups Projects
Unverified Commit 55b7d232 authored by Saurabh Kumar's avatar Saurabh Kumar Committed by GitHub
Browse files

Performance improvement on application form (#3577)


This PR optimizes the code and logic responsible for unlocking
the application form on detecting human activity.

- makes the unlocking action DRY.
- move away from using jquery
- prevent the unlock action from firing on every mouse move, the unlock
  action is performed only once.
- Use more standard key names instead of keycodes.

---------

Co-authored-by: default avatarFredrik Jonsson <frjo@xdeb.org>
parent cdcbda5e
No related branches found
No related tags found
2 merge requests!23Add ReviewOpinion delete functionality to review sidebar (#3565),!20Merge in v4.7.0 and v4.8.0
(function ($) {
(function () {
"use strict";
$(".application-form").each(function () {
var $application_form = $(this);
var $application_form_button = $application_form.find(
'button[type="submit"]'
);
const form = document.querySelector(".application-form");
const button = form.querySelector("[type=submit]");
const required = form.querySelectorAll("input[required]");
const groups = form.querySelectorAll(".form__group");
const errors = form.querySelectorAll(".form__error");
// set aria-required attribute true for required fields
$application_form
.find("input[required]")
.each(function (index, input_field) {
input_field.setAttribute("aria-required", true);
});
// add label_id as aria-describedby to help texts
$application_form
.find(".form__group")
.each(function (index, form_group) {
var label = form_group.querySelector("label");
if (label) {
var label_id = label.getAttribute("for");
if (form_group.querySelector(".form__help")) {
form_group
.querySelector(".form__help")
.setAttribute("aria-describedby", label_id);
}
}
});
// set aria-invalid for field with errors
var $error_fields = $application_form.find(".form__error");
if ($error_fields.length) {
// set focus to the first error field
$error_fields[0].querySelector("input").focus();
// Set aria-required attribute true for required fields.
required.forEach(function (field) {
field.setAttribute("aria-required", true);
});
$error_fields.each(function (index, error_field) {
const inputEl = error_field.querySelector("input, textarea");
if (inputEl) {
inputEl.setAttribute("aria-invalid", true);
}
});
// Add label_id as aria-describedby to help text.
groups.forEach(function (group) {
const label = group.querySelector("label");
if (label) {
const label_id = label.getAttribute("for");
if (group.querySelector(".form__help")) {
group
.querySelector(".form__help")
.setAttribute("aria-describedby", label_id);
}
}
});
// Remove the "no javascript" messages
$(".message-no-js").detach();
if (errors.length) {
// Set focus to the first error field.
const first_error = errors[0].querySelector("input");
if (first_error) {
first_error.focus();
}
// Wait for a mouse to move, indicating they are human.
$("body").mousemove(function () {
// Unlock the form.
$application_form.attr("action", "");
$application_form_button.attr("disabled", false);
// Set aria-invalid for field with errors.
errors.forEach(function (error) {
const input = error.querySelector("input, textarea");
if (input) {
input.setAttribute("aria-invalid", true);
}
});
}
// Wait for a touch move event, indicating that they are human.
$("body").on("touchmove", function () {
// Unlock the form.
$application_form.attr("action", "");
$application_form_button.attr("disabled", false);
});
// Remove the "no javascript" messages
document.querySelector(".message-no-js").remove();
// A tab or enter key pressed can also indicate they are human.
$("body").keydown(function (e) {
if (e.keyCode === 9 || e.keyCode === 13) {
// Unlock the form.
$application_form.attr("action", "");
$application_form_button.attr("disabled", false);
}
});
const unlockApplicationForm = function () {
form.setAttribute("action", "");
button.removeAttribute("disabled");
};
// Unlock form on
// 1. mouse move
// 2. touch move
// 3. tab or enter key pressed
document.body.addEventListener("mousemove", unlockApplicationForm, {
once: true,
});
document.body.addEventListener("touchmove", unlockApplicationForm, {
once: true,
});
})(jQuery);
document.body.addEventListener(
"keydown",
function (e) {
if (e.key === "Tab" || e.key === "Enter") {
unlockApplicationForm();
}
},
{ once: true }
);
})();
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment