payload
payload copied to clipboard
Displayed validation error gets stuck
Link to reproduction
No response
Describe the Bug
When the validate function returns an error, it gets stuck showing that first error, even if the user types new content. This is misleading when the user fixes one issue but has another issue that the validation function is catching.
To Reproduce
Set up an input like this and publish to trigger validation on typing. Then type 12345 in the input. When you get to 3, it shows Error number 3 as expected. But then typing subsequent characters doesn't update the displayed error, even though the logs show the validate function returns different errors.
{
name: `test`,
label: `Test`,
type: 'text',
validate: async (data: string) => {
if (!data || data.length < 3) {
return true;
}
const errStr = `Error number ${data.length} `;
console.log(errStr);
return errStr;
},
},
Payload Version
2.16.1
Adapters and Plugins
@payloadcms/richtext-slate 1.5.2
I can get around this by watching my inputs and manually calling validateForm each time, though this isn't very intuitive as a solution. More context in this discord thread.
function startValidation(formHookResult: ReturnType<typeof useForm>) {
const { formRef, setSubmitted, validateForm } = formHookResult;
setSubmitted(true);
// make sure we have the monaco editor textarea element on the page, and add an event listener
if (formRef.current) {
const inputFields = Object.values(formRef.current).filter(
(el) => el.id === 'field-subject' || el.className === 'inputarea monaco-mouse-cursor-text',
);
// if we have inputs, add an event listener on input and call validateForm manually
if (inputFields.length) {
inputFields.forEach((field) => {
// we call validateForm in the next tick so the value has been updated
field.addEventListener('input', () => setTimeout(() => void validateForm()));
});
}
}
// if the above failed, do it again in a second
setTimeout(() => startValidation(formHookResult), 1000);
}
and
// This is an invisible element that exists only to trigger the form's validate-upon-input behavior.
{
type: 'ui',
name: 'form-validation-trigger',
admin: {
components: {
Field: () => {
// `setSubmitted` seems to mainly be for handling the validation behavior of the form on input.
// By setting to true, the form will validate the fields on input, which is the behavior we want.
// Otherwise, it only validates on input after clicking "Publish" (Save Draft doesn't trigger validation)
const formHookResult = useForm();
startValidation(formHookResult);
return null;
},
},
},
},
@PatrikKozak Any chance we can get a release for v2 in the next week?
Hey @benjaffe - yup, we'll get a release out for v2 asap!
@benjaffe v2.27.0 is released with the above fix for this issue.
Thanks so much @PatrikKozak, and huge thanks for all you do on Payload ❤️
This issue has been automatically locked. Please open a new issue if this issue persists with any additional detail.