final-form icon indicating copy to clipboard operation
final-form copied to clipboard

Problem triggering form validations without calling submit.

Open omerman opened this issue 5 years ago • 9 comments

I think its trivial to have a way to trigger form validations manually without calling submit.

Is there a way to achieve this? Thanks you rock!

omerman avatar Dec 07 '20 21:12 omerman

@omerman what are you trying to accomplish with this? if you're using the validate method that's passed into the Form instance then you could call that separately

Dakkers avatar Dec 10 '20 15:12 Dakkers

@omerman what are you trying to accomplish with this? if you're using the validate method that's passed into the Form instance then you could call that separately

Actually I have validations on each field of the form.. I would like to validate them in any given time without calling the submit to do so.. Do you have an idea how to approach it?

omerman avatar Dec 11 '20 23:12 omerman

are you using react-final-form? if so, each Field has a validate prop. if this is a function you define inside your class then you could cal it form anywhere. if you're not using react-final-form, I'm not sure what the right approach is here.

Dakkers avatar Dec 12 '20 00:12 Dakkers

@Dakkers I don't think it is relevant where I use final-form.. I think its trivial to have the ability to trigger a validation at any time using the form api object. And as of now I think this ability is missing, and I must say Im surprised this issue has not been raised before :P

omerman avatar Dec 12 '20 14:12 omerman

@omerman

function Example () {
    let { form, dirty, invalid } = useForm({
        onSubmit () { },
        validate () {
            return { }
        },
        initialValues: {
            username: '',
            password: ''
        }
    })
    
    const username = useField('username', form)
    const password = useField('password', form)
    
    return <>
        <Form.Item label='username' required {...get_field_item(username.meta)}>
            <Input size='l' {...username.input} />
        </Form.Item>
        
        <Form.Item label='password' required {...get_field_item(password.meta)}>
            <Input size='l' {...password.input} />
        </Form.Item>
        
        <button onClick={() => {
            if (dirty || invalid) {
                form.batch(() => {
                    [username, password].forEach( field => {
                        field.input.onFocus()
                        field.input.onBlur()
                    })
                })
                
                return
            }
        }}>validate</button>
    </>
}

function get_field_item ({ touched, error }: { touched?: boolean, error?: any }): {
    status: 'success' | 'error' | 'validating'
    message: React.ReactNode
} {
    if (!touched) return { status: undefined, message: '' }
    if (error) return { status: 'error', message: error }
    return { status: 'success', message: '' }
}

ShenHongFei avatar Aug 25 '21 08:08 ShenHongFei

@ShenHongFei Thank you for the workaround, though I was hoping for a method as part of the api like ->

async myFunc() {
const isFormValid = await form.triggerValidations();
console.log("is form valid?", isFormValid);
}

omerman avatar Aug 25 '21 11:08 omerman

Absolutely! We need the ability to trigger validation manually in FormApi.

const errors = await form.validate()
console.log(errors.username)

ShenHongFei avatar Aug 25 '21 12:08 ShenHongFei

@omerman the validations should happen as you change the field. https://codesandbox.io/s/github/final-form/react-final-form/tree/master/examples/field-level-validation?file=/index.js

gertdreyer avatar Jan 13 '23 14:01 gertdreyer

U can just add a mutator called like validate

const form = createForm({
...
mutators: {
   validate: () => {}
 }
})

and called it when u need

form.mutators.validate()

binjospookie avatar Mar 07 '23 14:03 binjospookie