[HELP] triggering invalid state manually on input tags to display errors (with server-side valid & useActionState) #3480
-
Hi. I'm using DaisyUI v5, it's awesome. PROBLEMI need your help, it seems I can't find a way to manually trigger the As far as I understood, the DaisyUI v5 But, for example, when using password & password-confirm, I need to validate if the password-confirm matches the password field on the server. EXAMPLE OUTPUT
ABOUT MY SERVER-SIDE PROCESSINGI'm using Next.js 15 (latest), CODE EXAMPLEFORM COMPONENT 'use client';
import { useActionState } from 'react';
import { signinAction } from '@/features/signin/actions/action';
// ...
const default_state: SigninFormStatus = {
// ...
};
export default function Form() {
const [state, formAction, isPending] = useActionState(signinAction, default_state);
//...
return (
<form action={formAction}>
{/* password */}
<PasswordValidatorInput
// other common props as attributes
pattern={validationPassword.regex}
disabled={isPending}
defaultValue={state.values.password}
validator_client={t('Password.invalid_msg')}
validator_server={state.errors.password}
/>
{/* password_repeat */}
<PasswordValidatorInput
// other common props as attributes
pattern={validationPassword.regex}
disabled={isPending}
defaultValue={state.values.password_repeat}
validator_client={t('PasswordRepeat.invalid_msg')}
validator_server={state.errors.password}
/>
{/* submit */}
<Submit disabled={isPending} text={t('submit_text')} />
</form>
);
} PasswordValidatorInput.tsx 'use client';
import React, { useEffect, useRef, useState } from 'react';
// ...
export default function PasswordValidatorInput({
// other common props as attributes
pattern, // RegExp type
disabled, // boolean
defaultValue, // string or ''
validator_client, // string
validator_server, // string or null
}: PasswordProps) {
// other state for password input visibility
// my try to trigger input tag invalid state
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (inputRef.current && validator_server) {
inputRef.current.setCustomValidity(validator_server);
inputRef.current.reportValidity();
} else if (inputRef.current) {
inputRef.current.setCustomValidity('');
}
}, [validator_server]);
return (
<div className='mb-2'>
<label className='input validator w-full'>
// ...
<input
pattern={pattern.source}
disabled={disabled}
defaultValue={defaultValue}
className='input validator !border-none p-0 !outline-none'
ref={inputRef}
/>
// ...
</label>
<div
className='validator-hint !mx-1 !mt-1 !mb-2 hidden'
// I use dangerouslySetInnerHTML since ther is HTML markup in validator text string
dangerouslySetInnerHTML={{ __html: validator_server ? (validator_server as TrustedHTML) : (validator_client as TrustedHTML) }}
></div>
</div>
);
} action.ts 'use server';
// ...
export async function signupAction(state: SignupFormStatus, formData: FormData) {
// get form fields in variable ...
// set submitter form fileds in return object
const newState = structuredClone(state);
newState.values = formFields;
// run regex validations
const validations = [
{ field: 'password' as const, valid: validationPassword.test(formFields.password || ''), errorMsg: t('Password.invalid_msg') },
{ field: 'password_repeat' as const, valid: formFields.password === formFields.password_repeat, errorMsg: t('PasswordRepeat.no_match') },
];
validations.forEach(({ field, valid, errorMsg }) => {
if (!valid) newState.errors[field] = errorMsg;
});
// return if validations failed
if (Object.values(newState.errors).some((err) => err)) {
return newState;
}
// rest (update db,...)
} HOW TO SOLVEThe point is to find a way how to trigger |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Probably you can get an answer faster in a Next.js community. You're apparently using |
Beta Was this translation helpful? Give feedback.
Probably you can get an answer faster in a Next.js community.
daisyUI just sets color based on native HTML validation.
You're apparently using
setCustomValidity
already 👍 so if the React part works correctly, that should work as well.