<p>Required fields are marked with an asterisk <abbr title="Required field">*</abbr></p>
<!-- We're using novalidate attribute here to avoid the built in browser validation -->
<form method="post" action="/" id="test-form" novalidate>
<div id="form-message" class="form-message" role="alert" aria-atomic="true"></div>
<div class="form-field">
<label for="name">Name <abbr title="required">*</abbr></label>
<input type="name" name="name" id="name" required />
<div class="form-field">
<label for="email">E-mail <abbr title="required">*</abbr></label>
<input type="email" name="email" id="email" required />
</div>
<button type="submit">Send</button>
</form>
label {
display: block;
}
.form-message {
background-color: #ffffd4;
}
.form-field {
margin: 1rem 0;
}
.field-error {
color: maroon;
}
/* This javascript is only made to make a quick
* demonstration of the form states when validating.
* The code itself is a quick hack and nothing that
* should be used in the real world (wide web).
* I'm not proud of this...
*/
const testForm = document.getElementById("test-form");
const formMessageHolder = document.getElementById("form-message");
const nameField = document.getElementById("name");
const emailField = document.getElementById("email");
testForm.addEventListener("submit", event => {
event.preventDefault();
const nameValue = nameField.value;
const emailValue = emailField.value;
const nameDescNode = document.getElementById("nameDesc");
const emailDescNode = document.getElementById("emailDesc");
// Cleanup inline error messages
if (nameDescNode) {
nameDescNode.parentNode.removeChild(nameDescNode);
}
if (emailDescNode) {
emailDescNode.parentNode.removeChild(emailDescNode);
}
// Display error message if form is invalid
if (nameValue === "" || emailValue === "") {
formMessageHolder.innerHTML = `
<p>Please review the form and fix the following errors:</p>
<ul>
${nameValue ? "" : "<li>The name field must be filled in.</li>"}
${emailValue ? "" : "<li>The e-mail field must be filled in.</li>"}
</ul>
`;
if (nameValue === "") {
createErrorDescription("nameDesc", nameField, "The name field must be filled in.");
}
if (emailValue === "") {
createErrorDescription("emailDesc", emailField, "The e-mail field must be filled in.");
}
// Set focus on the first invalid field
nameValue === "" ? nameField.focus() : emailField.focus();
} else {
// Display success message if form was sent successfully
formMessageHolder.innerHTML = "<p>The form was sent successfully!</p>";
}
});
// Helper method to create an field error message
const createErrorDescription = (name, field, message) => {
var newNode = document.createElement("div");
newNode.setAttribute("id", name);
newNode.classList.add("field-error");
field.setAttribute("aria-describedby", name);
newNode.innerHTML = message;
field.after(newNode);
};
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.