2019-02-07 12:39:55 +03:00
|
|
|
import { Component } from 'preact';
|
|
|
|
|
|
|
|
const states = {};
|
|
|
|
|
|
|
|
export default class Form extends Component {
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
const includeData = props.includeData || {};
|
|
|
|
|
|
|
|
if (props.bindTo) {
|
|
|
|
if (states[props.bindTo]) {
|
|
|
|
this.state = states[props.bindTo]
|
|
|
|
this.state.data = { ...this.state.data, ...includeData };
|
|
|
|
} else {
|
|
|
|
states[props.bindTo] = this.state = {
|
|
|
|
submitted: false,
|
|
|
|
data: {...includeData}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.state = {
|
|
|
|
submitted: false,
|
|
|
|
data: {...includeData}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wrapChildren(children, data, onInput = () => {}) {
|
|
|
|
return children.map(child => {
|
2019-02-14 19:59:41 +03:00
|
|
|
const { bindTo } = child.attributes || {};
|
2019-02-07 12:39:55 +03:00
|
|
|
if (bindTo) {
|
|
|
|
child.attributes.value = data[bindTo];
|
|
|
|
child.attributes.onInput = (e) => {
|
|
|
|
// This is a hack
|
|
|
|
// Preact keeps copy of the child attributes to know whether to rerender
|
|
|
|
// The state change below will for a check, and the old attributes will be reused
|
|
|
|
child.attributes.error = false;
|
|
|
|
this.setState({
|
|
|
|
submitted: false,
|
|
|
|
data: Object.assign({}, this.state.data, {
|
|
|
|
[bindTo]: e.target.value
|
|
|
|
})
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.state.submitted && !data[bindTo]) {
|
|
|
|
child.attributes.error = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return child;
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
wrapSubmit(onSubmit = () => {}, children, data) {
|
|
|
|
return (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
const requiredFields = children.map(c => c.attributes.bindTo).filter(x => !!x)
|
|
|
|
if (!requiredFields.some(x => !data[x])) {
|
|
|
|
onSubmit(this.state.data)
|
|
|
|
}
|
|
|
|
this.setState({
|
|
|
|
submitted: true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
render({bindTo, children, onInput, onSubmit}, state) {
|
|
|
|
if (bindTo) {
|
|
|
|
states[bindTo] = state;
|
|
|
|
}
|
|
|
|
const data = state.data;
|
|
|
|
return (
|
2019-02-26 06:09:16 +03:00
|
|
|
<div className="flex flex-column mt7">
|
2019-02-07 12:39:55 +03:00
|
|
|
<form className="gm-signup-form" onSubmit={this.wrapSubmit(onSubmit, children, data)} noValidate>
|
|
|
|
{ this.wrapChildren(children, data, onInput) }
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|