Joey33's avatar

Joey33 wrote a reply+100 XP

4mos ago

I've been trying to implement tanstack from shadcn but had issues with displaying errors returned from failed validation by laravel so ended up with useForm from Inertia and zod for client-side. Works like a charm. Here you are:

import * as z from 'zod';

rules:

...
const LessonSchema = z.object({
    title: z
        .string()
        .min(5, 'Title must be at least 5 characters.')
        .max(10, 'Title must be at most 32 characters.')
    description: z
        .string()
        .min(20, 'Description must be at least 20 characters.')
        .max(100, 'Description must be at most 100 characters.'),
});

later in the form component closure

form fields

 <div>
                            <label htmlFor="title" className="mb-1 block text-sm font-medium text-gray-700">
                                Title
                            </label>
                            <input
                                type="text"
                                id="title"
                                value={data.title}
                                // Clear client-side error when user starts typing
                                onChange={(e) => {
                                    setData('title', e.target.value);
                                    if (clientErrors.title) {
                                        setClientErrors((prev) => ({ ...prev, title: undefined }));
                                    }
                                }}
                                className={`w-full rounded-lg border p-3 shadow-sm transition duration-150 ${
                                    isError('title')
                                        ? 'border-red-500 focus:ring-red-500'
                                        : 'border-gray-300 focus:ring-green-500'
                                }`}
                                onBlur={() => validateData(data)} // Validate on blur for immediate feedback
                            />
                            {getError('title') && <p className="mt-1 text-sm text-red-600">{getError('title')}</p>}
                        </div>