Add valueKey to specify the returned prop of the object, used also to set the selected value.
Often you have {id, label} but the field value is just the id, so it would be convenient to set the selected value by id and receiving just the id onChange.
What do you think?
Just to make sure I understand, it sounds like you're saying you want something like this:
<Typeahead
onChange={id => {
// Do some stuff on change...
}}
options={[
{id: 1, label: 'First Item'}
{id: 2, label: 'Second Item'}
{id: 3, label: 'Third Item'}
{id: 4, label: 'Fourth Item'}
]}
selected={[1, 2]}
valueKey="id"
/>
I'm also not entirely sure what you mean by:
[B]ut the field value is just the id
Thank you, I meant exactly that.
When I say that "the field value is just the id" I mean that often, when you need an autocomplete field, you have:
So it is easier to pre-select just the id and not the complete option object and to have just the id in the onChange to set the field value (I use Redux form).
I'd like to help with a pull request, but unfortunately I really cannot in these days.
Let me know if you are too busy, too. Maybe I could have a quick look this weekend and see if it easy :)
This is a crucial feature for anyone who needs to select data based on a displayed value but store a value in a database based on an ID. I was about to try to migrate my custom hacked typeahead component to use this but realized it's not possible until this feature is added.
I don't have much time at the moment either, but I'd expect it wouldn't be too hard to add it for someone familiar with the codebase. Has then been looked into yet? Thanks.
I agree that this kind of thing would be useful in certain cases. My main question/concern here is whether the functionality actually belongs as part of the core component as opposed to a util that lives outside of it. Could one or both of you post examples of your data? Useful things to know:
Maybe I'm confused since I haven't used your component yet, but I was thinking it would be a direct correlation to how the labelKey props works. valueKey would allow the user to specify which attribute of a given object holds the data that would be returned as the selected value of the input (just as labelKey specifies which attribute holds the data used for display).
If there is another easy way to handle something like that I'm open to suggestions.
An example of your data would be helpful so that we're talking about the same thing. That said, it's pretty trivial to use Underscore's pluck or Lodash's map to get just the values you want:
<Typeahead
multiple
onChange={selected => {
// Using Lodash's `map` function...
const ids = _.map(selected, 'id'); // Produces something like `[1, 4]`
// Do something with the array of ids...
}}
options={[
{id: 1, label: 'First Item'}
{id: 2, label: 'Second Item'}
{id: 3, label: 'Third Item'}
{id: 4, label: 'Fourth Item'}
]}
/>
I'm struggling a bit with the documentation so I'm sorry if I'm missing something basic. Most of my inputs are going to be controlled inputs tied to redux state. How would it work in a scenario like that? Also, at the moment I'm only using single selections (no multiple selected values).
If I still can't figure it out after your response then I'll try to put a repo together demonstrating what I'm looking for. Thanks.
Code examples would be really helpful to understand your issue :)
I'm up against a deadline so it may take a bit to put up a full code example. However, I have done some testing and I believe the bottom line where I have an issue is that the selected prop has to be both an array and contain the full object.
For scenarios where one loads data from a database and has ID fields in one table that map to lookup tables (such as storing a user_id in an items table and looking up the user_name from a users table) it is going to be common to only have the ID value when initially loading the page and populating a form. At least for me, part of the niceness of using a typeahead (the way I have things with my current implementation) is that I can just pass that ID field as the value of the typeahead (along with which attribute is the value key) and it will "just work" to display one piece of information (like a user_name) while having a different value (like the user_id). With the current implementation it appears I would have to do a lookup in the options data manually every time the typeahead is initially rendered in order to extract the full matched object, and then also pull out the ID from the selection when needing to save a change to a database.
I'll try to eventually get a repo to demonstrate precisely what I'm talking about, but in short I would love a mode (maybe even only for single select) where the selected value could be passed in as a simple string/numeric value along with a valueKey, and this would be enough to have the typeahead properly choose the right data to display based on the passed options. Doing things that way would make the binding of data much more intuitive in my opinion.
I would also like this option. What I'm trying to do is extract my search item's Id from state, but I can't accurately predict it.
a simple valueKey="id" makes total sense. I would even expect it as the default, really.
This has my vote!
Such a functionality would be helpful, but in the meantime it is easy to achieve the goal using onChange approach proposed by @ericgio. After fetching array of ids from database you can map that ids before assigning to "selected" property of Typeahed using this approach:
const options = [
{id: 1, label: 'A'},
{id: 2, label: 'B'},
{id: 3, label: 'C'},
{id: 4, label: 'D'},
{id: 5, label: 'E'},
]
const fetched = [1,3,5]
const selected = options.filter(item => _.find(fetched, id => id === item.id))
For those like me who came looking for a notion of value identity in this widget:
This control's state strategy uses record values rather than identity values because in the nature of a typeahead component, the selected value may not actually appear in the option list. So it is not enough to have an identity value (e.g. ID) in selection state, as that has no label and the option may not be loaded.
I was looking for exactly this and it can now be achieved using labelKey
So the above example will become:
<Typeahead
onChange={ option => {
const id = option[ 0 ].id;
// Do some stuff on change...
}}
options={[
{id: 1, label: 'First Item'}
{id: 2, label: 'Second Item'}
{id: 3, label: 'Third Item'}
{id: 4, label: 'Fourth Item'}
]}
labelKey={ (option) => option.label }
/>
I'm sure this would be convenient for some people, but given that the workaround (if you even want to call it that) is a one-liner, it's just not a compelling feature. Closing.
Can I just add to this - I can't get this package working correctly with redux-form. I'm using the AsyncTypeahead and I have it working to the point where the values received by redux-form include the selected label value.
This is no real use to me when the labels may be duplicated, I need the actual id returning. It sounds like this request would solve that.
Can I just add to this - I can't get this package working correctly with redux-form. I'm using the AsyncTypeahead and I have it working to the point where the values received by redux-form include the selected label value.
This is no real use to me when the labels may be duplicated, I need the actual id returning. It sounds like this request would solve that.
This is a valid request
@metadan: I'm not familiar enough with redux-form to comment on how it interacts with the typeahead. If you can provide an example, I might be able to suggest something. Specific compatibility with 3rd-party libraries (other than Bootstrap itself) is out of of scope for this library, though I've made an effort to provide enough flexibility in the API so that I believe it should work well with most packages.
Most helpful comment
a simple
valueKey="id"makes total sense. I would even expect it as the default, really.This has my vote!