Let's have a look of what using your themes and writing some actual forms looks like.
When writing your form you need to decide whether your form should be controlled or uncontrolled. I.e do you need to keep track of all the form changes via onFieldChange
and inform the form via a changed model
? Or is it sufficient to maybe provide an initialModel
and only get to know the field values in the onSubmit
handler?
In most cases the less complex uncontrolled forms will be fine. But sometimes you need to be aware of the field values to change the render output accordingly. This is when controlled forms come in handy.
import React from 'react'
import {Form, ReformContext} from 'react-reform'
import defaultValidations from 'react-reform/opt/validations'
import {Text} from 'react-reform/opt/inputs'
import defaultTheme from '../default-theme'
export default class ExampleForm extends React.Component {
handleSubmit = (data) => {
console.log('data', data)
}
render() {
return (
<ReformContext themes={{default: defaultTheme}} validations={defaultValidations}>
<div>
<h4>Form</h4>
<Form onSubmit={this.handleSubmit}>
<Text name="firstName" label="First Name" isRequired/>
</Form>
</div>
</ReformContext>
)
}
}
import React from 'react'
import {Form, ReformContext} from 'react-reform'
import defaultValidations from 'react-reform/opt/validations'
import {Text} from 'react-reform/opt/inputs'
import defaultTheme from '../default-theme'
export default class ExampleForm extends React.Component {
state = {
model: {firstName: null}
}
handleSubmit = (data) => {
console.log('data', data)
}
handleFieldChange = (fieldName, value) => {
this.setState({model: {...this.state.model, [fieldName]: value}})
}
render() {
const {model} = this.state
return (
<ReformContext themes={{default: defaultTheme}} validations={defaultValidations}>
<div>
<h4>Hello {model.firstName || 'there'}!</h4>
<Form model={model}
onFieldChange={this.handleFieldChange}
onSubmit={this.handleSubmit}
>
<Text name="firstName" label="First Name" isRequired/>
</Form>
</div>
</ReformContext>
)
}
}
theme: (string|themeObj)
Defaults to 'default'
. You may either pass a string referencing a theme name that you defined via ReformContext or you may pass a theme object created via createTheme
.
onSubmit: fn(data, event) => (Promise?)
The onSubmit
handler will be called once the form was submitted and all fields' validations returned true
.
The data is an object with the fields' name
s as keys and their values as the value.
You may return a promise to indicate to the theme that there's no result yet. The status
within the renderFormFn
will be 'pending'
.
If the promise gets resolved the form gets reset and a 'success'
status will be set.
You may also reject the promise. You have two options. If you know the field(s) that led to the error you may reject like this: reject({fieldName: 'is not unique'})
. If the error is more generic, reject with a string or react element: reject(<span>the server responded with a <b>{code}</b> message</span>)
initialModel
(optional) uncontrolled forms only.You may pass in initial data in the form of an object mapping field name to values. These values will be used when the form is mounted or reset.
model
controlled forms only.Passing a model prop signals to the form that it's an controlled form. It expects an object mapping field name to values. Field values won't be changed unless you explicitely change the model
.
onFieldChange: fn(fieldName, value)
controlled forms only.This handler allows you to react to fieldChange request. Most typically it looks like the one form the controlled form example above.
You may return false
to indicate that no change has happened. This will prevent the input from becoming isDirty
.
children
Pass your inputs here. It's perfectly fine to pass in non-inputs here as well. So a form like this will work:
<Form onSubmit={this.handleSubmit} theme="dark">
<Text name="name" isRequired/>
<hr/>
<button type="button" onClick={this.toggleSpecial}>
toggle special
</button>
{this.state.showSpecial && (
<div className="special">
<Text name="price" isRequired/>
</div>
)}
</Form>
You may attach a ref
prop to the form. This ref officially supports some methods you might want to take advantage of.
reset()
Sets the form inputs to an untouched state.
checkForErrors() => ({hasErrors, firstInvalidFieldName})
In case you'd like to validate the form without submitting it. Call this method. You can use the firstInvalidFieldName
to focus the relevant input (see below).
focusField(fieldName)
Calls focuses the input by executing the focusFn(node)
method according to it's definition on the WrapInput
component.