Created
December 2, 2022 06:32
-
-
Save mununki/1e9cecfcdf9d52b22aafd517b7b33df5 to your computer and use it in GitHub Desktop.
ReForm field array validation example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ProfileFormFields = %lenses( | |
type t = { | |
nickname: string, | |
age: int, | |
} | |
) | |
module FormFields = %lenses( | |
type state = { | |
name: string, | |
email: string, | |
profiles: array<ProfileFormFields.t>, | |
} | |
) | |
module Form = ReForm.Make(FormFields) | |
module ReFormPresenter = { | |
@react.component | |
let make = () => { | |
let handleSubmit = ({state}: Form.onSubmitAPI) => { | |
Js.log2("submit >", state.values) | |
None | |
} | |
let form = Form.use( | |
~initialState={name: "", email: "", profiles: [{nickname: "", age: 0}]}, | |
~onSubmit=handleSubmit, | |
~validationStrategy=OnDemand, | |
~schema={ | |
open Form.Validation | |
schema([string(~min=3, Name), custom(({profiles}) => { | |
let errors: array<ReSchema.childFieldError> = | |
profiles | |
->Array.mapWithIndex((index, profile) => | |
if profile.nickname == "" || profile.age <= 0 { | |
let error: ReSchema.childFieldError = { | |
error: "Invalid profile", | |
index, | |
name: "???", | |
} | |
Some(error) | |
} else { | |
None | |
} | |
) | |
->Array.keepMap(x => x) | |
switch errors { | |
| [] => Valid | |
| _ => NestedErrors(errors) | |
} | |
}, Profiles), email(~error="Invalid email", Email)]) | |
}, | |
(), | |
) | |
<div> | |
<div> | |
<div> {"Sign up"->React.string} </div> | |
<div> | |
<input | |
placeholder="Your name" | |
value={form.values.name} | |
onChange={ReForm.Helpers.handleChange(form.handleChange(Name))} | |
/> | |
{switch Field(Name)->form.getFieldError { | |
| None => React.null | |
| Some(message) => <div> {message->React.string} </div> | |
}} | |
</div> | |
<div> | |
<input | |
placeholder="Your email" | |
value={form.values.email} | |
onChange={ReForm.Helpers.handleChange(form.handleChange(Email))} | |
/> | |
{switch Field(Email)->form.getFieldError { | |
| None => React.null | |
| Some(message) => <div> {message->React.string} </div> | |
}} | |
</div> | |
<button onClick={_ => form.arrayPush(Profiles, {nickname: "", age: 0})}> | |
{React.string("Add profile")} | |
</button> | |
{form.values.profiles | |
->Array.mapWithIndex((index, profile) => | |
<div key={index->Int.toString} className=%twc("flex flex-row")> | |
<input | |
placeholder={"Your nickname"} | |
value={profile.nickname} | |
onChange={ReForm.Helpers.handleChange(nickname => | |
form.arrayUpdateByIndex(~field=Profiles, ~index, {...profile, nickname}) | |
)} | |
/> | |
{switch Field(Profiles)->form.getNestedFieldError(index) { | |
| None => React.null | |
| Some(message) => <div> {message->React.string} </div> | |
}} | |
<input | |
placeholder={`Your age`} | |
value={profile.age->Int.toString} | |
onChange={ReForm.Helpers.handleChange(age => { | |
let age = Int.fromString(age)->Belt.Option.getWithDefault(0) | |
form.arrayUpdateByIndex(~field=Profiles, ~index, {...profile, age}) | |
})} | |
/> | |
{switch Field(Profiles)->form.getNestedFieldError(index) { | |
| None => React.null | |
| Some(message) => <div> {message->React.string} </div> | |
}} | |
<button onClick={_ => form.arrayRemoveByIndex(Profiles, index)}> | |
{React.string("Remove")} | |
</button> | |
</div> | |
) | |
->React.array} | |
<div> | |
<button | |
onClick={e => { | |
e->ReactEvent.Mouse.preventDefault | |
form.submit() | |
}}> | |
{"Submit"->React.string} | |
</button> | |
</div> | |
</div> | |
</div> | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment