Last active
February 17, 2018 21:33
-
-
Save gearnode/1bfafc0cd060fbc505ff42be38f8169a to your computer and use it in GitHub Desktop.
Generic React AJAX Form
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import PropTypes from 'prop-types'; | |
import FormObject from './FormObject' | |
export default class Form extends Component { | |
static propTypes = { | |
method: PropTypes.string.isRequired, | |
action: PropTypes.string.isRequired, | |
encType: PropTypes.string.isRequired, | |
serializeForm: PropTypes.func.isRequired, | |
onResponse: PropTypes.func.isRequired | |
} | |
constructor(props) { | |
super(props) | |
this.state = { performing: false } | |
this.handleSubmit = this.handleSubmit.bind(this) | |
} | |
preventUserSpam(func) { | |
if (this.state.performing === false) { | |
this.setState({performing: true}) | |
func() | |
this.setState({performing: false}) | |
} else { | |
console.debug("some action perform please wait...") | |
} | |
} | |
handleSubmit(event) { | |
event.preventDefault() | |
const form = event.currentTarget | |
console.debug("NativeFormValidation disabled => ", form.noValidate) | |
this.preventUserSpam(_ => { | |
if (form.checkValidity() === false) { | |
form.reportValidity() | |
const formErrors = FormObject.collectErrors(form) | |
console.warn('formErrors => ', formErrors) | |
return | |
} | |
const fromData = FormObject.collectValues(form) | |
const serializeForm = this.props.serializeForm | |
const fetchRequest = { body: serializeForm(fromData), | |
headers: { 'content-type': this.props.encType }, | |
method: this.props.method } | |
fetch(this.props.action, fetchRequest).then(this.props.onResponse) | |
}) | |
} | |
render() { | |
return ( | |
<div> | |
<form method={ this.props.method } | |
action={ this.props.action } | |
encType={ this.props.encType } | |
onSubmit={ this.handleSubmit } | |
noValidate> | |
{ this.props.children } | |
</form> | |
</div> | |
) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default class FormObject { | |
static collectValues(form) { | |
const inputs = form.elements | |
let data = {} | |
for (let i = 0; inputs[i] !== undefined; i++) | |
if (inputs[i].nodeName !== "BUTTON") | |
data[inputs[i].name] = inputs[i].value | |
return data | |
} | |
static collectErrors(form) { | |
const inputs = form.elements | |
let errors = {} | |
for (let i = 0; inputs[i] !== undefined; i++) | |
if (inputs[i].nodeName !== "BUTTON") | |
errors[inputs[i].name] = inputs[i].validationMessage | |
return errors | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div> | |
<h1>Demo Form</h1> | |
<Form method="post" | |
action="/bar" | |
encType="application/json" | |
onResponse={ this.onResponse } | |
serializeForm={ this.serializeForm }> | |
<div> | |
<input type="text" | |
name="first_name" | |
required | |
maxLength="200" | |
placeholder="John" | |
autoComplete="given-name"/> | |
</div> | |
<div> | |
<input type="text" | |
name="last_name" | |
required | |
maxLength="200" | |
placeholder="Doe" | |
autoComplete="family-name"/> | |
</div> | |
<div> | |
<input type="email" | |
name="email" | |
required | |
placeholder="[email protected]" | |
autoComplete="email"/> | |
</div> | |
<button>Create</button> | |
</Form> | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment