我需要验证月份和年份的生日。如果feb比生日不会大于28。如果月数比生日数不会超过30,如果奇数月,生日不会大于31,而在闰年生日不会超过29。已经为所有可能的条件设置了验证。现在我必须在选择月份时从redux商店获得价值。这是遗留代码和示例显示,从redux表单网站示例中选择值使我对此代码感到困惑。我需要在此代码中从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 :(得分:0)
要验证某些字段,这取决于其他字段,您可以使用验证功能中传递的allValues
参数。
因此,您可以为该字段编写特定规则:
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]}
/>