Merge pull request #1248 from ing-bank/docs/addBackendValidationExample
docs(validation): add backend validator example
This commit is contained in:
commit
155b0cda4e
1 changed files with 89 additions and 0 deletions
|
|
@ -695,3 +695,92 @@ export const FormValidationReset = () => html`
|
||||||
</lion-form>
|
</lion-form>
|
||||||
`;
|
`;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Backend validation
|
||||||
|
|
||||||
|
Backend validation is needed in some cases. For example, you have a sign up form, the username could be already taken. You can add an `AsyncValidator` to check the availability when the `username` field is changed but you may have a conflict when you submit the form (another user take the username in parallel).
|
||||||
|
|
||||||
|
```js preview-story
|
||||||
|
export const backendValidation = () => {
|
||||||
|
// Mock
|
||||||
|
function fakeFetch(ms = 0, withError = false) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(
|
||||||
|
new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
message: withError ? 'Username is already taken' : '',
|
||||||
|
}),
|
||||||
|
{ status: withError ? 400 : 200 },
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}, ms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let backendValidationResolver;
|
||||||
|
let backendErrorMessage = 'Unknown Error';
|
||||||
|
let isBackendCallPending = false;
|
||||||
|
|
||||||
|
const submitHandler = ev => {
|
||||||
|
const lionForm = ev.target;
|
||||||
|
if (lionForm.hasFeedbackFor.includes('error')) {
|
||||||
|
const firstFormElWithError = lionForm.formElements.find(el =>
|
||||||
|
el.hasFeedbackFor.includes('error'),
|
||||||
|
);
|
||||||
|
firstFormElWithError.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isBackendCallPending = true;
|
||||||
|
lionForm.formElements.username.validate(); // => backendValidationResolver will be assigned
|
||||||
|
const formData = lionForm.serializedValue;
|
||||||
|
fakeFetch(2000, formData.simulateError.length).then(async response => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
backendErrorMessage = (await response.json())?.message;
|
||||||
|
backendValidationResolver(true);
|
||||||
|
}
|
||||||
|
backendValidationResolver(false);
|
||||||
|
isBackendCallPending = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackendValidator extends Validator {
|
||||||
|
static get validatorName() {
|
||||||
|
return 'backendValidator';
|
||||||
|
}
|
||||||
|
static get async() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
async execute() {
|
||||||
|
if (isBackendCallPending) {
|
||||||
|
return await new Promise(resolve => (backendValidationResolver = resolve));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static getMessage({ fieldName, modelValue, params: param }) {
|
||||||
|
return backendErrorMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
lion-input[is-pending] {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<lion-form @submit=${submitHandler}>
|
||||||
|
<form>
|
||||||
|
<lion-input
|
||||||
|
label="username"
|
||||||
|
name="username"
|
||||||
|
.validators="${[new BackendValidator(''), new Required()]}"
|
||||||
|
.modelValue="${''}"
|
||||||
|
></lion-input>
|
||||||
|
<lion-checkbox-group name="simulateError">
|
||||||
|
<lion-checkbox label="Check to simulate a backend error"></lion-checkbox>
|
||||||
|
</lion-checkbox-group>
|
||||||
|
<lion-button raised>Submit</lion-button>
|
||||||
|
</form>
|
||||||
|
</lion-form>
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue