2017-10-13 4 views
0

月と年について誕生日を検証する必要があります。誕生日よりもfebが28より大きければ、誕生日は誕生日よりも偶数で30を超えない場合、奇数月の場合は誕生日が31より大きくならず、うるう年の誕生日は29より大きくなりません。すべての可能な条件の検証を設定しました。今私は月を選択するには、還元店からの価値を取得する必要があります。これはレガシーコードであり、このコードと私を混乱させるような、redux形式のウェブサイトの例から値を選択する例です。このコードでreduxストアから値を取得する必要があります。その結果、指定された条件で誕生日を検証するための条件に入れることができます。あなたが検証関数に渡されたallValuesパラメータを使用することができます他の人に依存し、いくつかのフィールドを、検証するためにReduxフォームフォームの値の選択

import React, { PureComponent, PropTypes } from 'react'; 
import { connect } from 'react-redux'; 
// import { formValueSelector } from 'redux-form/immutable'; 
import moment from 'moment'; 
import { createStructuredSelector } from 'reselect'; 
import { FaVenus as FemaleIcon, FaMars as MaleIcon } from 'react-icons/lib/fa/'; 
import { FormattedMessage, injectIntl, intlShape } from 'react-intl'; 
import { Field, reduxForm, actions } from 'redux-form/immutable'; 
import { TextInput, Select } from 'components/Fields'; 

import * as rules from 'utils/validationRules'; 
import * as DateValidator from 'utils/DateValidator'; 
import { DOB_RAW_FORMAT, PERSON_TYPE_CLIENT, PERSON_TYPE_PARTNER, HOUSEHOLD_SINGLE, birthMonth } from 'containers/constants'; 
import { selectDobOfClientAndPartner, selectPostalCodeLookup } from '../selectors'; 
import { doValidatePostalCode, clearPostalCodeLookup } from '../actions'; 

// const FORM_NAME = 'advisor-feeForm'; 

// const selector = formValueSelector(FORM_NAME); 

export const SexOptions = [ 
    { value: 'female', label: 'Female', icon: <FemaleIcon /> }, 
    { value: 'male', label: 'Male', icon: <MaleIcon /> }, 
]; 

let dobValues = null; 
let personType = ''; 
const AGE_OFFSET = 30; 
let showPostalCodeInfo = false; 
const CLIENT_FORM = 'clientForm'; 

const dobDiffValidator = (dobVals, householdType, dob) => { 
    let diffDob = null; 
    if (dobVals && dobVals.householdType !== HOUSEHOLD_SINGLE && (dobVals.partner || dobVals.client)) { 
    if (householdType === PERSON_TYPE_CLIENT) { 
     diffDob = dobVals.partner || dob; 
    } else if (householdType === PERSON_TYPE_PARTNER) { 
     diffDob = dobVals.client || dob; 
    } 
    return DateValidator.validateDobDiff(diffDob, dob, 'years', AGE_OFFSET, householdType); 
    } 
    return null; 
}; 

const doValidateDob = (formProps) => { 
    const date = moment.utc(formProps.toJS().DOB, DOB_RAW_FORMAT, true); 
    const errors = {}; 
    if (dobValues && personType && date) { 
    errors.DOB = dobDiffValidator(dobValues, personType, date); 
    } 
    return errors; 
}; 

const normalizePostalCode = (value) => { 
    const postalCode = value.toUpperCase().replace(/\s+/, ''); 
    showPostalCodeInfo = false; 
    if (!postalCode || postalCode.length !== 6) return value; 

    return postalCode.substring(0, 3).concat(' ', postalCode.substring(3)); 
}; 

const OptionStandalone = ({ label, icon, value, onSelect, namePrefix, disabled }) => { 
    const cn = disabled ? 'client-form__button--disabled client-form__button' : 'client-form__button'; 
    return (
    <button id={`${value}button`} onClick={() => onSelect(value)} type="button" className={cn}> 
     {label} 
    </button> 
); 
}; 

class MaleOrFemale extends PureComponent { 
    onChangeCombined = (val) => { 
    const { input } = this.props; 
    input.onChange(val); 
    }; 

    render() { 
    return (
     <span> 
     <OptionStandalone 
      {...SexOptions[1]} 
      onSelect={this.onChangeCombined} 
      disabled={this.props.input.value !== 'male'} 
     /> 
     <OptionStandalone 
      {...SexOptions[0]} 
      onSelect={this.onChangeCombined} 
      disabled={this.props.input.value !== 'female'} 
     /> 
     </span> 
    ); 
    } 
} 

const SexSelector = ({ onChange, active, namePrefix, captions }) => { 
    const selector = (
    <Field 
     name={`${namePrefix}sex`} 
     component={MaleOrFemale} 
     directOnChange={onChange} 
     active={active} 
     className="2" 
     validate={[rules.required]} 
    /> 
); 

    return (
    <div className="client-form__input"> 
     <div className="client-form__input-label" id="labelSex"> 
     <FormattedMessage {...captions.sexLabel} /> 
     </div> 
     {selector} 
    </div> 
); 
}; 

**const BirhdayValidator = (validateAllDoB) => { 
    if (birthMonth !== '2') { 
    validateAllDoB = rules.birthDay; 
    } else { 
    validateAllDoB = rules.febBirthday; 
    } 
    return (
    <Field 
     name={'birth_day'} 
     type="tel" placeholder={'day'} 
     component={TextInput} 
     validate={[rules.required, validateAllDoB]} 
    /> 
); 
};** 

/* eslint react/no-multi-comp: 0 */ 
class ClientForm extends PureComponent { 
    constructor(props) { 
    super(props); 
    const { initialValues } = props; 

    this.state = { 
     sex: initialValues.get('sex'), 
     fNameFilled: false, 
     lNameFilled: false, 
    }; 
    } 

    componentDidMount() { 
    const formName = this.props.form; 
    dobValues = this.props.dobValues; 
    personType = formName.substring(0, formName.indexOf('Form')); 
    } 

    componentWillUnmount() { 
    this.props.clearPostalCode(); 
    } 

    handleFirstNameBlur = (e) => { 
    const value = e.target.value; 
    const isFilled = value.length > 0; 
    this.setState({ fNameFilled: isFilled }); 
    }; 

    handleLastNameBlur = (e) => { 
    const value = e.target.value; 
    const isFilled = value.length > 0; 
    this.setState({ lNameFilled: isFilled }); 
    }; 

    handleSexChange = (value) => { 
    this.setState({ sex: value }); 
    }; 

    handlePostalCodeOnBlur = (e) => { 
    showPostalCodeInfo = false; 
    const postalCode = String(e.target.value); 
    if (postalCode) { 
     const isInvalid = rules.postalCode(postalCode); 
     if (!isInvalid) { 
     showPostalCodeInfo = true; 
     this.props.clearPostalCode(); 
     this.props.validatePostalCode(postalCode); 
     } 
    } else { 
     // error... 
    } 
    }; 

    handleLastNameKeyPress = (e) => { 
    if (e.key === 'Enter') { 
     this.handleLastNameBlur(e); 
    } 
    }; 

    incFieldsCount() { 
    if (this.state.fieldsCount + 1 <= this.maxFieldsCount) { 
     return { fieldsCount: this.state.fieldsCount + 1 }; 
    } 
    return { fieldsCount: this.state.fieldsCount }; 
    } 

    render() { 
    const { captions, intl, namePrefix, postalCodeLookup, form } = this.props; 
    const state = this.state; 
    return (
     <div className="client-form-container"> 
     <h2> 
      <FormattedMessage {...captions.header} /> 
     </h2> 
     <form className="client-form"> 
      <div> 
      <div className="client-form__input"> 
       <div className="client-form__input-label" id="labelClientFirstName"> 
       <FormattedMessage {...captions.nameLabel} /> 
       </div> 
       <div className="client-form__input-field client-form__input-field__first-name"> 
       <Field 
        name={`${namePrefix}firstName`} 
        type="text" 
        component={TextInput} 
        placeholder={intl.formatMessage(captions.firstNamePlaceholder)} 
        validate={[rules.required]} 
        onBlur={this.handleFirstNameBlur} 
        ariaLabel={intl.formatMessage(captions.firstNamePlaceholder)} 
       /> 
       </div> 
       <div className="client-form__input-label" id="labelClientLastName" /> 
       <div className="client-form__input-field client-form__input-field__last-name"> 
       <Field 
        name={`${namePrefix}lastName`} 
        type="text" 
        component={TextInput} 
        placeholder={intl.formatMessage(captions.lastNamePlaceholder)} 
        validate={[rules.required]} 
        onBlur={this.handleLastNameBlur} 
        onKeyPress={this.handleLastNameKeyPress} 
        ariaLabel={intl.formatMessage(captions.lastNamePlaceholder)} 
       /> 
       </div> 
      </div> 
      <SexSelector 
       onChange={this.handleSexChange} 
       value={state.sex} 
       namePrefix={namePrefix} 
       captions={captions} 
      /> 
      <div className="client-form__input"> 
       <div className="client-form__input-label" id="labelDOB"> 
       <FormattedMessage {...captions.birthdayLabel} values={{ GENDER: state.sex || '' }} /> 
       </div> 

       <div className="client-form__input-field client-form__input-field__birth-month"> 
       <Field 
        name={`${namePrefix}birth_month`} 
        label="month" 
        component={Select} 
        placeholder="Month" 
        validate={[rules.required]} 
        options={birthMonth} 
       /> 
       </div> 
       <div className="client-form__input-label" /> 
       <div className="client-form__input-field client-form__input-field__birth-day"> 
       {BirhdayValidator()} 
       </div> 

       <div className="client-form__input-label" /> 
       <div className="client-form__input-field client-form__input-field__birth-year"> 
       <Field 
        name={`${namePrefix}birth_year`} 
        type="tel" placeholder={'year'} 
        component={TextInput} 
        validate={[rules.required, rules.birthYear]} 
       /> 
       </div> 
      </div> 
      {form === CLIENT_FORM && (
       <div className="client-form__input"> 
       <div className="client-form__input-label" id="labelPostalCode"> 
        <FormattedMessage {...captions.postalCodeLabel} /> 
       </div> 
       <div className="client-form__input-field"> 
        <Field 
        name={`${namePrefix}postalCode`} 
        type="text" 
        component={TextInput} 
        placeholder="e.g. M1M 1M1" 
        normalize={normalizePostalCode} 
        validate={[rules.required, rules.postalCode]} 
        onBlur={this.handlePostalCodeOnBlur} 
        width="7em" 
        /> 
       </div> 
       </div> 
      )} 
      </div> 
      {postalCodeLookup.isPostalCodeFound === false && 
      showPostalCodeInfo && 
      form === CLIENT_FORM && (
      <div> 
       <div className="client-form__warning-label" name="label_postalCodeInfo"> 
       <FormattedMessage {...captions.postalCodeAllCanada} /> 
       </div> 
      </div> 
     )} 
     </form> 
     </div> 
    ); 
    } 
} 


ClientForm.propTypes = { 
    initialValues: PropTypes.object, 
    captions: PropTypes.object.isRequired, 
    intl: intlShape, 
    namePrefix: PropTypes.string, 
    form: PropTypes.string, 
    dobValues: PropTypes.object, 
    clearPostalCode: PropTypes.func.isRequired, 
    validatePostalCode: PropTypes.func.isRequired, 
    postalCodeLookup: PropTypes.object, 
}; 

ClientForm.defaultProps = { 
    namePrefix: '', 
}; 
const mapStateToProps = createStructuredSelector({ 
    dobValues: selectDobOfClientAndPartner(), 
    postalCodeLookup: selectPostalCodeLookup(), 
}); 

function mapDispatchToProps(dispatch) { 
    return { 
    updateErrors: (formName, field, err, touched) => { 
     if (touched) { 
     dispatch(actions.blur(formName, field, '', touched)); 
     } 
     return dispatch(actions.updateSyncErrors(formName, { [field]: err })); 
    }, 
    validatePostalCode: (postalCode) => dispatch(doValidatePostalCode(postalCode)), 
    clearPostalCode:() => dispatch(clearPostalCodeLookup()), 
    }; 
} 

export default connect(mapStateToProps, mapDispatchToProps)(
    reduxForm({ validate: doValidateDob })(injectIntl(ClientForm)) 
); 
+0

を内側にあなたの検証ロジックを置く:doValidateDobを –

答えて

0

だから、そのフィールドの特定のルール書くことができます。

const validateDoB = (value, allValues) => { 
    // For example allValues.birth_year is accessible here 
} 

をしてからFieldコンポーネント記述:

<Field 
    name={'birth_day'} 
    type="tel" placeholder={'day'} 
    component={TextInput} 
    validate={[rules.required, validateDoB]} 
/>