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

Remove JQuery from form validation code #160

Merged
merged 8 commits into from
Jun 23, 2021
110 changes: 58 additions & 52 deletions blossom/templates/website/generic_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,6 @@
{% load string_helpers %}

{% block content %}
{% comment %}
TODO: Rip jQuery out of this form
This has just enough jquery in it to be irritating, but it's the only
page that actually requires it. Since this is the only one, we'll
import jquery here and hopefully nuke it one of these days when someone
better at JS than me comes and looks at it.
{% endcomment %}
<script
src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
crossorigin="anonymous"></script>
<div class="container mt-4">
{% if slim_form %}
<div class="row">
Expand Down Expand Up @@ -136,9 +125,8 @@ <h4>{{ subheader }}</h4>
</div>

<script>
document.addEventListener("DOMContentLoaded", function (event) {
const inputs = document.querySelectorAll('.inputfile');
Array.prototype.forEach.call(inputs, function (input) {
document.addEventListener("DOMContentLoaded", function () {
document.querySelectorAll('.inputfile').forEach(function (input) {
let label = input.previousElementSibling

input.addEventListener('change', function (e) {
Expand All @@ -149,52 +137,70 @@ <h4>{{ subheader }}</h4>
label.innerText = fileName ? fileName : "browse";
});
});
// from https://www.tjvantoll.com/2012/08/05/html5-form-validation-showing-all-error-messages/
const createAllErrors = function () {
let form = $(this)
let errorList = $(".errorMessages");

const showAllErrorMessages = function () {
errorList.innerHTML = "";
// Adapted from https://www.tjvantoll.com/2012/08/05/html5-form-validation-showing-all-error-messages/
document.querySelectorAll("form").forEach(function (form) {
const errorList = form.querySelector(".errorMessages");

// Find all invalid fields within the form.
form.find(":invalid").each(function (index, node) {
if (errorList) {
const showAllErrorMessages = function () {
errorList.textContent = "";

// Find the field's corresponding label
let label = $("label[for=" + node.id + "] "),
// Find all invalid fields within the form.
form.querySelectorAll(":invalid").forEach(function (node) {
TimJentzsch marked this conversation as resolved.
Show resolved Hide resolved
// Find the field's corresponding label
const label = form.querySelector(`label[for="${node.id}"]`);
// Opera incorrectly does not fill the validationMessage property.
message = node.validationMessage || 'Invalid value.';

// jquery won't add the same class multiple times, so we can have
// addClass run for each loop.
errorList.addClass("mt-3");
errorList.append(
'<div class="alert alert-danger" role="alert">\n' + label.html() + " " + message + '\n</div>'
)
const message = node.validationMessage || 'Invalid value.';

if (!errorList.classList.contains("mt-3")) {
errorList.classList.add("mt-3");
}

// Add the error message to the list
const errorMessage = document.createElement("span");
errorMessage.innerText = " " + message;

const errorElement = document.createElement("div");
errorElement.classList.add("alert");
errorElement.classList.add("alert-danger");
errorElement.role = "alert";
if (label) {
errorElement.appendChild(label.cloneNode(true));
}
errorElement.appendChild(errorMessage);

errorList.appendChild(errorElement);
});
};

// Support Safari
form.addEventListener("submit", function (event) {
if (this.checkValidity && !this.checkValidity()) {
const firstInvalid = form.querySelector(":invalid");
if (firstInvalid) {
firstInvalid.focus();
}
event.preventDefault();
}
});
};

// Support Safari
form.on("submit", function (event) {
if (this.checkValidity && !this.checkValidity()) {
$(this).find(":invalid").first().focus();
event.preventDefault();
const submitButton = form.querySelector("input[type=submit], button:not([type=button])");
if (submitButton) {
submitButton.addEventListener("click", showAllErrorMessages);
}
});

$("input[type=submit], button:not([type=button])", form)
.on("click", showAllErrorMessages);

$("input", form).on("keypress", function (event) {
let type = $(this).attr("type");
if (/date|email|month|number|search|tel|text|time|url|week/.test(type)
&& event.keyCode === 13) {
showAllErrorMessages();
}
});
};

$("form").each(createAllErrors);
form.querySelectorAll("input").forEach(function (inputElem) {
inputElem.addEventListener("keypress", function (event) {
const checkedTypes = ["date", "email", "month", "number", "search", "tel", "text", "time", "url", "week"]
if (checkedTypes.includes(inputElem.type)
&& event.code === "Enter") {
showAllErrorMessages();
}
});
});
}
});
})
</script>

Expand Down