From f1e39d08e26cd0419cbeb9f308bea8fba4ec162b Mon Sep 17 00:00:00 2001 From: Bogdan Dimofte Date: Mon, 8 Oct 2018 12:31:02 +0300 Subject: [PATCH] vulcan-form-tags: refactor and fix: - fix suggestions (ReactTags accepts {id, text}) - fix updating the parent form (using `props.inputProperties.onChange`) - lighten state (only `tags` was needed) and streamline callbacks --- .../vulcan-forms-tags/lib/components/Tags.jsx | 96 ++++++------------- 1 file changed, 28 insertions(+), 68 deletions(-) diff --git a/packages/vulcan-forms-tags/lib/components/Tags.jsx b/packages/vulcan-forms-tags/lib/components/Tags.jsx index 635832806..c557e3c46 100644 --- a/packages/vulcan-forms-tags/lib/components/Tags.jsx +++ b/packages/vulcan-forms-tags/lib/components/Tags.jsx @@ -11,88 +11,39 @@ class Tags extends PureComponent { constructor(props) { super(props); - this.handleDelete = this.handleDelete.bind(this); - this.handleAddition = this.handleAddition.bind(this); - const tags = props.value ? props.value.map(optionId => { - return { - id: optionId, - text: _.findWhere(props.options, {value: optionId}).label - }; - }) : []; + this.suggestions = (props.options || []).map( + ({ value, label }) => ({ id: value, text: label }) + ); + const tags = (props.value || []).map(id => ( + // tolerate cases when a tag is not found in suggestions (create a tag on the fly) + this.suggestions.find(suggestion => id === suggestion.id) || { id, text: id } + )); - this.state = { - tags: tags, - suggestions: _.pluck(props.options, 'label'), - value: props.value || [] - }; + this.state = { tags }; } - handleDelete(i) { - - const tags = this.state.tags; - tags.splice(i, 1); - - const value = this.state.value; - value.splice(i,1); - - this.setState({ - tags: tags, - value: value - }); - } - - handleAddition(tag) { - - // first, check if added tag is part of the possible options - const option = _.findWhere(this.props.options, {label: tag}); - - if (option) { - - // add tag to state (for tag widget) - const tags = this.state.tags; - tags.push({ - id: tags.length + 1, - text: tag - }); - - // add value to state (to store in db) - const value = this.state.value; - value.push(option.value); - - this.setState({ - tags: tags, - value: value - }); - } - + handleChange = reducer => value => { + const tags = reducer(this.state.tags, value) + this.setState({ tags }); + this.props.inputProperties.onChange(this.props.name, tags.map(({ id }) => id)) } render() { - - const {name, /* value, */ label} = this.props; - return (
- +
[...tags.slice(0, index), ...tags.slice(index + 1)] + )} + handleAddition={this.handleChange((tags, newTag) => [...tags, newTag])} minQueryLength={1} - classNames={{ - // tags: 'tagsClass', - // tagInput: 'form-control' - // selected: 'selectedClass', - // tag: 'tagClass', - // remove: 'removeClass', - // suggestions: 'suggestionsClass' - }} /> -
@@ -103,7 +54,16 @@ class Tags extends PureComponent { Tags.propTypes = { name: PropTypes.string, value: PropTypes.any, - label: PropTypes.string + label: PropTypes.string, + inputProperties: PropTypes.shape({ + onChange: PropTypes.func, + }), + options: PropTypes.arrayOf( + PropTypes.shape({ + value: PropTypes.any, + label: PropTypes.string, + }) + ), }; export default Tags;