Quickstart¶
Defining a Form¶
Form constructors are created using Form.extend().
This takes an Object argument defining Form fields and any other properties for the form’s prototype (custom validation functions etc.), returning a Form constructor which inherits from BaseForm():
var ContactForm = forms.Form.extend({
subject: forms.CharField({maxLength: 100})
, message: forms.CharField()
, sender: forms.EmailField()
, ccMyself: forms.BooleanField({required: false})
You can implement custom validation for a field by adding a clean<FieldName>() function to the form’s prototype:
, cleanSender: function() {
if (this.cleanedData.sender == 'mymatesteve@gmail.com') {
throw forms.ValidationError("I know it's you, Steve. " +
"Stop messing with my example form.")
}
}
Custom whole-form validation can be implemented by adding a clean() function to the form’s prototype:
, clean: function() {
if (this.cleanedData.subject &&
this.cleanedData.subject.indexOf('that tenner you owe me') != -1 &&
PEOPLE_I_OWE_A_TENNER_TO.indexOf(this.cleanedData.sender) != 1) {
// This error will be associated with the named field
this.addError('sender', "Your email address doesn't seem to be working.")
// This error will be associated with the form itself, to be
// displayed independently.
throw forms.ValidationError('*BZZZT!* SYSTEM ERROR. Beeepity-boop etc. etc.')
}
}
})
Instantiating a Form¶
For convenience and compactness, the new operator is optional when creating newforms’ Fields, Widgets and other constructors which are commonly used while defining a Form, such as ValidationError() – however new is not automatically optional for Form constructors:
// ...in a React component...
getInitialState: function() {
return {
form: new ContactForm({
validation: 'auto'
, onStateChange: this.forceUpdate.bind(this)
})
}
}
Rendering a Form¶
Forms have default convenience rendering methods to get you started quickly, which display a label, input widgets and any validation errors for each field:
// ...in a React component's render() method...
<form ref="contactForm" onSubmit={this.onSubmit}>
{this.state.form.asDiv()}
<div className="controls">
<input type="submit" value="Submit"/>
</div>
</form>
The API used to implement default rendering is exposed for you to implement your own custom rendering using JSX (if you wish) and React.createElement.
Validating input with a Form¶
When a form is instantiated with the validate option, as above, it will automatically hook its rendered fields up with onChange handlers to validate user input as it’s entered.
To supply a form with a complete set of user input to be validated and cleaned – such as when the user submits a <form> – call setData() on a form instance to bind new data to it, or if you already have the data, pass a data option when instantiating the form.
A convenience wrapper around setData() is provided – validate() – which takes a reference to a <form>, extracts input data from it and sets it on the form, which validates it.
For example, if the form was held as state in a React component which had the above JSX in its render() method:
// ...in a React component...
onSubmit: function(e) {
e.preventDefault()
// A Form's validate() method gets input data from a given <form> and
// validates it.
var isValid = this.state.form.validate(this.refs.contactForm)
// If the data was invalid, the forms's error object will have been
// populated with field validation errors and the form will have called
// its onStateChange callback to update its display.
if (isValid) {
// form.cleanedData contains validated input data, coerced to the
// appropriate JavaScript data types by its Fields.
}
}