const MyField = (props) => {
const {
errorMessage,
id,
isValid,
isPristine,
isSubmitted,
resetKey,
setValue,
value,
} = useField(props)
const { label, type, required } = props
const [isFocused, setIsFocused] = React.useState(false);
const showError = !isValid && !isFocused && (!isPristine || isSubmitted)
return (
<div className={`demo-form-group ${showError ? 'is-error' : ''}`}>
<label
className="demo-label"
htmlFor={id}
>
{ label }
{required && ' *'}
</label>
<input
key={resetKey}
id={id}
type={type || 'text'}
value={value || ''}
className="demo-input"
onChange={e => setValue(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
aria-invalid={!isValid}
aria-describedby={!isValid ? `${id}-error` : null}
/>
{showError && (
<div id={`${id}-error`} className="demo-form-feedback">
{ errorMessage }
</div>
)}
</div>
)
}
const MyForm = () => {
const myForm = useForm()
const [isLoading, setIsLoading] = React.useState(false)
const submitForm = (values) => {
setIsLoading(true)
setTimeout(() => {
setIsLoading(false)
alert(JSON.stringify(values))
myForm.invalidateFields({
email: 'You can display an error after an API call',
})
const step = myForm.getFieldStepName('email')
myForm.goToStep(step)
}, 1000)
}
return (
<Formiz onValidSubmit={submitForm} connect={myForm}>
<form
noValidate
onSubmit={myForm.submitStep}
className="demo-form"
style={{ minHeight: '16rem' }}
>
<div className="demo-form__content">
<FormizStep name="step1">
<MyField
name="name"
label="Name"
required="Name is required"
/>
<MyField
name="nickname"
label="Nickname"
/>
</FormizStep>
<FormizStep name="step2">
<MyField
name="email"
label="Email"
type="email"
required="Email is required"
validations={[
{
rule: validations.isEmail(),
message: 'Not a valid email',
}
]}
/>
</FormizStep>
<FormizStep name="step3">
<MyField
name="password"
label="Password"
type="password"
/>
<MyField
name="passwordConfirm"
label="Confirm password"
type="password"
validations={[
{
rule: (value) => myForm.values.password === value,
deps: [myForm.values.password],
message: 'Passwords do not match',
}
]}
/>
</FormizStep>
</div>
<div className="demo-form__footer">
<div className="mr-auto" style={{ minWidth: '6rem' }}>
{!myForm.isFirstStep && (
<button
className="demo-button is-full"
type="button"
onClick={myForm.prevStep}
>
Previous
</button>
)}
</div>
<div className="text-sm text-gray-500 p-2 text-center w-full xs:w-auto order-first xs:order-none">
Step
{' '}
{myForm.currentStep && myForm.currentStep.index + 1 || 0}
{' '}
of
{' '}
{myForm.steps.length}
</div>
<div
className="ml-auto"
style={{ minWidth: '6rem' }}
>
{myForm.isLastStep ? (
<button
className="demo-button is-full is-primary"
type="submit"
disabled={isLoading || (!myForm.isValid && myForm.isStepSubmitted)}
>
{isLoading ? 'Loading...' : 'Submit'}
</button>
) : (
<button
className="demo-button is-full is-primary"
type="submit"
disabled={!myForm.isStepValid && myForm.isStepSubmitted}
>
Next
</button>
)}
</div>
</div>
</form>
</Formiz>
)
}
render(
<MyForm />
)