Built out form ajax requesting, needs some more testing

This commit is contained in:
2018-07-04 21:40:19 +10:00
parent e4eb653a88
commit bd77bf6696
8 changed files with 169 additions and 31 deletions

View File

@ -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>
);
}
}