Maybe I'm missing something, but I can't seem to find it anywhere in the docs. When using multi select, the onChange handler only returns the new array of items. There is no way to tell which option was added or removed.
Is there any handler that can tell me which option was removed and which option was added instead of a complete array of currently selected options?
yeah, this library is incredible, but i found this design decision difficult to understand
I'm just using a simple diff function onChange for now.
Here's a snippet of my solution. I just picked this library up today, so it's likely this isn't the optimal way to do this, but I'm procrastinating atm, so what the hell. Note a few caveats for my use case:
Creatable, I've assigned the handler to onNewOptionClick as welloptions as an array of objects, I've just used the simpleValue option so that my onChange handler receives a comma-delimited string instead of an array of objects. Unnecessary for an example this trivial, but on larger arrays, I imagine this might make a difference.This works for my use case, but given how customizable this component is, I doubt it's copy-pasta for everyone.
// these two props are passed in from above
const allTags = [
{ value: 'one', label: 'Fake Tag' },
{ value: 'two', label: 'Fake Tag2' },
{ value: 'three', label: 'Fake Tag3' },
{ value: 'four', label: 'Fake Tag4' },
]
const currentTags = ['one', 'two']
const AddTagDealy = (props) => {
const _onChange = (newTags) => {
const { currentTags } = props
// split on whatever your delimiter is
const newTagsArray = newTags.split(',')
// is this a tag addition or deletion? find which array is longer to find out
const isDeletion = newTagsArray.length < currentTags.length
// note brackets are just es6 array destructuring
const [ alteredValue ] = isDeletion ?
// if deletion
currentTags.filter(tag => !newTagsArray.includes(tag))
// if addition
: newTagsArray.filter(tag => !currentTags.includes(tag))
console.log('CHANGED VALUE', alteredValue, "Was it a deletion?", isDeletion)
}
const { allTags, currentTags } = props
return (
<Select.Creatable
name='form-field-name'
value={currentTags}
multi
backspaceRemoves={false}
deleteRemoves={false}
clearable={false}
simpleValue
onNewOptionClick={_onChange}
options={allTags}
onChange={_onChange}
/>
)
}
So if user clicks to delete 'Fake Tag2', the console logs two, and true
If they add the custom value 'Fake Tag99', the console logs 'Fake Tag99' and false
It's a bit inconsistent, because clicking an item gets you the value, while custom creations get you what amounts to the label, but afaik it's the only way.
Did the same as @brandonmp.
I've a list of item already selected for my item. In the onChange function of the Select i do this:
if(this.state.myItemSelectedValues.length > onChangeNewVal)this.state.myItemSelectedValues arrayonChangeNewVal array does not include my this.state.myItemSelectedValues[i] (use .includes() function), I unshift or push it in my available options arrayThanks for the tip. Had this same problem.
Faced the same issues, hope it will help someone
import 'difference' from 'lodash/difference'
this.currentTags = []
handleChange = (options) => {
const optionsValue = options.map(({ value }) => value)
if (this.currentTags.length < options.length) {
const addedElement = difference(optionsValue, this.currentTags)[0]
this.currentTags.push(addedElement)
console.log("addedElement",addedElement)
//call custom add event here
}
else {
let removedElement = difference(this.currentTags, optionsValue)[0]
console.log("removedElement", removedElement)
// call custom removed event here
let index = this.currentTags.indexOf(removedElement)
if (index !== -1) {
this.currentTags.splice(index, 1)
}
}
}
The file difference what does he contain??
Hello -
In an effort to sustain the react-select project going forward, we're closing old issues.
We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our efforts towards the current major version.
If you aren't using the latest version of react-select please consider upgrading to see if it resolves any issues you're having.
However, if you feel this issue is still relevant and you'd like us to review it - please leave a comment and we'll do our best to get back to you!
Most helpful comment
yeah, this library is incredible, but i found this design decision difficult to understand
I'm just using a simple diff function
onChangefor now.Here's a snippet of my solution. I just picked this library up today, so it's likely this isn't the optimal way to do this, but I'm procrastinating atm, so what the hell. Note a few caveats for my use case:
Creatable, I've assigned the handler toonNewOptionClickas welloptionsas an array ofobjects, I've just used thesimpleValueoption so that myonChangehandler receives a comma-delimited string instead of an array of objects. Unnecessary for an example this trivial, but on larger arrays, I imagine this might make a difference.This works for my use case, but given how customizable this component is, I doubt it's copy-pasta for everyone.
So if user clicks to delete 'Fake Tag2', the console logs
two, andtrueIf they add the custom value 'Fake Tag99', the console logs
'Fake Tag99'andfalseIt's a bit inconsistent, because clicking an item gets you the
value, while custom creations get you what amounts to thelabel, but afaik it's the only way.