A minimal react form with data parsing and input validation.
by marhaba
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.min.js"></script>
<div id="app"></div>
SCSS
body {
font-family: 'Roboto Slab', sans-serif;
background: white;
color: #484848;
padding: 40px;
}
input {
display: block;
margin-bottom: 15px;
margin-top: 5px;
padding: 10px;
border: 1px solid #cfcfcf;
font-family: 'Roboto Slab', sans-serif;
font-size: 16px;
outline: none;
}
pre, code {
font-family: 'Roboto Mono', Monaco;
}
button {
cursor: pointer;
padding: 12px;
background: #999;
font-family: 'Roboto Slab', sans-serif;
font-size: 16px;
border: none;
outline: none;
color: white;
border-bottom: 2px solid #797979;
&:hover {
background-color: #a1a1a1;
}
&:active {
background-color: #888;
}
}
form {
display: inline-block;
margin-right: 50px;
vertical-align: top;
}
.res-block {
display: inline-block;
}
h3 {
margin-top: 0;
}
@keyframes bounce {
from, 20%, 53%, 80%, to {
animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
transform: translate3d(0,0,0);
}
40%, 43% {
animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
transform: translate3d(0, -30px, 0);
}
70% {
animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
transform: translate3d(0, -15px, 0);
}
90% {
transform: translate3d(0,-4px,0);
}
}
.bounce {
animation: bounce 0.5s;
transform-origin: center bottom;
}
Babel + JSX
const inputParsers = {
date(input) {
const split = input.split('/');
const day = split[1]
const month = split[0];
const year = split[2];
return `${year}-${month}-${day}`;
},
uppercase(input) {
return input.toUpperCase();
},
number(input) {
return parseFloat(input);
},
};
class ShakingError extends React.Component {
constructor() { super(); this.state = { key: 0 }; }
componentWillReceiveProps() {
// update key to rerender the component to rerun the animation
this.setState({ key: ++this.state.key });
}
render() {
return <div key={this.state.key} className="bounce">{this.props.text}</div>;
}
}
class MyForm extends React.Component {
constructor() {
super();
this.state = {};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
event.preventDefault();
if (!event.target.checkValidity()) {
this.setState({ invalid: true });
return;
}
const form = event.target;
const data = new FormData(form);
for (let name of data.keys()) {
const input = form.elements[name];
const parserName = input.dataset.parse;
console.log('parser name is', parserName);
if (parserName) {
const parsedValue = inputParsers[parserName](data.get(name))
data.set(name, parsedValue);
}
}
this.setState({
res: stringifyFormData(data),
invalid: false,
});
// fetch('/api/form-submit-url', {
// method: 'POST',
// body: data,
// });
}
render() {
const { res, invalid } = this.state;
return (
<div>
<form onSubmit={this.handleSubmit} noValidate>
<label htmlFor="username">Username:</label>
<input
id="username"
name="username"
type="text"
data-parse="uppercase" required
/>
<label htmlFor="email">Email:</label>
<input id="email" name="email" type="email" />
...