3

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

Sarah
  • 1,199
  • 2
  • 21
  • 42

1 Answers1

5

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.

yaya
  • 7,675
  • 1
  • 39
  • 38
  • @Sarah no problem, here is my full code : https://github.com/ya3ya6/ReactPlay1/blob/stack/src/stackoverflow_play/q4_antd_autocomplete.js also also note that for questions like this, you should add `antd` tag, since it's the main tag for this question. `ant-design-pro` has only 49 watchers, but `antd` has 468 watchers. by using non-popular tags, you'll decrease your chance to get an answer. – yaya Aug 05 '20 at 00:52
  • Thank you so very much.. Yes this is my first time posting, I was struggling with picking the right tags, thank you so much for mentioning that. I will keep that in mind. So I updated the code and it seems to be working but I am getting a red squiggle line under my onSelect. Updating the code under update1 for you to check please. Not sure how to resolve that. – Sarah Aug 05 '20 at 01:12
  • @Sarah no problem. you mean compiler/eslint warnings? can you post a snapshot? – yaya Aug 05 '20 at 01:17
  • Posted the entire error above in my original post under update1. – Sarah Aug 05 '20 at 01:19
  • Also I noticed that you are using a param name "option" here.. const onSelect = (value, option) => { Is that different from const [options, setOptions] = useState["options"]>([]); Or did you mean to write "options" – Sarah Aug 05 '20 at 01:20
  • @Sarah options is a parameter that ant-design will send to onclick handler. `onSelect` means that user selected an option, so ant-design will give you the option object that user clicked on it (selected it). `options` in state is the `options` that auto complete will provide the user. so they are kind of related. (options are the all options, option passed param is the selected option.) – yaya Aug 05 '20 at 01:25
  • @Sarah and probably the problem is that you used the wrong type for option. i think the type of option parameter is : `OptionData | OptionGroupData` and you specified it wrongly to `{ key: any;}`. that's what the error says. – yaya Aug 05 '20 at 01:30
  • Oh ok so "option" param can just be named anything like maybe uniqueId like this const onSelect = (value: string, UniqueId: { key: string }) => { props.parentCallback(UniqueId.key); }; – Sarah Aug 05 '20 at 01:35
  • @Sarah yes you can just rename it (however you named it worse (it's an object containings all info about the selected option, not only unique id.). also its type is not `{ key: string }`. – yaya Aug 05 '20 at 01:38
  • Gotcha! That makes sense, ok I updated the code with more meaningful name. However I dont know what type I need to give it. .const onSelect = (value: string, SelectedObject) => { – Sarah Aug 05 '20 at 01:43
  • @Sarah try `SelectedObject: OptionData | OptionGroupData` . – yaya Aug 05 '20 at 01:44
  • Thanks so much yaya.. Here is the screenshot of the error. Humm.. I am trying to paste it here but its not allowing me.. Posting it up on the original post. – Sarah Aug 05 '20 at 01:47
  • @Sarah put the cursor at the end of OptionData, and then press control+space. it will recommend you some sources of it to import. it's: `import { OptionData, OptionGroupData } from "rc-select/lib/interface";` – yaya Aug 05 '20 at 01:51
  • Says no recommendations. Posting the screenshot. Thanks for much for helping here. Do I need to install any libraries? – Sarah Aug 05 '20 at 02:01
  • 2
    @Sarah no problem. i'm not good at `typescript`. does `import { OptionData, OptionGroupData } from "rc-select/lib/interface";` works? – yaya Aug 05 '20 at 02:07
  • So seems like that worked, So why did control+space not work for me and how would I know that I need that library for those two data types? What is rc-select interface library? – Sarah Aug 05 '20 at 02:29
  • 1
    @Sarah well that's completely another issue (`control + space` doesn't suggest typescript packages.). i think it's because i installed some extenstions like `visual tudio intellisense`. you can ask another question for it cause i'm not good at `typescript`. – yaya Aug 05 '20 at 02:51
  • 1
    Gotcha!. I will look that up. Thank you so very much for helping me figure this issue out. Really appreciate that. if i could give 100 thumbs up :) – Sarah Aug 05 '20 at 03:02
  • @Sarah no problem. happy coding. – yaya Aug 05 '20 at 03:07
  • one more question @yaya .. once the key is used, is there a way to clear the search bar? – Sarah Aug 07 '20 at 00:47
  • 1
    @Sarah not sure, why not posting a new question for it and hopefully it'll get answered, cause it seems a separate question. – yaya Aug 07 '20 at 06:52