-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Autocomplete] Add getOptionSelected prop #18443
Comments
@miguelbalboa I'm not sure that |
What's wrong with? <Autocomplete
value={role}
options={optionsProp}
filterOptions={(options, state) => {
/*
* Custom function returns a transformed array of options with the format:
* [{item: {id: 1, name: "The Role"}, matches: []}]
*/
return myCustomFuse.search(options, state.inputValue).map(x => {
x.item.matches = x.matches
return x.item
})
}}
/> |
Hi @oliviertassinari, yes, returning a different structure will impact Coming back to the initial proposal about exposing const RoleSelect = () => {
// Value will come from different source with a pre-populated initial value.
const [role, setRole] = useState({
id: 2,
name: "Second Role"
});
// Options are in different source
const [roles, setRoles] = useState([
{id: 1, name: "My Role"},
{id: 2, name: "Second Role"}
]);
// Because role is a different Object that roles[1], the selected option will not be highlighted.
return (
<Autocomplete
value={role}
options={roles}
getOptionLabel={role => role.name}
onChange={(event, newValue) => {
setRole(newValue);
}}
renderInput={params => (
<TextField {...params} label="Role select" fullWidth />
)}
/>
);
}; That is why I thought about providing a way to specifically do |
@miguelbalboa This is interesting, they are ways to work around the problem, but it seems valid but a |
Great! I will work in the pull request. |
+1. Also need this feature, because in my case value object and any of options objects cannot be simply compared, i need some way to compare value.id with option.id, maybe need some getOptionValue prop as in react-select |
We have a use case in the documentation for this method: http://material-ui.com/components/autocomplete#asynchronous-requests. The options are fetched from the network, they don't match with a previously selected value. |
Any news about this the PR from this issue ? |
@florleb Do you want to give it a shot? |
I wish i could if i was better :/. What should i do ? |
Hello @florleb are you working on it? |
Regarding the changes, I think that it could go with something in this order: diff --git a/docs/src/pages/components/autocomplete/Asynchronous.tsx b/docs/src/pages/components/autocomplete/Asynchronous.tsx
index acd873074..fb9c2d4b5 100644
--- a/docs/src/pages/components/autocomplete/Asynchronous.tsx
+++ b/docs/src/pages/components/autocomplete/Asynchronous.tsx
@@ -59,6 +59,7 @@ export default function Asynchronous() {
onClose={() => {
setOpen(false);
}}
+ getOptionSelected={(option, value) => option.name === value.name}
getOptionLabel={option => option.name}
options={options}
loading={loading}
diff --git a/packages/material-ui-lab/src/Autocomplete/Autocomplete.js b/packages/material-ui-lab/src/Autocomplete/Autocomplete.js
index b3f87c525..f7fa6cae7 100644
--- a/packages/material-ui-lab/src/Autocomplete/Autocomplete.js
+++ b/packages/material-ui-lab/src/Autocomplete/Autocomplete.js
@@ -204,6 +204,7 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) {
freeSolo = false,
getOptionDisabled,
getOptionLabel = x => x,
+ getOptionSelected,
groupBy,
id: idProp,
includeInputInList = false,
diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.d.ts b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.d.ts
index d67795e0b..310167c6c 100644
--- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.d.ts
+++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.d.ts
@@ -90,6 +90,11 @@ export interface UseAutocompleteProps {
* It's used to fill the input (and the list box options if `renderOption` is not provided).
*/
getOptionLabel?: (option: any) => string;
+ /**
+ * Used to determine if an option is selected.
+ * Uses strict equality by default.
+ */
+ getOptionSelected?: (option: any, value: any) => boolean;
/**
* If provided, the options will be grouped under the returned string.
* The groupBy value is also used as the text for group headings when `renderGroup` is not provided.
diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
index a8fd29e1a..bda4a6720 100644
--- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
+++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
@@ -83,6 +83,7 @@ export default function useAutocomplete(props) {
freeSolo = false,
getOptionDisabled,
getOptionLabel = x => x,
+ getOptionSelected = (option, value) => option === value,
groupBy,
id: idProp,
includeInputInList = false,
@@ -239,7 +240,9 @@ export default function useAutocomplete(props) {
options.filter(option => {
if (
filterSelectedOptions &&
- (multiple ? value.indexOf(option) !== -1 : value === option)
+ (multiple ? value : [value]).some(
+ value2 => value2 !== null && getOptionSelected(option, value2),
+ )
) {
return false;
}
@@ -791,7 +794,9 @@ export default function useAutocomplete(props) {
},
}),
getOptionProps: ({ index, option }) => {
- const selected = multiple ? value.indexOf(option) !== -1 : value === option;
+ const selected = (multiple ? value : [value]).some(
+ value2 => value2 != null && getOptionSelected(option, value2),
+ );
const disabled = getOptionDisabled ? getOptionDisabled(option) : false;
return { |
Well finally i don't use defaultValue but i use value instead and it doesnt seems to have the problem anymore. |
Hi @oliviertassinari i opened up this issue #18499 I was going to make a pr for this but not sure if that's needs or not. since i would need to loop through the selectedValue in renderOption
as long as i have value not sure adding another props getOptionSelected would help anyway. However, if value can be return in the renderOption alongwith selected and inputValue should suffice this use case right now, it only returning
adding value to the above function should give some flexibility to show the selected option Just a thought, lemme know if that makes sense |
@DarkKnight1992 We have a use case in the demo, where we fetch new options from the API each time the autocomplete popup is displayed. Without this In your case, it wouldn't be enough. The autocomplete relies on the |
makes sense, thanks. Will send pr soon with getOptionSelected |
the figured out the issue but not sure how should fix them another prop maybe ? not sure
so selecting and deselecting also relies on reference |
@DarkKnight1992 Interesting, I think that we can use an IE 11 compatible version of |
@oliviertassinari Lemme know if i am doing anything wrong here. |
@DarkKnight1992 You can use findIndex with getOptionSelected. |
@oliviertassinari
i am working on codesandox liveview, do you want to take a look into that ? |
@DarkKnight1992 If you want, you can open a draft pull request, and I will have a look. |
@oliviertassinari draft pull requested #18695 |
You guys are awesome! |
Hi! Can i use default selected prop from string, if i use async autocomplete? |
@Legilimens Yes. |
Could you give an example, please? I tried to do this, but could not. I found exapmple how use default value for some option value, but i not found how i can use any string for default value |
I can't here, please ask on StackOverflow. |
For the same reasons, this property (getOptionSelected) should be added to the <Select> component. What do you think @DarkKnight1992 ? |
@JuanmaMenendez select already works if you provide a primitive value |
Yes but I need to provide and select an object, not a primitive value. |
@oliviertassinari is that's possible ? |
@DarkKnight1992 It's supported but discouraged with the non-native select. It's not supported by the native select. |
@oliviertassinari thanks for your answer, can you please give us a link about the use of getOptionSelected in a Select component, I don't see anything in the docs https://material-ui.com/api/select/ |
I have a warning when using this prop, not sure if there's anything I can do about it:
|
@zeljkocurcic Upgrade to the latest version. |
Latest version of what? I have the latest version of Autocomplete that I see published and the newest versions of React and React DOM. |
I get the same warning using
Also, i can import Autocomplete from both lab and core. I don't know if this is on purpose? |
Summary 💡
To bring more flexibility to the Autocomplete component, It will be great to be able customize the behavior on when an option should be selected by exposing a getOptionSelected prop similar to getOptionDisabled.
Examples 🌈
Motivation 🔦
Currently I'm trying to use https://fusejs.io/ in the prop
filterOptions
to filter the options, but fuseJs wraps the options on another object, a simple comparison as in here won't work. also I think addinggetOptionSelected
will allow to compare by id if is wishedvalue.id === option.id
. Let me know your thoughts and if you have a better way to accomplish what I'm trying to do, thanks!The text was updated successfully, but these errors were encountered: