admin-on-rest: Скрыть ввод формы зависит от другого значения ввода
Я не мог найти способ скрыть ввод зависит от некоторого значения записи. Я пытался получить import { formValueSelector } from 'redux-form'
чтобы получить текущее состояние, но я не смог.
export default props =>
<Edit {...props}>
<SimpleForm>
<DisabledInput source="id"/>
<NumberInput options={opts} source="age" />
{
props.record.age > 18 &&
<TextInput options={opts} source="question"/>
}
</SimpleForm>
</Edit>
4 ответа
Вы можете использовать marmelab / aor-зависимый ввод, это компонент для отображения ввода в зависимости от других значений ввода.
Пример использования:
import React from 'react';
import {
Create, SimpleForm, TextInput, DisabledInput, NumberInput
} from 'admin-on-rest';
import DependentInput from 'aor-dependent-input';
const checkAge = (age) => {
return parseInt(age, 10) > 18;
};
const UserCreate = (props) => (
<Create {...props}>
<SimpleForm>
<DisabledInput source="id"/>
<NumberInput source="age" step="1" />
<DependentInput dependsOn="age" resolve={checkAge}>
<TextInput source="question"/>
</DependentInput>
</SimpleForm>
</Create>
);
export default UserCreate;
record
не меняется, пока вы не отправите заявку, поэтому ваше решение не работает. Я считаю, что решение заключается в использовании formValueSelector
, как объяснено в документации приставки, в пользовательских компонентах ввода.
Что-то вроде:
// in src/ConditionalInput.js
import React from 'react';
import { connect } from 'react-redux';
import { formValueSelector } from 'redux-form'
import { TextInput } from 'admin-on-rest/lib/mui`;
const ConditionalInput = ({ isDisplayed, condition, children, ...rest }) =>
isDisplayed
? React.cloneElement(children, rest)
: null;
function mapStateToProps(state, props) {
return {
isDisplayed: props.condition(formValueSelector('record-form')),
}
}
export default connect(mapStateToProps)(ConditionalInput);
// in your EditView
export default props =>
<Edit {...props}>
<SimpleForm>
<DisabledInput source="id"/>
<NumberInput options={opts} source="age" />
<ConditionalInput condition={selector => selector('age') > 18}>
<TextInput options={opts} source="question"/>
</ConditionalInput>
</SimpleForm>
</Edit>
Ответ Франсуа был очень близок, и, честно говоря, мой не настолько чист, но у меня было несколько проблем с ним:
selector
требует от государства тоже- после прохождения в состоянии у меня были проблемы с
Trying to access touched of undefined
После некоторого поиска я обнаружил, что касание является мета-атрибутом, см. https://github.com/marmelab/admin-on-rest/blob/master/docs/Inputs.md. И на странице говорится, что <Field>
проходит meta
и input
приписать своему ребенку. Я попытался исправить ответ Франсуа, но я хотел изменить его ответ.
const ConditionalChildRendering = ({isDisplayed, condition, children, ...rest}) => {
return isDisplayed
? React.cloneElement(children, rest)
: null;
}
const ConditionalInput = connect((state, props) => {
return {
isDisplayed: props.condition(formValueSelector('record-form'), state),
}
})(ConditionalChildRendering);
...
let conditionalTextField = ({meta, input, name, ...rest}) => {
return <ConditionalInput {...rest}>
<TextInput source={name} meta={meta} input={input} {...rest} />
</ConditionalInput>;
};
<Field
component={conditionalTextField}
name="postcode"
condition={(selector,state) => selector(state, 'somefield') === 'somevalue'} />
Благодарю Франсуа за то, что он указал мне правильное направление с формами. К сожалению, с этим решением вам нужно будет обернуть каждое поле в переменную, чтобы иметь возможность передавать в <Field>
"s component
имущество. (но если кто-то знает более хороший способ, пожалуйста, поделитесь, я новичок, чтобы реагировать)
У меня была похожая проблема, но я не смог отобразить ярлык с помощью этого решения, поэтому я внес небольшие изменения, чтобы отобразить ярлык и сделать его более общим.
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { formValueSelector } from 'redux-form';
import {TextInput,FieldTitle} from 'admin-on-rest';
import { Field } from 'redux-form';
function mapStateToProps(state, props) {
return {
isDisplayed: props.condition(formValueSelector('record-form'),state),
}
}
const ConditionalInput = ({ isDisplayed,source,label,resource,isRequired,component, ...rest }) => {
if (isDisplayed) {
return <Field name={source}
component={component}
label={(addLabel)?<FieldTitle
label={label}
source={source}
resource={resource}
isRequired={isRequired}/>:null} {...rest} />
} else {
return null;
}
}
ConditionalInput.defaultProps = {
addLabel: true,
isRequired : false
}
ConditionalInput.propTypes = {
addField: PropTypes.bool.isRequired,
elStyle: PropTypes.object,
input: PropTypes.object,
label: PropTypes.string,
resource: PropTypes.string,
source: PropTypes.string,
isRequired:PropTypes.bool,
component:PropTypes.object
};
export const GcConditionalInput = connect(mapStateToProps)(ConditionalInput);
...
//then it can be used like this
<SelectInput source="terminationStatus" optionText="label" optionValue="id" choices={terminationStatus} style={inlineBlockStyle} allowEmpty/>
<GcConditionalInput source="terminationEnteredDate" component={DateInput} condition={(selector,state) => selector(state, 'terminationStatus') !== null}/>
<GcConditionalInput source="terminationComment" component={TextInput} condition={(selector,state) => selector(state, 'terminationStatus') !== null}/>