htmx Tutorial · Common Patterns · Lesson 20 of 30
Inline Validation
Check a field on the server as soon as the user leaves it, and show the message next to the field.
The pattern
Some checks need the server: "is this email already registered?", "is this coupon valid?". Validate one field at a time when it changes:
- The field's wrapper sends
hx-post="/check/email"onchange(orinput changed delay:500ms), withhx-target="this"andhx-swap="outerHTML". - The server returns the wrapper again, with the value, an error or success message, and
aria-invalid.
<form hx-post="/signup" hx-target="#done">
<div hx-target="this" hx-swap="outerHTML">
<label>Email <input name="email" type="email" hx-post="/check/email" hx-trigger="change"></label>
<small>Try [email protected]</small>
</div>
<button>Sign up</button>
</form>
<p id="done"></p>
<!-- The pretend server: on a real site this part is your backend (Python, PHP, Node, Go...) -->
<script>
server.post("/check/email", (req) => {
const email = req.body.email || "";
const taken = email.toLowerCase() === "[email protected]";
return `<div hx-target="this" hx-swap="outerHTML">
<label>Email <input name="email" type="email" value="${server.escape(email)}" hx-post="/check/email"
hx-trigger="change" aria-invalid="${taken}" aria-describedby="email-msg"></label>
<small id="email-msg" style="color:${taken ? "#b91c1c" : "#15803d"}">
${taken ? "That email is already registered." : "Looks good!"}</small></div>`;
});
server.post("/signup", (req) => "Signed up " + server.escape(req.body.email));
</script>
The final submit must validate everything again on the server: inline checks are a convenience, and the situation may change between the check and the submit.
Test yourself
If the email is checked inline, does the final form submit still need server-side validation?
Yes, always validate again on submitNo, the inline check is enoughOnly for GET formsOnly if JavaScript is disabled
Show answer
Answer: Yes, always validate again on submit
Inline checks are for user experience; the submit handler must still enforce the rules.