Search code examples
javascriptreactjsreact-autocomplete

Render value for no matches found in react-autocomplete


I am using the react-autocomplete npm package to build the autocomplete functionality in my Reactjs app. So far I have been able to render dropdown items that match the user's input, as you see in the documentation of this package. However, I would like to generate a default text in the dropdown as No results found whenever user's input do not match any of the dropdown items. And to be honest I am really struggling with it.

I tried adding custom function to the shouldItemRender to change the state and dropdown items accordingly but it does not help either. Here is the snippet of my code -


const suggestions=  [{id: 100 , text:  "Aluminium extracts" }, {id: 101 , text:  "Copper extracts" }] 

<Autocomplete
    getItemValue={(item) => item.text}
    items={ suggestions }
    renderItem={(item, isHighlighted) => {
            return <div> {item.text} </div>)
        }
    }
    shouldItemRender={(item, value) => item.text.toLowerCase().indexOf(value.toLowerCase()) > -1}
    // shouldItemRender={(item, value) => handleRender(item, value) }
    value={value}
    onChange={(e, newValue) => { setValue(e.target.value) }}
    onSelect={(v) => handleInput(v)}
    inputProps={{ placeholder: "start typing"}}
/>

I will appreciate your help if you can help me accomplish this. Thank you.


Solution

  • Use renderMenu to check whether a match found or not. If there is no match found then show the No match found, if match found then return the items and renderItem will render the items list.

    <ReactAutocomplete
      items={[
        { id: "foo", label: "foo" },
        { id: "bar", label: "bar" },
        { id: "baz", label: "baz" },
      ]}
      shouldItemRender={(item, value) =>
        item.label.toLowerCase().indexOf(value.toLowerCase()) > -1
      }
      getItemValue={(item) => item.label}
      renderItem={(item, highlighted) => (
        <div
          key={item.id}
          style={{ backgroundColor: highlighted ? "#eee" : "transparent" }}
        >
          {item.label}
        </div>
      )}
      renderMenu={(items, value) => (
        <div>{items.length === 0 ? `No matches for ${value}` : items}</div>
      )}
      value={this.state.value}
      onChange={(e) => this.setState({ value: e.target.value })}
      onSelect={(value) => this.setState({ value })}
    />
    

    Check this link for better understanding. https://github.com/reactjs/react-autocomplete/blob/master/examples/custom-menu/app.js