Integrating server-side validation into HTML's client-side validation APIs
by mcsf
HTML
<p><strong>
Integrating server-side validation into HTML's client-side validation APIs
</strong></p>
<p>
Try with:
</p>
<ul>
<li><a href="#" onclick="tryAddress(event)">localhost</a></li>
<li><a href="#" onclick="tryAddress(event)">a@localhost</a></li>
<li><a href="#" onclick="tryAddress(event)">b@localhost</a></li>
</ul>
<form onsubmit="event.preventDefault(); validateForm(this)">
<fieldset>
<legend>Email</legend>
<input type="email" required oninput="this.setCustomValidity('')">
</fieldset>
<p><input type="submit"></p>
</form>
<dialog>
<p>OK!</p>
<form method="dialog">
<button>Close</button>
</form>
</dialog>
CSS
:user-invalid {
background-color: yellow;
}
.pending, .pending input {
color: lightgrey;
}
JavaScript
async function validateForm(form) {
const input = form.querySelector('input[type="email"]');
const button = form.querySelector('input[type="submit"]');
const dialog = document.querySelector('dialog');
form.classList.add('pending');
button.disabled = true;
try {
const result = await doAsyncRequest(input.value);
dialog.showModal();
} catch (e) {
input.setCustomValidity(e);
form.reportValidity();
} finally {
form.classList.remove('pending');
button.disabled = undefined;
}
}
function doAsyncRequest(email) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (email === 'a@localhost') {
reject('Address taken');
} else {
resolve();
}
}, 600);
})
}
function tryAddress({target}) {
const input = document.querySelector('input[type="email"]');
const button = document.querySelector('input[type="submit"]');
input.setCustomValidity('');
input.value = target.innerText;
button.click();
}