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>
|
||||
`;
|
||||
```
|
||||
|
||||
## 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