List single field (#175)

* accept both single or multiple fields

* labelField should be defined
This commit is contained in:
Cássio Souza 2016-11-29 20:18:01 -02:00 committed by GitHub
parent 874810cb5c
commit 3cbb1ba280
2 changed files with 45 additions and 17 deletions

View File

@ -19,6 +19,11 @@ function valueToString(value) {
const SortableListItem = sortable(ListItem); const SortableListItem = sortable(ListItem);
const valueTypes = {
SINGLE: 'SINGLE',
MULTIPLE: 'MULTIPLE',
};
export default class ListControl extends Component { export default class ListControl extends Component {
static propTypes = { static propTypes = {
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
@ -32,6 +37,26 @@ export default class ListControl extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { itemStates: Map(), value: valueToString(props.value) }; this.state = { itemStates: Map(), value: valueToString(props.value) };
this.valueType = null;
}
componentDidMount() {
const { field } = this.props;
if (field.get('fields')) {
this.valueType = valueTypes.MULTIPLE;
} else if (field.get('field')) {
this.valueType = valueTypes.SINGLE;
}
}
componentWillUpdate(nextProps) {
if (this.props.field === nextProps.field) return;
if (nextProps.field.get('fields')) {
this.valueType = valueTypes.MULTIPLE;
} else if (nextProps.field.get('field')) {
this.valueType = valueTypes.SINGLE;
}
} }
handleChange = (e) => { handleChange = (e) => {
@ -43,26 +68,25 @@ export default class ListControl extends Component {
} }
this.setState({ value: valueToString(listValue) }); this.setState({ value: valueToString(listValue) });
this.props.onChange(listValue);
}; };
handleCleanup = (e) => { handleCleanup = (e) => {
const listValue = e.target.value.split(',').map(el => el.trim()).filter(el => el); const listValue = e.target.value.split(',').map(el => el.trim()).filter(el => el);
this.setState({ value: valueToString(listValue) }); this.setState({ value: valueToString(listValue) });
this.props.onChange(listValue);
}; };
handleAdd = (e) => { handleAdd = (e) => {
e.preventDefault(); e.preventDefault();
const { value, onChange } = this.props; const { value, onChange } = this.props;
const parsedValue = (this.valueType === valueTypes.SINGLE) ? null : Map();
onChange((value || List()).push(Map())); onChange((value || List()).push(parsedValue));
}; };
handleChangeFor(index) { handleChangeFor(index) {
return (newValue) => { return (newValue) => {
const { value, onChange } = this.props; const { value, onChange } = this.props;
onChange(value.set(index, newValue)); const parsedValue = (this.valueType === valueTypes.SINGLE) ? newValue.first() : newValue;
onChange(value.set(index, parsedValue));
}; };
} }
@ -86,10 +110,11 @@ export default class ListControl extends Component {
objectLabel(item) { objectLabel(item) {
const { field } = this.props; const { field } = this.props;
const fields = field.get('fields'); const multiFields = field.get('fields');
const first = fields.first(); const singleField = field.get('field');
const value = item.get(first.get('name')); const labelField = (multiFields && multiFields.first()) || singleField;
return value || `No ${ first.get('name') }`; const value = multiFields ? item.get(multiFields.first().get('name')) : singleField.get('label');
return value || `No ${ labelField.get('name') }`;
} }
handleSort = (obj) => { handleSort = (obj) => {
@ -145,7 +170,7 @@ export default class ListControl extends Component {
const { field } = this.props; const { field } = this.props;
const { value } = this.state; const { value } = this.state;
if (field.get('fields')) { if (field.get('field') || field.get('fields')) {
return this.renderListControl(); return this.renderListControl();
} }

View File

@ -16,7 +16,7 @@ export default class ObjectControl extends Component {
controlFor(field) { controlFor(field) {
const { onAddMedia, onRemoveMedia, getMedia, value, onChange } = this.props; const { onAddMedia, onRemoveMedia, getMedia, value, onChange } = this.props;
const widget = resolveWidget(field.get('widget') || 'string'); const widget = resolveWidget(field.get('widget') || 'string');
const fieldValue = value && value.get(field.get('name')); const fieldValue = value && Map.isMap(value) ? value.get(field.get('name')) : value;
return (<div className={controlStyles.widget} key={field.get('name')}> return (<div className={controlStyles.widget} key={field.get('name')}>
<div className={controlStyles.control} key={field.get('name')}> <div className={controlStyles.control} key={field.get('name')}>
@ -39,14 +39,17 @@ export default class ObjectControl extends Component {
render() { render() {
const { field } = this.props; const { field } = this.props;
const fields = field.get('fields'); const multiFields = field.get('fields');
const singleField = field.get('field');
if (!fields) { if (multiFields) {
return <h3>No fields defined for this widget</h3>; return (<div className={styles.root}>
{multiFields.map(field => this.controlFor(field))}
</div>);
} else if (singleField) {
return this.controlFor(singleField);
} }
return (<div className={styles.root}> return <h3>No field(s) defined for this widget</h3>;
{field.get('fields').map(field => this.controlFor(field))}
</div>);
} }
} }