react-admin
react-admin copied to clipboard
Validation in FormDataConsumer is not updated (taking previous validation) when selected option is updated in SelectInput.
What you were expecting: I am expecting that validation will change according to the selected value in SelectInput dropdown.
What happened instead: It validates against the previously selected value.
Steps to reproduce:
- Create new comment. Click on Post SelectInput and a dropdown will appear. Select the last post (id = 1).
- In the field right below Post, write 'abcde', and we'll get validation error 'max 1 char'
- Now go back to Post and select the second last option (id = 2)
- Notice that the validation error is still 'max 1 char'
- Then, select last post (id = 1) again. Now we'll get validation error 'max 2 char' which is what we're supposed to get when selected id = 2.
Related code: Code is in PostReferenceInput.js I reproduced this issue in this codesandbox
import * as React from 'react';
import { Field } from 'redux-form';
import { maxLength, required } from 'ra-core';
import {
ReferenceInput,
SelectInput,
FormDataConsumer,
LongTextInput
} from 'react-admin';
import PostQuickCreateButton from './PostQuickCreateButton';
import PostQuickPreviewButton from './PostQuickPreviewButton';
class PostReferenceInput extends React.Component {
constructor(props) {
super(props);
this.renderValue = this.renderValue.bind(this);
this.validate = this.validate.bind(this);
}
validate(type) {
if (type === 1) {
return maxLength(1, 'max 1 char');
} else if (type === 2) {
return maxLength(2, 'max 2 char');
}
}
renderValue() {
return (
<FormDataConsumer>
{({ formData, ...rest }) => {
const type = formData.post_id && formData.post_id;
console.log(type);
return (
<LongTextInput
source="ruleValue"
label={type}
validate={this.validate(type)}
/>
);
}}
</FormDataConsumer>
);
}
render() {
return (
<React.Fragment>
<ReferenceInput {...this.props}>
<SelectInput optionText="id" />
</ReferenceInput>
{this.renderValue()}
<PostQuickCreateButton />
{/* We use Field to get the current value of the `post_id` field */}
<Field
name="post_id"
component={({ input }) =>
input.value && (
<PostQuickPreviewButton id={input.value} />
)
}
/>
</React.Fragment>
);
}
}
export default PostReferenceInput;
Other information:
Environment
- React-admin version: 2.8
- Last version that did not exhibit the issue (if applicable): N/A
- React version: 16.3
- Browser: Chrome
- Stack trace (in case of a JS error):
Reproduced Same in v3 https://codesandbox.io/s/late-https-f2zce
I'm not sure we can do something for this. Form validation is managed by react-final-form (or redux-form in v2). It seems they both don't care that a change made on a field can trigger a dynamic validation error on another field.
I tryed using multi validation functions instead of a unique validation function having multl messages, but it doesn't change the behaviour
@JulienMattiussi is there any workaround (that probably ditches redux-form)?
To circumvent this I am passing validateOnBlur={true}
to the form, but that messed with my ImageInput
validation because it never blurs. I guess it could help you if you don't have also an image in your form.
I had same problem. And I prefer If you want to validate between multiple value use allValues field
validate={[
required(),
minValue(),
...
anyCustom,
]}
//value: value of current input
//allValues : all values of current form
const anyCustom = (value, allValues) => {
if (...) {
return errorMessage : string
}
return undefined
}