Built out form ajax requesting, needs some more testing
This commit is contained in:
@ -47,16 +47,20 @@ class App extends React.Component {
|
||||
|
||||
render() {
|
||||
let clazz = "c-app";
|
||||
if(this.props.menuOpen) clazz += " is-menu-open "
|
||||
if(this.props.menuOpen) clazz += " is-menu-open ";
|
||||
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<div className={clazz} ref="app">
|
||||
<Header />
|
||||
<Routes onEntering={this.onEnteringBound} />
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
let children = (
|
||||
<div className={clazz} ref="app">
|
||||
<Header />
|
||||
<Routes onEntering={this.onEnteringBound} />
|
||||
</div>
|
||||
);
|
||||
|
||||
if(true) {
|
||||
return <HashRouter>{children}</HashRouter>;
|
||||
} else {
|
||||
return <BrowserRouter>{children}</BrowserRouter>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -125,6 +125,12 @@ module.exports = {
|
||||
|
||||
"contact": {
|
||||
"title": "Contact Me",
|
||||
"heading": "Contact Me",
|
||||
"paragraph": "\
|
||||
Want to get in touch with me? Fill out this easy form and I should be \
|
||||
in touch shortly to chat! More of a phone person? Leave a number \
|
||||
and we can chat.\
|
||||
",
|
||||
"name": {
|
||||
"label": "Name",
|
||||
"placeholder": "Enter your name."
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export default function(props) {
|
||||
const Loader = function(props) {
|
||||
return (
|
||||
<span className={"o-loader"+(props.className?" "+props.className:"")}>
|
||||
<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" className="o-loader__image">
|
||||
@ -38,3 +38,16 @@ export default function(props) {
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const LoaderBackdrop = function(props) {
|
||||
return (
|
||||
<div className={"o-loader__backdrop"+(props.className?" "+props.className:"")}>
|
||||
{ props.children }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Loader;
|
||||
export {
|
||||
LoaderBackdrop
|
||||
};
|
||||
|
@ -52,11 +52,9 @@ class ContactPage extends React.Component {
|
||||
|
||||
<ElementScrollFader from="left">
|
||||
<ContentBox box className="u-text-center">
|
||||
<Title>Contact Me</Title>
|
||||
<Title>{ Language.get("pages.contact.heading") }</Title>
|
||||
<Paragraph>
|
||||
Want to get in touch with me? Fill out this easy form and I should be
|
||||
in touch shortly to chat! More of a phone person? Leave a number
|
||||
and we can chat.
|
||||
{ Language.get("pages.contact.paragraph") }
|
||||
</Paragraph>
|
||||
</ContentBox>
|
||||
</ElementScrollFader>
|
||||
@ -66,7 +64,7 @@ class ContactPage extends React.Component {
|
||||
|
||||
<ElementScrollFader from="right">
|
||||
<BodySection>
|
||||
<Form>
|
||||
<Form post="/api/contact/send" ajax loader>
|
||||
<InputGroup>
|
||||
<Label>{ Language.get("pages.contact.name.label") }</Label>
|
||||
<Input
|
||||
@ -74,7 +72,6 @@ class ContactPage extends React.Component {
|
||||
placeholder={ Language.get("pages.contact.name.placeholder") }
|
||||
required={ Forms.contact.name.required }
|
||||
maxLength={ Forms.contact.name.maxLength }
|
||||
|
||||
/>
|
||||
</InputGroup>
|
||||
|
||||
|
@ -8,7 +8,9 @@
|
||||
* Version:
|
||||
* 1.0.0 - 2018/05/13
|
||||
*/
|
||||
.o-form { }
|
||||
.o-form {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.o-form__group {
|
||||
+ .o-btn-group,
|
||||
|
@ -46,4 +46,13 @@
|
||||
stroke: $s-color--loader;
|
||||
}
|
||||
}
|
||||
|
||||
&__backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ module.exports = {
|
||||
path: '/dist',
|
||||
filename: "app.js"
|
||||
},
|
||||
|
||||
mode: 'development',
|
||||
|
||||
resolve: {
|
||||
modules: ['node_modules', './public'],
|
||||
@ -55,6 +57,9 @@ module.exports = {
|
||||
// initialize the added webpack plugins
|
||||
plugins: [
|
||||
HTMLWebpackPluginConfig,
|
||||
new webpack.HotModuleReplacementPlugin()
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
DEVELOPMENT: JSON.stringify(true)
|
||||
})
|
||||
]
|
||||
};
|
||||
|
Reference in New Issue
Block a user