happypack
Version:
webpack speed booster, makes you happy!
141 lines (133 loc) • 5.03 kB
JavaScript
import React, {Component, PropTypes} from 'react';
import {reduxForm} from 'redux-form';
import surveyValidation from './surveyValidation';
function asyncValidate(data) {
// TODO: figure out a way to move this to the server. need an instance of ApiClient
if (!data.email) {
return Promise.resolve({});
}
return new Promise((resolve, reject) => {
setTimeout(() => {
const errors = {};
let valid = true;
if (~['bobby@gmail.com', 'timmy@microsoft.com'].indexOf(data.email)) {
errors.email = 'Email address already used';
valid = false;
}
if (valid) {
resolve();
} else {
reject(errors);
}
}, 1000);
});
}
@reduxForm({
form: 'survey',
fields: ['name', 'email', 'occupation', 'currentlyEmployed', 'sex'],
validate: surveyValidation,
asyncValidate,
asyncBlurFields: ['email']
})
export default
class SurveyForm extends Component {
static propTypes = {
active: PropTypes.string,
asyncValidating: PropTypes.bool.isRequired,
fields: PropTypes.object.isRequired,
dirty: PropTypes.bool.isRequired,
handleSubmit: PropTypes.func.isRequired,
resetForm: PropTypes.func.isRequired,
invalid: PropTypes.bool.isRequired,
pristine: PropTypes.bool.isRequired,
valid: PropTypes.bool.isRequired
}
render() {
const {
asyncValidating,
dirty,
fields: {name, email, occupation, currentlyEmployed, sex},
active,
handleSubmit,
invalid,
resetForm,
pristine,
valid
} = this.props;
const styles = require('./SurveyForm.scss');
const renderInput = (field, label, showAsyncValidating) =>
<div className={'form-group' + (field.error && field.touched ? ' has-error' : '')}>
<label htmlFor={field.name} className="col-sm-2">{label}</label>
<div className={'col-sm-8 ' + styles.inputGroup}>
{showAsyncValidating && asyncValidating && <i className={'fa fa-cog fa-spin ' + styles.cog}/>}
<input type="text" className="form-control" id={field.name} {...field}/>
{field.error && field.touched && <div className="text-danger">{field.error}</div>}
<div className={styles.flags}>
{field.dirty && <span className={styles.dirty} title="Dirty">D</span>}
{field.active && <span className={styles.active} title="Active">A</span>}
{field.visited && <span className={styles.visited} title="Visited">V</span>}
{field.touched && <span className={styles.touched} title="Touched">T</span>}
</div>
</div>
</div>;
return (
<div>
<form className="form-horizontal" onSubmit={handleSubmit}>
{renderInput(name, 'Full Name')}
{renderInput(email, 'Email', true)}
{renderInput(occupation, 'Occupation')}
<div className="form-group">
<label htmlFor="currentlyEmployed" className="col-sm-2">Currently Employed?</label>
<div className="col-sm-8">
<input type="checkbox" id="currentlyEmployed" {...currentlyEmployed}/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2">Sex</label>
<div className="col-sm-8">
<input type="radio" id="sex-male" {...sex} value="male" checked={sex.value === 'male'}/>
<label htmlFor="sex-male" className={styles.radioLabel}>Male</label>
<input type="radio" id="sex-female" {...sex} value="female" checked={sex.value === 'female'}/>
<label htmlFor="sex-female" className={styles.radioLabel}>Female</label>
</div>
</div>
<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">
<button className="btn btn-success" onClick={handleSubmit}>
<i className="fa fa-paper-plane"/> Submit
</button>
<button className="btn btn-warning" onClick={resetForm} style={{marginLeft: 15}}>
<i className="fa fa-undo"/> Reset
</button>
</div>
</div>
</form>
<h4>Props from redux-form</h4>
<table className="table table-striped">
<tbody>
<tr>
<th>Active Field</th>
<td>{active}</td>
</tr>
<tr>
<th>Dirty</th>
<td className={dirty ? 'success' : 'danger'}>{dirty ? 'true' : 'false'}</td>
</tr>
<tr>
<th>Pristine</th>
<td className={pristine ? 'success' : 'danger'}>{pristine ? 'true' : 'false'}</td>
</tr>
<tr>
<th>Valid</th>
<td className={valid ? 'success' : 'danger'}>{valid ? 'true' : 'false'}</td>
</tr>
<tr>
<th>Invalid</th>
<td className={invalid ? 'success' : 'danger'}>{invalid ? 'true' : 'false'}</td>
</tr>
</tbody>
</table>
</div>
);
}
}