- Installation
- Description
- Demo
- Tests
- Form props
- Fields
- FormEventsListener
- How to use
- Separate fields
- Bootstrap fields
$ npm install react --save
$ npm install form-schema-validation --save
$ npm install react-components-form --save
React components form give you posibility to create forms with schema validation using "form-schema-validation". You can easy create any form with any inputs and create Your own custom fields and validators. Also You can create object fields that represents some object data. Please read another sections of this readme to check what You can use in your project.
Live demo: https://mprzodala.github.io/react-components-form/
Localhost demo: You can run demo by clone repository and run webpack-dev-server:
$ git clone https://github.com/mprzodala/react-components-form.git
$ cd react-components-form
$ npm install
$ npm run start
Now go to http://localhost:8080 in your browser.
If You want run tests. Please clone this project repository
$ git clone https://github.com/mprzodala/react-components-form.git
Go to project directory
$ cd react-components-form
Install node module
$ npm install
Run "Jest" tests
$ npm run test
Props name | Type |
---|---|
schema | Instance of Schema from "form-schema-validation" |
model | Object |
onSubmit | Function(model) |
onError | Function(errors, model) |
validateOnChange | Boolean |
customValidation | Function(model) { return errors} |
eventsListener | Instance of FormEventsListener |
className | String |
subform | Boolean |
You can use current fields or create new fields. Here You have list of fields.
Field name | Description |
---|---|
TextField | This field is normal input that return string value |
TextareaField | This field is normal textarea that return string value |
SelectField | This field is normal select that return string value |
SubmitField | This field create submit form button |
NumberField | This field is normal input with type number and return Integer |
DateField | This field is normal input with type date and return Date Object |
CheckboxField | This field is normal checkbox that return Boolean |
ObjectField | This field give You posibility to wrap another fields to object |
ListField | This field give You posibility to create list of fields with add and remove buttons |
AutocompleteField | You can use this field by import them from 'react-components-form/AutocompleteField' |
Props name | Type |
---|---|
name | String |
type | String |
value | String, Number, Object, Date, [String], [Number], [Object], [Date] |
label | String, Node |
placeholder | String |
options | [String], [{label: String, value: String}] |
defaultOption | Number |
className | String |
wrapperClassName | String |
errorStyles | {className, itemClassName, fieldClassName, ErrorComponent} |
onChangeModel | Function(data: { name: String, value: Any }, componentInstance: FieldComponentInstance) |
onEmitEvents | Function(data, componentInstance: FieldComponentInstance) or array of functions |
fieldAttributes | Object with html attributes for input |
eventsListener (from context) | Instance of FormEventsListener (prop avaible if you have eventListener in form) |
path (from context) | String (this prop give you path to field "form.someObjectField.thisField") |
callbacks | Object ({ onError: Function, onChange: Function, onBlur: Function, onFocus: Function }) |
trim (TextField) | boolean (trims values passed to onChange if set) |
minLength (ListField) | Number (number of minimal amount of listField elements) |
maxLength (ListField) | Number (number of maximal amount of listField elements) |
hideAddButton (ListField) | Boolean (you can hide add button) |
hideRemoveButton (ListField) | Boolean (you can hide remove buttons) |
addButton (ListField) | Object ({ className: String, value: Node}) |
removeButton (ListField) | Object ({ className: String, value: Node}) |
You can submit your form outside form context by use FormEventsListener. Form register submit and validate events if have eventsListener in props. When form have eventListener on all fields you can use onChangeModel method by props on field or use eventsListener on Your custom field to change state of field etc.
Method name | Arguments |
---|---|
registerEvent | name: String |
registerEventListener | name: String method: Function(data: Any) |
unregisterEvent | name: String |
unregisterEventListener | name: String, handler: Instance of registred function |
callEvent | name: String data: Any |
- changeModel
- submit
- validate
- reset
If You want create Your own custom field You must create component that use onChange method from props when value is changed and on export use FieldConnect method. FieldConnect will wrap Your field component and give props from form to Your field. Abow You have example of custom text field that have icon.
import React from 'react';
import { FieldConnect, ErrorField } from 'react-components-form';
const CustomTextField = ({
wrapperClassName,
className,
onChange,
name,
errors,
error,
value,
label,
placeholder,
errorStyles = {}
fieldAttributes = {}
}) => (
<div className={wrapperClassName}>
{label && <label>{label}</label>}
<input
type="text"
name={name}
onChange={(e) => onChange(e.target.value)}
value={value}
placeholder={placeholder}
className={className}
{...fieldAttributes}
/>
<icon className="some-icon-class" />
{error && <ErrorField errors={errors} {...errorStyles} />}
</div>
);
export default FieldConnect(CustomTextField);
You can define any form. Abow You have example of login and registration form.
import React from 'react';
import { Form, TextField, SubmitField } from 'react-components-form';
import Schema from 'form-schema-validation';
const loginSchema = new Schema({
login:{
type: String,
required: true
},
password: {
type: String,
required: true
}
});
const LoginForm = () => (
<Form
schema={loginSchema}
onSubmit={data => console.log(data)}
onError={(errors, data) => console.log('error', errors, data)}
>
<TextField name="login" label="Login" type="text" />
<TextField name="password" label="Login" type="text" />
<SubmitField value="Submit" />
</Form>
);
export default LoginForm;
import React from 'react';
import { Form, TextField, SubmitField } from 'react-components-form';
import Schema from 'form-schema-validation';
const loginSchema = new Schema({
login:{
type: String,
required: true
},
password: {
type: String,
required: true
}
});
const model = {
login: 'TestLogin',
password: '1234'
};
const LoginForm = () => (
<Form
schema={loginSchema}
model={model}
onSubmit={data => console.log(data)}
onError={(errors, data) => console.log('error', errors, data)}
>
<TextField name="login" label="Login" type="text" />
<TextField name="password" label="Login" type="text" />
<SubmitField value="Submit" />
</Form>
);
export default LoginForm;
import React from 'react';
import { Form, FormEventsListener, TextField, SubmitField } from 'react-components-form';
import Schema from 'form-schema-validation';
const loginSchema = new Schema({
login:{
type: String,
required: true
},
password: {
type: String,
required: true
}
});
const LoginForm = () => {
const eventsListener = new FormEventsListener();
return (
<div>
<Form
schema={loginSchema}
onSubmit={data => console.log(data)}
onError={(errors, data) => console.log('error', errors, data)}
eventsListener={eventsListener}
>
<TextField name="login" label="Login" type="text" />
<TextField name="password" onChangeModel={({ name, value }) => { console.log(name, value) }} label="Login" type="text" />
</Form>
<button onClick={() => eventsListener.callEvent('submit')}>Outside form submit button</button>
</div>
);
};
export default LoginForm;
import React from 'react';
import Schema from 'form-schema-validation';
import { Form, TextField, CheckboxField, SubmitField } from 'react-components-form';
const emailValidator = () => ({
validator(value){
const regex = /^[a-zA-Z0-9\.]+@[a-zA-Z0-9]+(\-)?[a-zA-Z0-9]+(\.)?[a-zA-Z0-9]{0,6}?\.[a-zA-Z]{2,6}$/;
if (!value.match(regex)) {
return false;
}
return true;
},
errorMessage: 'Inserted value is not a email adress'
});
const sameValueAs = (fieldName) => ({
validator(value, type, model){
return value === model[fieldName];
},
errorMessage: 'Reapeted password is incorrect'
});
const registrationSchema = new Schema({
name:{
type: String,
required: true
},
email:{
type: String,
required: true,
validators: [emailValidator()]
},
phone:{
type: String
},
password: {
type: String,
required: true
},
password2: {
type: String,
required: true,
validators: [sameValueAs('password')]
},
termsAccepted: {
type: Boolean,
required: true,
}
});
const RegistrationForm = () => (
<Form
schema={registrationSchema}
onSubmit={data => console.log(data)}
onError={(errors, data) => console.log('error', errors, data)}
>
<h4>REGISTRATION FORM</h4>
<TextField name="name" label="Name" type="text" />
<TextField name="email" label="Email" type="text" />
<TextField name="phone" label="Phone" type="text" />
<TextField name="password" label="Password" type="password" />
<TextField name="password2" label="Repeate password" type="password" />
<CheckboxField name="termsAccepted" label="Accept terms" />
<SubmitField value="Register" />
</Form>
);
export default RegistrationForm;
import React from 'react';
import { Form, SelectField, SubmitField } from 'react-components-form';
import Schema from 'form-schema-validation';
const countrySchema = new Schema({
country: {
type: String,
required: true,
}
});
const countrys = [
{label:'Poland', value:'PL'},
{label:'Germany', value:'DE'},
{label:'England', value:'EN'}
];
const CompanyForm = () => (
<Form
schema={countrySchema}
onSubmit={data => console.log(data)}
onError={(errors, data) => console.log('error', errors, data)}
>
<SelectField name="country" options={countrys} label="Country" />
<SubmitField value="Submit" />
</Form>
);
export default CompanyForm;
You can group fields as object by using ObjectField component.
import React from 'react';
import { Form, TextField, ObjectField, SubmitField } from 'react-components-form';
import Schema from 'form-schema-validation';
const ownerSchema = new Schema({
name: {
type: String,
required: true,
},
surname: {
type: String
}
});
const companySchema = new Schema({
title:{
type: String,
required: true
},
owner: {
type: ownerSchema,
required: true
}
});
const CompanyForm = () => (
<Form
schema={companySchema}
onSubmit={data => console.log(data)}
onError={(errors, data) => console.log('error', errors, data)}
>
<TextField name="title" label="Company title" />
<ObjectField name="owner" label="Company owner">
<TextField name="name" label="Name" />
<TextField name="surname" label="Surname" />
</ObjectField>
<SubmitField value="Submit" />
</Form>
);
export default CompanyForm;
You can use ListField to create list of fields or groups of fields
import React from 'react';
import { Form, TextField, ListField, SubmitField } from 'react-components-form';
import Schema from 'form-schema-validation';
const memberSchema = new Schema({
name: {
type: String,
required: true,
},
surname: {
type: String
},
languages: {
type: [String]
}
});
const MemberForm = () => (
<Form
schema={memberSchema}
onSubmit={data => console.log(data)}
onError={(errors, data) => console.log('error', errors, data)}
>
<TextField name="name" label="Name" />
<TextField name="surname" label="Surname" />
<ListField name="languages" label="Languages">
<TextField placeholder="language" />
</ListField>
<SubmitField value="Submit" />
</Form>
);
export default MemberForm;
You can restyle all fields by FieldRestyle method
import {
fieldsRestyle
TextField as TextFieldUnstyled,
DateField as DateFieldUnstyled,
TextareaField as TextareaFieldUnstyled,
NumberField as NumberFieldUnstyled,
SubmitField as SubmitFieldUnstyled,
SelectField as SelectFieldUnstyled,
CheckboxField as CheckboxFieldUnstyled,
ListField as ListFieldUnstyled
} from 'react-components-form';
const errorStyles = {
className: 'alert alert-danger'
};
const Fields = fieldRestyle({
TextFieldUnstyled: {
className: 'form-control',
wrapperClassName: 'form-group',
errorStyles
},
DateFieldUnstyled: {
className: 'form-control',
wrapperClassName: 'form-group',
errorStyles
},
TextareaFieldUnstyled: {
className: 'form-control',
wrapperClassName: 'form-group',
errorStyles
},
NumberFieldUnstyled: {
className: 'form-control',
wrapperClassName: 'form-group',
errorStyles
},
SubmitFieldUnstyled: {
wrapperClassName: 'clearfix',
className: 'btn btn-primary pull-right',
errorStyles
},
SelectFieldUnstyled: {
className: 'form-control',
wrapperClassName: 'form-group',
errorStyles
},
CheckboxFieldUnstyled: {
wrapperClassName: 'form-group checkbox',
errorStyles
},
ListFieldUnstyled: {
className: 'form-group',
wrapperClassName: 'form-group',
itemWrapperClassName: 'form-group clearfix',
errorStyles,
addButton: {
className: 'btn btn-success btn-sm'
},
removeButton: {
className: 'btn btn-danger btn-xs pull-right'
}
}
}, {
TextFieldUnstyled,
DateFieldUnstyled,
TextareaFieldUnstyled,
NumberFieldUnstyled,
SubmitFieldUnstyled,
SelectFieldUnstyled,
CheckboxFieldUnstyled,
ObjectFieldUnstyled,
ListFieldUnstyled
});
export const TextField = Fields.TextFieldUnstyled;
export const DateField = Fields.DateFieldUnstyled;
export const TextareaField = Fields.TextareaFieldUnstyled;
export const NumberField = Fields.NumberFieldUnstyled;
export const SubmitField = Fields.SubmitFieldUnstyled;
export const SelectField = Fields.SelectFieldUnstyled;
export const CheckboxField = Fields.CheckboxFieldUnstyled;
export const ListField = Fields.ListFieldUnstyled;
export default Fields;
You can use fields without Form context by import it from "react-components-form/Separate"
import { TextField } from 'react-components-form/Separate';
const exampleSearchComponent = ({onSearch}) => (
<div>
<TextField onChange={onSearch} />
</div>
);
export default exampleSearchComponent;
You can use fields with Bootstrap theme by import it from "react-components-form/Bootstrap"
import React from 'react';
import { Form, TextField, SubmitField } from 'react-components-form/Bootstrap';
import Schema from 'form-schema-validation';
const loginSchema = new Schema({
login:{
type: String,
required: true
},
password: {
type: String,
required: true
}
});
const model = {
login: 'TestLogin',
password: '1234'
};
const LoginForm = () => (
<Form
schema={loginSchema}
model={model}
onSubmit={data => console.log(data)}
onError={(errors, data) => console.log('error', errors, data)}
>
<TextField name="login" label="Login" type="text" />
<TextField name="password" label="Login" type="text" />
<SubmitField value="Submit" />
</Form>
);
export default LoginForm;