reactive-form-creator
v0.0.9
Published
Form generator for react
Downloads
11
Maintainers
Readme
HOC that gives you ability easily generate fully interactive forms
it helps not only with date management, but also create view of your form.
import React from 'react';
import ReactiveFormCreator from 'reactive-form-creator'; // import librarry
/** import needed components **/
import { FormControl } from 'react-bootstrap';
import Select from 'material-ui/Select';
import { MenuItem } from 'material-ui/Menu';
import Input from '../components/Input';
/**
create wrapper for your components to be use it
key is the name of your component
**/
const ReactiveFormInstance = ReactiveFormCreator({
email: ({onChange, ...rest}) => (
<FormControl
type="email"
onChange={(event) => onChange(event.value)} // onChange should always get new value that will be set to this component
{...rest}
/>
),
password: (props) => (
<Input {...props} type="password" />
),
select: ({value, options, onChange,...rest}) => (
<Select
value={value || ''} // you can specify some default value
onChange={(event) => onChange(event.target.value)}
{...rest}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
{options.map(({ value, label }) => ( // props can be renamed or modified the way you need it in component
<MenuItem value={value}>
{label}
</MenuItem>
))}
</Select>
),
});
/**
Defining the form
**/
const ReactiveForm = ({
onSubmit,
clearForm,
onChange,
value,
getCountries,
getCities,
loading,
startLoading,
finishLoading,
}) => (
<div
style={{
position: 'relative',
}}
>
<div
style={loading ? {
position: 'absolute',
background: 'rgba(255, 255, 255, 0.8)',
textAlign: 'center',
width: '100%',
height: '100%'
} : {}}
>
{loading && 'loading'}
</div>
<form onSubmit={onSubmit}>
<ReactiveFormInstance
fields={[{
name: 'login', // name of the component is a key of return value that we will have
type: 'email', // type will be mapped to <FormControl type="email" that was described earlier
ownProps: { // ownProps is props that will be dirrectly placed to mapped component
required: true,
},
}, {
name: 'password',
type: 'password',
ownProps: {
required: true,
minLength: 6,
}
}, {
name: 'country',
type: 'select',
dynamicFiels: { // sometimes you don't have all data for you form element and you need to load them
query: getCountries, // is the function that returns promise with the value that after adapter function will be set to property name that is declared in dependentFields.name. So after query resolves to options of will be equal result of query with adapter
dependentFields: [{
name: 'ownProps.options',
adapter: val => val ? val : [],
}]
},
ownProps: {
required: true,
options: [],
},
}, {
name: 'city',
type: 'select',
dynamicFiels: {
influenceFields: [{
name: 'country',
required: true, // this mean that query won't be run if fiend with name country is empty
adapter: val => val, // function that will be runned with value of country field
}],
query: getCities,
dependentFields: [{
name: 'ownProps.options',
adapter: val => val ? val : [],
}]
},
ownProps: {
options: [],
required: true,
},
}]}
onStartLoading={(promise) => { // here we can add function that will be fired when form will start loading some dynamic props
startLoading()
promise.then(() => {
finishLoading()
}).catch(() => {
finishLoading();
})
}}
onChange={onChange} // function that will be runned each time when some property changes
value={value} // value is an object where each key is name of field and value is a value of that field
/>
<button type="submit">login</button>
<button type="reset" onClick={clearForm}>reset</button>
</form>
</div>
);