First version of stateless form
parent
b190ecc857
commit
9de67a44bf
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import style from './style';
|
import ReactDOM from 'react-dom';
|
||||||
import Autocomplete from '../autocomplete';
|
import Autocomplete from '../autocomplete';
|
||||||
import Button from '../button';
|
import Button from '../button';
|
||||||
import Checkbox from '../checkbox';
|
import Checkbox from '../checkbox';
|
||||||
|
@ -10,12 +10,27 @@ import RadioGroup from '../radio/RadioGroup';
|
||||||
import Slider from '../slider';
|
import Slider from '../slider';
|
||||||
import Switch from '../switch';
|
import Switch from '../switch';
|
||||||
import TimePicker from '../time_picker';
|
import TimePicker from '../time_picker';
|
||||||
|
import style from './style';
|
||||||
|
|
||||||
|
const Component = {
|
||||||
|
'autocomplete': Autocomplete,
|
||||||
|
'button': Button,
|
||||||
|
'checkbox': Checkbox,
|
||||||
|
'datepicker': DatePicker,
|
||||||
|
'dropdown': Dropdown,
|
||||||
|
'input': Input,
|
||||||
|
'radioGroup': RadioGroup,
|
||||||
|
'slider': Slider,
|
||||||
|
'switch': Switch,
|
||||||
|
'timepicker': TimePicker
|
||||||
|
};
|
||||||
|
|
||||||
class Form extends React.Component {
|
class Form extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
attributes: React.PropTypes.array,
|
attributes: React.PropTypes.array,
|
||||||
children: React.PropTypes.node,
|
children: React.PropTypes.node,
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
|
model: React.PropTypes.object,
|
||||||
onChange: React.PropTypes.func,
|
onChange: React.PropTypes.func,
|
||||||
onError: React.PropTypes.func,
|
onError: React.PropTypes.func,
|
||||||
onSubmit: React.PropTypes.func,
|
onSubmit: React.PropTypes.func,
|
||||||
|
@ -28,135 +43,32 @@ class Form extends React.Component {
|
||||||
className: ''
|
className: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
|
||||||
attributes: this.storage(this.props)
|
|
||||||
};
|
|
||||||
|
|
||||||
componentWillReceiveProps (next_props) {
|
|
||||||
if (next_props.attributes) {
|
|
||||||
const attributes = this.storage(next_props);
|
|
||||||
this.setState({attributes});
|
|
||||||
this.setValue(attributes.map((item) => { return item; }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit = (event) => {
|
onSubmit = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (this.props.onSubmit) {
|
if (this.props.onSubmit) this.props.onSubmit(event);
|
||||||
this.props.onSubmit(event, this);
|
};
|
||||||
|
|
||||||
|
onChange = (field, event) => {
|
||||||
|
if (this.props.onChange) {
|
||||||
|
const value = event.target.value;
|
||||||
|
this.props.onChange(field, value, event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onChange = (event) => {
|
renderFields () {
|
||||||
let is_valid = true;
|
return Object.keys(this.props.model).map((field, index) => {
|
||||||
const value = this.getValue();
|
const properties = this.props.model[field];
|
||||||
for (const attr of this.state.attributes) {
|
const Field = Component[properties.kind.toLowerCase()];
|
||||||
if (attr.required && value[attr.ref] !== undefined && value[attr.ref].trim() === '') {
|
return <Field key={index} {...properties} onChange={this.onChange.bind(this, field)} />
|
||||||
is_valid = false;
|
});
|
||||||
if (this.refs[attr.ref].setError) this.refs[attr.ref].setError('Requited field');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.onChange) this.props.onChange(event, this);
|
|
||||||
if (this.props.storage) this.storage(this.props, value);
|
|
||||||
|
|
||||||
if (is_valid) {
|
|
||||||
if (this.refs.submit) this.refs.submit.getDOMNode().removeAttribute('disabled');
|
|
||||||
if (this.props.onValid) this.props.onValid(event, this);
|
|
||||||
} else {
|
|
||||||
if (this.refs.submit) this.refs.submit.getDOMNode().setAttribute('disabled', true);
|
|
||||||
if (this.props.onError) this.props.onError(event, this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
storage (props, value) {
|
|
||||||
const key = `react-toolbox-form-${props.storage}`;
|
|
||||||
if (value) {
|
|
||||||
const store = {};
|
|
||||||
for (const attr of props.attributes) {
|
|
||||||
if (attr.storage) store[attr.ref] = value[attr.ref];
|
|
||||||
}
|
|
||||||
window.localStorage.setItem(key, JSON.stringify(store));
|
|
||||||
} else if (props.storage) {
|
|
||||||
const store = JSON.parse(window.localStorage.getItem(key) || {});
|
|
||||||
for (const input of props.attributes) {
|
|
||||||
if (store && store[input.ref]) {
|
|
||||||
input.value = store[input.ref];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return props.attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
getValue () {
|
|
||||||
const value = {};
|
|
||||||
for (const ref of Object.keys(this.refs)) {
|
|
||||||
const el = this.refs[ref];
|
|
||||||
if (el.getValue) {
|
|
||||||
if (ref.indexOf('.') === -1) {
|
|
||||||
value[ref] = el.getValue();
|
|
||||||
} else {
|
|
||||||
let parent = value;
|
|
||||||
const hierarchy = ref.split('.');
|
|
||||||
hierarchy.forEach((attr, index) => {
|
|
||||||
if (index === hierarchy.length - 1) {
|
|
||||||
parent[attr] = el.getValue();
|
|
||||||
} else {
|
|
||||||
parent[attr] = parent[attr] || {};
|
|
||||||
parent = parent[attr];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
setValue (data = {}) {
|
|
||||||
for (const field of data) {
|
|
||||||
if (this.refs[field.ref].setValue) {
|
|
||||||
this.refs[field.ref].setValue(field.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const className = `${style.root} ${this.props.className}`;
|
const className = `${style.root} ${this.props.className}`;
|
||||||
const attributes = this.state.attributes.map((attribute, index) => {
|
|
||||||
if (attribute.type === 'autocomplete') {
|
|
||||||
return <Autocomplete key={index} {...attribute} onChange={this.onChange}/>;
|
|
||||||
} else if (attribute.type === 'submit') {
|
|
||||||
return <Button key={index} {...attribute} ref='submit' onClick={this.onSubmit} type='square' />;
|
|
||||||
} else if (attribute.type === 'checkbox') {
|
|
||||||
return <Checkbox key={index} {...attribute} onChange={this.onChange}/>;
|
|
||||||
} else if (attribute.type === 'date_picker') {
|
|
||||||
return <DatePicker key={index} {...attribute} onChange={this.onChange}/>;
|
|
||||||
} else if (attribute.type === 'dropdown') {
|
|
||||||
return <Dropdown key={index} {...attribute} onChange={this.onChange}/>;
|
|
||||||
} else if (attribute.type === 'radio_group') {
|
|
||||||
return <RadioGroup key={index} {...attribute} onChange={this.onChange}/>;
|
|
||||||
} else if (attribute.type === 'slider') {
|
|
||||||
return <Slider key={index} {...attribute} onChange={this.onChange}/>;
|
|
||||||
} else if (attribute.type === 'switch') {
|
|
||||||
return <Switch key={index} {...attribute} onChange={this.onChange}/>;
|
|
||||||
} else if (attribute.type === 'time_picker') {
|
|
||||||
return <TimePicker key={index} {...attribute} onChange={this.onChange}/>;
|
|
||||||
} else {
|
|
||||||
return <Input key={index} {...attribute} />;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form data-react-toolbox='form' className={className} onSubmit={this.onSubmit}>
|
||||||
data-react-toolbox='form'
|
{this.renderFields()}
|
||||||
className={className}
|
|
||||||
onChange={this.onChange}
|
|
||||||
onSubmit={this.onSubmit}
|
|
||||||
>
|
|
||||||
{attributes}
|
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue