Mani
Mani

Reputation: 2563

Async Autocomplete does not show options when label keys are different from filtering keys

I'm not new to ReactJs or Material UI but this one really struck to me as surprise. So I'm using Material-UI Autocomplete like below. users is array of object as shown below. So when I match firstName or lastName from user table, options are rendered correctly. But if I try to search via email in the table options does not render on focus. Though I'm sure that emails were matched and users were return. Now if I change getOptionLabel={(option) => option.firstName + ' ' + option.lastName } to getOptionLabel={(option) => option.email } it renders via email but search no longer works for firstName or lastName. So, my question is how can I bypass this behaviour of autocomplete where I can pass any array and autocomplete still show firstName and lastName keys

users array of object

[
  {_id: 1, firstName: 'f1abc', lastName: 'l1abc', email: '[email protected]'},
  {_id: 2, firstName: 'f2abc', lastName: 'l2abc', email: '[email protected]'},
  {_id: 3, firstName: 'f3abc', lastName: 'l3abc', email: '[email protected]'},
]

<Autocomplete
    options={users}
    onChange={onChange}
    getOptionLabel={(option) => option.firstName + ' ' + option.lastName }
    getOptionSelected={(option, value) => option._id === value._id}
    value={selectedPatients}
    renderInput={(params) => (
      <TextField
        {...params}
        placeholder='Select Patient'
        onChange={handleChange}
        variant='standard'
      />
    )}
/>

Upvotes: 0

Views: 548

Answers (1)

Giovanni Esposito
Giovanni Esposito

Reputation: 11176

If you want to show firstName + lastName in dropdown but you want to filter on firstName + lastName + email you could use Autocomplete's createFilterOptions in this way:

import Autocomplete, { createFilterOptions } from "@material-ui/lab/Autocomplete";

const filterOptions = createFilterOptions({
   matchFrom: "any",
   stringify: (option: UserTypeType) => option.firstName + option.lastName + option.email
});

interface UserTypeType {
  _id: number;
  firstName: string;
  lastName: string;
  email: string;
}

...

<Autocomplete
    options={users}
    onChange={onChange}
    getOptionLabel={(option) => option.firstName + ' ' + option.lastName }
    getOptionSelected={(option, value) => option._id === value._id}
    filterOptions={filterOptions}  //<-- here pass filterOptions to Autocomplete
    value={selectedPatients}
    renderInput={(params) => (
      <TextField
        {...params}
        placeholder='Select Patient'
        onChange={handleChange}
        variant='standard'
      />
    )}
/>

Here a working example.

Upvotes: 2

Related Questions