4

我找不到隐藏输入的方法取决于某些记录值。我试图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

4 回答 4

12

您可以使用marmelab/aor-dependent-input,它是用于根据其他输入值显示输入的组件。

示例用法:

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;
于 2017-05-19T23:19:52.747 回答
5

record您提交之前不会更改,因此您的解决方案不起作用。我相信解决方案是在自定义连接的输入组件中使用formValueSelector,如redux-form 文档中所述。

就像是:

// 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>
于 2017-03-15T17:04:55.477 回答
1

弗朗索瓦的回答非常接近,公平地说,我的回答不是那么干净,但我有一些问题:

  • 也需要selector状态
  • 在通过该州后,我遇到了问题Trying to access touched of undefined

经过一番挖掘,我发现 touch 是一个元属性,请参见: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'} />

感谢 François 用表格为我指明了正确的方向。不幸的是,使用此解决方案,您需要将每个字段包装在一个变量中,以便能够传递给<Field>'scomponent属性。(但如果有人知道更好的方法,请分享,我是新手)

于 2017-03-20T23:34:55.907 回答
0

我遇到了类似的问题,但我无法使用此解决方案显示标签,因此我做了一些更改以显示标签并使其更通用。

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}/>
于 2018-05-11T12:48:09.473 回答