1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
+++
title = "Inline Validation"
template = "demo.html"
+++
This example shows how to do inline field validation, in this case of an email address. To do this
we need to create a form with an input that `POST`s back to the server with the value to be validated
and updates the DOM with the validation results.
We start with this form:
```html
<h3>Signup Form</h3>
<form hx-post="/contact">
<div hx-target="this" hx-swap="outerHTML">
<label>Email Address</label>
<input name="email" hx-post="/contact/email" hx-indicator="#ind">
<img id="ind" src="/img/bars.svg" alt="Checking..." class="htmx-indicator"/>
</div>
<div class="form-group">
<label>First Name</label>
<input type="text" class="form-control" name="firstName">
</div>
<div class="form-group">
<label>Last Name</label>
<input type="text" class="form-control" name="lastName">
</div>
<button class="btn primary">Submit</button>
</form>
```
Note that the first div in the form has set itself as the target of the request and specified the `outerHTML`
swap strategy, so it will be replaced entirely by the response. The input then specifies that it will
`POST` to `/contact/email` for validation, when the `changed` event occurs (this is the default for inputs).
It also specifies an indicator for the request.
When a request occurs, it will return a partial to replace the outer div. It might look like this:
```html
<div hx-target="this" hx-swap="outerHTML" class="error">
<label>Email Address</label>
<input name="email" hx-post="/contact/email" hx-indicator="#ind" value="test@foo.com">
<img id="ind" src="/img/bars.svg" alt="Checking..." class="htmx-indicator"/>
<div class='error-message'>That email is already taken. Please enter another email.</div>
</div>
```
Note that this div is annotated with the `error` class and includes an error message element.
This form can be lightly styled with this CSS:
```css
.error-message {
color:red;
}
.error input {
box-shadow: 0 0 3px #CC0000;
}
.valid input {
box-shadow: 0 0 3px #36cc00;
}
```
To give better visual feedback.
Below is a working demo of this example. The only email that will be accepted is `test@test.com`.
<style>
.error-message {
color:red;
}
.error input {
box-shadow: 0 0 3px #CC0000;
}
.valid input {
box-shadow: 0 0 3px #36cc00;
}
</style>
{{ demoenv() }}
<script>
//=========================================================================
// Fake Server Side Code
//=========================================================================
// routes
init("/demo", function(request, params){
return demoTemplate();
});
onPost("/contact", function(request, params){
return formTemplate();
});
onPost(/\/contact\/email.*/, function(request, params){
var email = params['email'];
if(!/\S+@\S+\.\S+/.test(email)) {
return emailInputTemplate(email, "Please enter a valid email address");
} else if(email != "test@test.com") {
return emailInputTemplate(email, "That email is already taken. Please enter another email.");
} else {
return emailInputTemplate(email);
}
});
// templates
function demoTemplate() {
return `<h3>Signup Form</h3><p>Enter an email into the input below and on tab out it will be validated. Only "test@test.com" will pass.</p> ` + formTemplate();
}
function formTemplate() {
return `<form hx-post="/contact">
<div hx-target="this" hx-swap="outerHTML">
<label for="email">Email Address</label>
<input name="email" id="email" hx-post="/contact/email" hx-indicator="#ind">
<img id="ind" src="/img/bars.svg" alt="Checking..." class="htmx-indicator"/>
</div>
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" class="form-control" name="firstName" id="firstName">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" name="lastName" id="lastName">
</div>
<button type='submit' class="btn primary" disabled>Submit</button>
</form>`;
}
function emailInputTemplate(val, errorMsg) {
return `<div hx-target="this" hx-swap="outerHTML" class="${errorMsg ? "error" : "valid"}">
<label>Email Address</label>
<input name="email" hx-post="/contact/email" hx-indicator="#ind" value="${val}" aria-invalid="${!!errorMsg}">
<img id="ind" src="/img/bars.svg" alt="Checking..." class="htmx-indicator"/>
${errorMsg ? (`<div class='error-message' >${errorMsg}</div>`) : ""}
</div>`;
}
</script>
|