Skip to content

Instantly share code, notes, and snippets.

@hpneo
Created November 11, 2017 16:48
Show Gist options
  • Save hpneo/8a10d16608acee774942d3105a1813f4 to your computer and use it in GitHub Desktop.
Save hpneo/8a10d16608acee774942d3105a1813f4 to your computer and use it in GitHub Desktop.
import React from 'react';
import { connect } from 'react-redux';
import { reduxForm, Field, FieldArray } from 'redux-form';
const sleep = ms =>
new Promise(resolve => setTimeout(resolve, ms));
const asyncValidateForm = (values) => {
return sleep(1000)
.then(() => {
if (values.email !== '[email protected]') {
throw { email: 'Remoto: El correo es inválido' };
}
});
};
const validateForm = (values) => {
const errors = {};
if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
// errors.email = 'Debe ingresar un correo válido';
}
if (Object.keys(errors).length > 0) {
errors._error = 'Formulario inválido';
}
return errors;
}
const required = value =>
value ? undefined : 'Debe ingresar un valor';
const email = value =>
/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value) ? undefined : 'Debe ingresar un correo con formato correcto';
const validateFieldArray = (values) => {
const errors = {};
const commentsError = [];
console.log(values);
if (!values || values.length === 0) {
errors.comments = {
_error: 'Debe agregar al menos un comentario'
}
}
else {
values.forEach((value, index) => {
const fieldErrors = {};
if (!value || !value.text) {
fieldErrors.text = 'El comentario necesita un contenido';
commentsError[index] = fieldErrors;
}
});
if (commentsError.length > 0) {
errors.comments = commentsError;
}
}
console.log(errors);
if (Object.keys(errors).length > 0) {
return errors;
}
};
const renderField = (props) => {
const { type, input, label, meta } = props;
return (
<div>
<label htmlFor={input.name}>{label}</label>
<input type={type} {...input} />
{ meta.touched && meta.error && <span>{meta.error}</span> }
</div>
);
};
const renderComments = ({ fields, meta, ...props }) => {
console.log(meta, props);
return (
<ul>
<li>
{
meta.submitFailed && meta.error
&& meta.error.comments
&& <span>{meta.error.comments._error}</span>
}
</li>
<li>
<button
type="button"
onClick={() => fields.push()}
>
Agregar comentario
</button>
</li>
{fields.map((comment, index) => {
return (
<li key={index}>
<button type="button" title="Quitar"
onClick={() => fields.remove(index)}
>
Quitar
</button>
<Field
name={`${comment}.subject`}
type="text"
component={renderField}
label="Asunto"
/>
<Field
name={`${comment}.text`}
type="text"
component={renderField}
label="Comentario"
/>
{
meta.submitFailed && meta.error
&& meta.error.comments
&& meta.error.comments[index]
&& <span>{meta.error.comments[index].text}</span>
}
</li>
);
})}
</ul>
);
};
const ContactForm = (props) => {
const { handleSubmit } = props;
return (
<form onSubmit={handleSubmit}>
<Field name='name' component='input' type='text' />
<Field
name='email'
component={renderField}
type='email'
label='Correo electrónico'
validate={[required, email]} />
<FieldArray
name='comments'
component={renderComments}
validate={validateFieldArray}
/>
<button type='submit'>Enviar</button>
{
props.anyTouched &&
props.error &&
<span>{props.error}</span>
}
</form>
);
}
const EnhancedContactForm = reduxForm({
form: 'contact-form',
// validate: validateForm,
asyncValidate: asyncValidateForm,
asyncBlurFields: ['email'],
// initialValues: {
// name: 'Gustavo Leon',
// email: '[email protected]',
// comments: [
// undefined,
// {
// subject: 'Hola',
// text: 'Mundo'
// }
// ]
// }
})(ContactForm);
const mapStateToProps = (state) => {
return {
initialValues: {
name: 'Gustavo Leon',
email: '[email protected]',
comments: [
undefined,
{
subject: 'Hola',
text: 'Mundo'
}
]
}
};
};
export default connect(mapStateToProps)(EnhancedContactForm);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment