Search code examples
reactjstypescriptantdant-design-pro

Ant Design- autocomplete need to not show value


I need some help in either clearing the auto complete place holder after the user selects from drop down list or better display part of the label not the value. Currently its showing Value. Because Value is coming out to be a unique Id, we dont want that to be seen by the end user. This is the URL for the sample I am following https://ant.design/components/auto-complete/

Here is my code

import React, { useState } from "react";
import { Input, AutoComplete } from "antd";
import { SelectProps } from "antd/es/select";


const SearchBar: React.FC<> = () => {
    const [options, setOptions] = useState<SelectProps<unknown>["options"]>([]);
  
    const handleSearch = async (value: string) => {
      setOptions(
        value ? await searchResults() : []
      );
    };
  
    const onSelect = (value: string) => {
      console.log (value)
    };
return (
    <AutoComplete
          dropdownMatchSelectWidth={300}
          style={{ width: 350 }}
          options={options}
          onSelect={onSelect}
          onSearch={handleSearch}
        >
          <Input.Search
            size="large"
            placeholder="Search By name"
            enterButton
          />
        </AutoComplete>
     );
    };
    export default SearchBar;

Object that is coming back from searchResults is in this form. { value: string, label: JSX.Element }

And this is how the return is forming

const searchResults = async () => {
    return {
        value: id,
        label: DisplayElement (query, Title, info),
      };
    }

    const DisplayElement = (query: string, Title: string, info: string) => {
      return (
        <>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
            }}
          >
            <span>
              <a>{Title}</a>
            </span>
          </div>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
            }}
          >
            <span>{info}</span>
          </div>
        </>
      );
    };

After the user selects from drop down, its leaving the search bar like this. This is the value. I would like to either clear it or Only show a substring of the label, preferably Title of the label on this line {Title}.

enter image description here

-------------- Update 1------------- This is the error I am getting on <AutoComplete onSelect={onSelect} Line

(JSX attribute) onSelect?: ((value: string, option: OptionData | OptionGroupData) => void) | undefined Type '(value: string, options: { key: any;}) => void' is not assignable to type '(value: string, option: OptionData | OptionGroupData) => void'. Types of parameters 'options' and 'option' are incompatible. Type 'OptionData | OptionGroupData' is not assignable to type '{ key: any; }'. Type 'OptionData' is not assignable to type '{ key: any; }'. Property 'key' is optional in type 'OptionData' but required in type '{ key: any; }'.ts(2322) generate.d.ts(80, 5): The expected type comes from property 'onSelect' which is declared here on type 'IntrinsicAttributes & AutoCompleteProps & RefAttributes<Select>'

const onSelect = (value: string, options: { key: any }) => {
    console.log(options.key);
    console.log(value);
    props.parentCallback(options.key);
  };

  return (
    <AutoComplete
      dropdownMatchSelectWidth={300}
      style={{ width: 350 }}
      options={options}
      onSelect={onSelect}  // error on first OnSelect
      onSearch={handleSearch}
    >

Posting screenshot of the error. enter image description here

------Update 2 enter image description here

enter image description here


Solution

  • If it was a select, you could use optionLabelProp to change the displayed prop. (link)

    But in autocomplete, you can't change the displayed property. But, you can adopt with it. change the value: id to key: id and set the value to Title.

    const searchResults = async query => {
      return [
        {
          key: id,
          value: Title,
          label: DisplayElement(query, Title, info)
        }
      ];
    };
    

    then you can access the key (the id) in onSelect like this:

    const onSelect = (value, option) => {
      // you don't want the value, instead you want the key.
      console.log(option.key);
    };
    

    This way you display the right value to user, and also you can access the id when user selects it.