Built out form ajax requesting, needs some more testing
This commit is contained in:
@ -22,21 +22,123 @@
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import React from 'react';
|
||||
import Loader, { LoaderBackdrop } from './../../loading/Loader';
|
||||
|
||||
export default function(props) {
|
||||
let clazzes = "o-form";
|
||||
export default class Form extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
if(props.className) clazzes += " " + props.className;
|
||||
//Prepare our initial state
|
||||
let s = {
|
||||
ajax: props.ajax || false,
|
||||
loader: props.loader || false,
|
||||
loading: false,
|
||||
onSubmit: props.onSubmit,
|
||||
contentType: props.contentType || props.encType || "application/x-www-form-urlencoded"
|
||||
};
|
||||
|
||||
return (
|
||||
<form
|
||||
className={ clazzes }
|
||||
method={ props.method }
|
||||
action={ props.action }
|
||||
autoComplete={ props.autoComplete }
|
||||
target={ props.target }
|
||||
>
|
||||
{ props.children }
|
||||
</form>
|
||||
);
|
||||
//Determine action and method based off the internals
|
||||
if(props.action) s.action = props.action;
|
||||
if(props.method) s.method = props.method;
|
||||
|
||||
if(props.get) {
|
||||
s.action = props.get;
|
||||
s.method = "GET";
|
||||
}
|
||||
|
||||
if(props.post) {
|
||||
s.action = props.post;
|
||||
s.method = "POST";
|
||||
}
|
||||
|
||||
//Write our state to the component
|
||||
this.state = s;
|
||||
}
|
||||
|
||||
onSubmit(e) {
|
||||
//Is Ajax?
|
||||
if(!this.state.ajax) {
|
||||
return this.state.onSubmit ? this.state.onSubmit(e) : true;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
if(!this.state.action) return console.warning("This form has no action.");
|
||||
if(this.state.submitting) return false;//Already submitting?
|
||||
|
||||
//Start submitting!
|
||||
this.setState({
|
||||
loading: true,
|
||||
submitting: true
|
||||
});
|
||||
|
||||
//Prepare our request.
|
||||
fetch(this.state.action, {
|
||||
method: this.state.method,
|
||||
mode: this.state.mode,
|
||||
headers: {
|
||||
"Content-Type": this.state.contentType
|
||||
}
|
||||
})
|
||||
.then(this.onSubmitted.bind(this))
|
||||
.catch(this.onError.bind(this))
|
||||
;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
onSubmitted(response) {
|
||||
if(!response.ok) {
|
||||
throw Error(response.statusText);
|
||||
}
|
||||
|
||||
if(this.props.onData) return this.props.onData(response);
|
||||
|
||||
//Handle the old fashioned way (expect json)
|
||||
response.json().then(this.onJSON.bind(this)).catch(this.onError.bind(this));
|
||||
}
|
||||
|
||||
onJSON(response) {
|
||||
if(this.props.onJSON) return this.props.onJSON(response);
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
onError(e, a, b) {
|
||||
this.setState({
|
||||
loading: false,
|
||||
submitting: false
|
||||
});
|
||||
if(this.props.onError) return this.props.onError(e, a, b);
|
||||
|
||||
if(e) console.error(e);
|
||||
if(a) console.error(a);
|
||||
if(b) console.error(b);
|
||||
}
|
||||
|
||||
render() {
|
||||
let clazz = "o-form";
|
||||
if(this.props.className) clazz += " " + this.props.className;
|
||||
|
||||
//Do I need a loader?
|
||||
let loader;
|
||||
if(this.state.loader && this.state.loading) {
|
||||
loader = (
|
||||
<LoaderBackdrop className="o-form__loader">
|
||||
<Loader className="o-form__loader-spinner" />
|
||||
</LoaderBackdrop>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<form
|
||||
className={clazz}
|
||||
method={ this.state.method }
|
||||
autoComplete={ this.props.autoComplete }
|
||||
target={ this.props.target }
|
||||
onSubmit={ this.onSubmit.bind(this) }
|
||||
>
|
||||
{ this.props.children }
|
||||
{ loader }
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user