Components for rendering a newforms Form using Bootstrap 3 CSS classes and conventions for layout.
- The Form of Death - a
form with a range of validation defined, including async field validation and
whole-form validation, rendered with the
<BootstrapForm>
component. - Grid Components - a
form layout making use of the the Bootstrap grid, with the provided
<Container>
,<Row>
,<Col>
and<Field>
components. - All Default Fields -
a form usiong all the default newforms Fields and Widgets, rendered with the
<BootstrapForm>
component.
newforms-bootstrap can be used on the server, or bundled for the client using an npm-compatible packaging system such as Browserify or webpack.
npm install newforms-bootstrap
By default, newforms-bootstrap will be in development mode. To use it in
production mode, set the environment variable NODE_ENV
to 'production'
when
bundling. To completely remove all development mode code, use a minifier that
performs dead-code elimination, such as
UglifyJS.
The browser bundle exposes a global BootstrapForm
variable and expects to
find global React
(React) and forms
(newforms) variables to work with.
The uncompressed bundle is in development mode, so will log warnings about potential mistakes.
You can find it in the /dist directory.
Pass BootstrapForm
a Form instance as a form
prop.
Any component which accepts a form
prop can be used as a custom renderer for
newforms' RenderForm
component, which can also handle creation of a form
instance for you:
var forms = require('newforms')
var BootstrapForm = require('newforms-bootstrap')
var SignupForm = forms.Form.extend({
username: forms.CharField({maxLength: 20}),
// ...
})
var Signup = React.createClass({
_onSubmit() {
var form = this.refs.signupForm.getForm()
if (form.validate()) {
// ...
}
},
render() {
return <form onSubmit={this._onSubmit}>
<forms.RenderForm form={SignupForm} ref="signupForm">
<BootstrapForm/>
</forms.RenderForm>
<button>Sign Up</button>
</form>
}
})
To render a form as a Bootstrap grid, you can use the provided grid components:
var {Col, Container, Row, Field} = BootstrapForm
<forms.RenderForm form={ProductForm} ref="productForm">
<Container>
<Row>
<Field name="productName" md="8"/>
<Field name="tags" md="4"/>
</Row>
<Row>
<Field name="vendor" md="6"/>
<Field name="productType" md="6"/>
</Row>
<Row>
<Field name="productDescription" md="12"/>
</Row>
<Row>
<Col md="2">
I'm just a regular column.
</Col>
<Field name="sku" md="2"/>
<Field name="initialStockLevel" md="2"/>
<Field name="costPrice" md="2"/>
<Field name="wholesalePrice" md="2"/>
<Field name="retailPrice" md="2"/>
</Row>
</Container>
</forms.RenderForm>
To automatically split the 12 available Bootstrap grid units among columns, pass
an autoColumns
prop to a Container
or Row
component. For example, the
following rows would render identically:
<Row>
<Field name="vendor" md="6"/>
<Field name="productType" md="6"/>
</Row>
<Row autoColumns="md">
<Field name="vendor"/>
<Field name="productType"/>
</Row>
This takes into account any column widths and offsets which have been provided for the specified size unit, so this grid layout would render identically to the first grid layout example above:
<forms.RenderForm form={ProductForm} ref="productForm">
<Container autoColumns="md">
<Row>
<Field name="productName" md="8"/>
<Field name="tags"/>
</Row>
<Row>
<Field name="vendor"/>
<Field name="productType"/>
</Row>
<Row>
<Field name="productDescription"/>
</Row>
<Row>
<Col>
I'm just a regular column.
</Col>
<Field name="sku"/>
<Field name="initialStockLevel"/>
<Field name="costPrice"/>
<Field name="wholesalePrice"/>
<Field name="retailPrice"/>
</Row>
</Container>
</forms.RenderForm>
-
form
- aForm
instance. -
spinner
- the URL or data URI for an image to be displayed when async validation is pending for a field or the whole form.This defaults to a data URI for a 14x14 circular grey spinner with a transparent background:
-
static
- set totrue
to render fields using a static display control:<p className="form-control-static">{value}</p>
This is useful if you want to have readonly forms, and switch to editable given a flag:
<BootstrapForm static={!this.props.editable} />
Provide a
widgetAttrs.convertStatic
function on a field to convert the value when displaying statically. The following would render a cost value with a dollar sign in front whenstatic=true
, but would otherwise just render an integer field:var ProductForm = forms.Form.extend({ cost: forms.IntegerField({ widgetAttrs: { convertStatic: (value) => '$' + value } }) })
-
horizontal
- An object for specifyingform-horizontal
classes. Keys are one of the bootstrap sizes (xs, sm, md, lg), and values are the number given to the form control.So for example:
<BootstrapForm horizontal={{sm: 10}}/>
This would produce fields such as:
<div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">Password</label> <div class="col-sm-10"> <input type="password" class="form-control" id="inputPassword3" placeholder="Password"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <div class="checkbox"> <label> <input type="checkbox"> Remember me </label> </div> </div> </div>
The following custom renderers are available for use. Note that the non-inline renderers will be automatically applied for you if you're using certain combinations of default fields and widgets.
BootstrapForm.CheckboxRenderer
- renders choices as a list of checkboxes; supports choice categories.BootstrapForm.CheckboxInlineRenderer
- renders flat choices as inline checkboxesBootstrapForm.RadioRenderer
- renders choices as a list of radio buttons; supports choice categoriesBootstrapForm.RadioInlineRenderer
- renders flat choices as inline radio buttons
Use the inline renderers manually if you want to configure fields to render
inline checkbox or radio inputs using Bootstrap 3's checkbox-inline
and
radio-inline
classes, respectively:
var StuffForm = forms.Form.extend({
stuff: forms.MultipleChoiceField({
choices: [1, 2, 3, 4, 5],
widget: forms.CheckboxSelectMultiple({renderer: BootstrapForm.CheckboxInlineRenderer})
})
})
Renders a .container
or .container-fluid
.
-
form
:Form
- theForm
instance to be rendered. Will be passed as a prop to all children. -
autoColumns
:String
- a Bootstrap grid size unit (xs
,sm
,md
orlg
). If provided, will be passed to all children. -
fluid
:Boolean
(default:false
) - iftrue
, the container will have the.container-fluid
class, otherwise it will be a.container
-
className
:String
- an additional class for the container element. -
spinner
:String
- as perBootstrapForm
, see above.
Renders a .row
.
These should be nested directly under Container
components.
-
form
:Form
- theForm
instance to be rendered. Will be passed as a prop to all children. -
autoColumns
:String
- a Bootstrap grid size unit (xs
,sm
,md
orlg
).If provided, the Row will ensure that all its children have a column width set for the specified size. If any of them do not, the number of available column units left (out of the 12 unit available in Bootstrap's grid system) after considering any widths and offsets which have been provided for the unit provided will be distibuted equally among children which need a width set.
If the remaining units cannot be split equally among the children, the initial children in the row will have the leftover units divided amongst them.
-
className
:String
- an additional class for the container element.
Renders a column containing a named form field.
These should be nested directly under Row
components.
Field
is a specialisation of Col
, so it accepts all the sizing/offset props
described below plus the following:
-
form
:Form
- theForm
instance to be rendered. -
name
:String
- the name of the field to be rendered.
Renders a column, with contents manually provided as its children.
Note that Field
components generates their own column container, you do not
need to and should not wrap a Field
with a Col
Column sizing props can be passed as a String
or Number
.
At least one of the following sizing props must be give to define the column's width:
xs
sm
md
lg
Additionally, the column's offset can be specified with the following props:
-
xsOffset
-
smOffset
-
mdOffset
-
lgOffset
-
className
:String
- an additional class for the column element.
BootstrapForm
and Container
will automatically patch the widgets of certain
fields for Bootstrap-compatible output.
These changes will be made the first time they renders a form - patching will only affect the form instance it was given.
If the widget is using the default renderer, it will be replaced with
BootstrapForm.RadioRenderer
.
If the widget is using the default renderer, it will be replaced with
BootstrapForm.CheckboxRenderer
.
If the field has fewer than 5 sub-fields and its widget is using the default
implementation of MultiWidget.prototype.formatOutput()
, the widget will be
given a Bootstrap-specific version of formatOutput()
which wraps the rendered
widgets as equally-distributed columns in a Bootstrap grid row.
BootstrapForm
configuration- Make use of
has-error
/has-success
highlighting configurable - Horizontal layout with configuratble breakpoints
- Make use of