1
0
mirror of https://github.com/ascribe/onion.git synced 2024-11-15 17:45:10 +01:00
onion/js/components/ascribe_forms/form.js

180 lines
5.1 KiB
JavaScript
Raw Normal View History

2015-06-23 16:02:48 +02:00
'use strict';
import React from 'react';
import ReactAddons from 'react/addons';
import Button from 'react-bootstrap/lib/Button';
import AlertDismissable from './alert';
2015-06-23 16:02:48 +02:00
import requests from '../../utils/requests';
import { getLangText } from '../../utils/lang_utils';
2015-07-10 18:51:35 +02:00
import { mergeOptionsWithDuplicates } from '../../utils/general_utils';
2015-06-23 16:02:48 +02:00
2015-06-23 16:02:48 +02:00
let Form = React.createClass({
propTypes: {
url: React.PropTypes.string,
handleSuccess: React.PropTypes.func,
getFormData: React.PropTypes.func,
children: React.PropTypes.oneOfType([
React.PropTypes.object,
React.PropTypes.array
2015-07-08 14:37:20 +02:00
]),
className: React.PropTypes.string
2015-06-23 16:02:48 +02:00
},
getInitialState() {
return {
edited: false,
submitted: false,
errors: []
};
},
reset(){
for (let ref in this.refs){
if (typeof this.refs[ref].reset === 'function'){
this.refs[ref].reset();
}
}
2015-07-10 10:30:17 +02:00
this.setState(this.getInitialState());
2015-06-23 16:02:48 +02:00
},
submit(event){
if (event) {
event.preventDefault();
}
this.setState({submitted: true});
this.clearErrors();
let action = (this.httpVerb && this.httpVerb()) || 'post';
window.setTimeout(() => this[action](), 100);
2015-06-23 16:02:48 +02:00
},
post(){
requests
.post(this.props.url, { body: this.getFormData() })
.then(this.handleSuccess)
.catch(this.handleError);
},
getFormData(){
2015-07-10 11:59:03 +02:00
let data = {};
2015-06-23 16:02:48 +02:00
for (let ref in this.refs){
data[this.refs[ref].props.name] = this.refs[ref].state.value;
}
2015-07-10 18:51:35 +02:00
if ('getFormData' in this.props){
data = mergeOptionsWithDuplicates(data, this.props.getFormData());
}
2015-06-23 16:02:48 +02:00
return data;
},
handleChangeChild(){
this.setState({edited: true});
},
handleSuccess(response){
if ('handleSuccess' in this.props){
this.props.handleSuccess(response);
}
for (var ref in this.refs){
if ('handleSuccess' in this.refs[ref]){
this.refs[ref].handleSuccess();
}
}
this.setState({edited: false, submitted: false});
},
handleError(err){
if (err.json) {
for (var input in err.json.errors){
if (this.refs && this.refs[input] && this.refs[input].state) {
this.refs[input].setErrors( err.json.errors[input]);
} else {
this.setState({errors: this.state.errors.concat(err.json.errors[input])});
}
}
}
else {
let formData = this.getFormData();
// sentry shouldn't post the user's password
if(formData.password) {
delete formData.password;
}
console.logGlobal(err, false, formData);
this.setState({errors: [getLangText('Something went wrong, please try again later')]});
2015-06-23 16:02:48 +02:00
}
this.setState({submitted: false});
},
clearErrors(){
for (var ref in this.refs){
if ('clearErrors' in this.refs[ref]){
this.refs[ref].clearErrors();
}
}
this.setState({errors: []});
},
getButtons() {
if (this.state.submitted){
return this.props.spinner;
}
if (this.props.buttons){
return this.props.buttons;
}
let buttons = null;
if (this.state.edited){
buttons = (
<div className="row" style={{margin: 0}}>
<p className="pull-right">
2015-07-02 11:54:33 +02:00
<Button className="btn btn-default btn-sm ascribe-margin-1px" type="submit">SAVE</Button>
<Button className="btn btn-danger btn-delete btn-sm ascribe-margin-1px" onClick={this.reset}>CANCEL</Button>
2015-06-23 16:02:48 +02:00
</p>
</div>
);
}
return buttons;
},
getErrors() {
let errors = null;
if (this.state.errors.length > 0){
errors = this.state.errors.map((error) => {
return <AlertDismissable error={error} key={error}/>;
});
}
return errors;
},
renderChildren() {
return ReactAddons.Children.map(this.props.children, (child) => {
2015-06-30 10:42:58 +02:00
if (child) {
return ReactAddons.addons.cloneWithProps(child, {
handleChange: this.handleChangeChild,
ref: child.props.name
});
}
2015-06-23 16:02:48 +02:00
});
},
render() {
2015-07-08 14:37:20 +02:00
let className = 'ascribe-form';
if(this.props.className) {
className += ' ' + this.props.className;
}
2015-06-23 16:02:48 +02:00
return (
2015-06-30 10:42:58 +02:00
<form
role="form"
2015-07-08 14:37:20 +02:00
className={className}
onSubmit={this.submit}
autoComplete="on">
2015-06-23 16:02:48 +02:00
{this.getErrors()}
{this.renderChildren()}
{this.getButtons()}
</form>
);
}
});
2015-07-15 18:55:02 +02:00
export default Form;