Created
November 11, 2017 16:48
-
-
Save hpneo/8a10d16608acee774942d3105a1813f4 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 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