Skip to content

Instantly share code, notes, and snippets.

@natrim
Created November 14, 2018 13:59
Show Gist options
  • Save natrim/167c75d920229201f6d76a5dcc2512c1 to your computer and use it in GitHub Desktop.
Save natrim/167c75d920229201f6d76a5dcc2512c1 to your computer and use it in GitHub Desktop.
simplified aor-dependent-input
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { formValueSelector, getFormValues } from 'redux-form';
import get from 'lodash/get';
import set from 'lodash/set';
import FormField from 'admin-on-rest/lib/mui/form/FormField';
const REDUX_FORM_NAME = 'record-form';
const getValue = (value, path) => {
if (typeof value === 'object') {
return get(value, path);
}
return value;
};
export const DependentInputComponent = ({ children, formValues, dependsOn, value, resolve, ...props }) => {
let show;
if (resolve && (dependsOn === null || typeof dependsOn === 'undefined')) {
show = resolve(formValues, dependsOn, value);
} else if (resolve && !Array.isArray(dependsOn)) {
show = resolve(getValue(formValues, dependsOn));
} else if (resolve && Array.isArray(dependsOn)) {
const obj = dependsOn.reduce((acc, path) => {
const value = get(formValues, path);
return set(acc, path, value);
}, {});
show = resolve(obj);
} else if (Array.isArray(dependsOn) && Array.isArray(value)) {
show = dependsOn.reduce((acc, s, index) => acc && get(formValues, s) === value[index], true);
} else if (typeof value === 'undefined') {
if (Array.isArray(dependsOn)) {
show = dependsOn.reduce((acc, s) => acc && !!getValue(formValues, s), true);
} else {
show = !!getValue(formValues, dependsOn);
}
} else {
show = getValue(formValues, dependsOn) === value;
}
if (!show) {
return null;
}
if (Array.isArray(children)) {
return (
<div>
{React.Children.map(children, child => (
<div
key={child.props.source}
style={child.props.style}
className={`aor-input-${child.props.source}`}
>
<FormField input={child} {...props} />
</div>
))}
</div>
);
}
return (
<div key={children.props.source} style={children.props.style} className={`aor-input-${children.props.source}`}>
<FormField input={children} {...props} />
</div>
);
};
DependentInputComponent.propTypes = {
children: PropTypes.node.isRequired,
dependsOn: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
value: PropTypes.any,
resolve: PropTypes.func,
formValues: PropTypes.object.isRequired,
};
export const mapStateToProps = (state, { resolve, dependsOn }) => {
if (resolve && (dependsOn === null || typeof dependsOn === 'undefined')) {
return { formValues: getFormValues(REDUX_FORM_NAME)(state) };
}
if (Array.isArray(dependsOn)) {
if (dependsOn.length > 1) {
// We have to destructure the array here as redux-form does not accept an array of fields
return { formValues: formValueSelector(REDUX_FORM_NAME)(state, ...dependsOn) };
} else if (dependsOn.length === 1) {
const dep = dependsOn.shift();
return { formValues: { [dep]: formValueSelector(REDUX_FORM_NAME)(state, dep) } };
} else {
return { formValues: getFormValues(REDUX_FORM_NAME)(state) };
}
}
return { formValues: { [dependsOn]: formValueSelector(REDUX_FORM_NAME)(state, dependsOn) } };
};
export default connect(mapStateToProps)(DependentInputComponent);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment