Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Material UI Autocomplete custom renderInput

I'm following various examples from https://material-ui.com/components/autocomplete/ to create a custom autocomplete. I'm trying to use the renderInput property to use a custom input component. All of the examples I find use the TextField component, but I'd like to use a regular input component.

Problem is, the options are never displayed. I've created a demonstration here (swap renderInput with renderInputWORKING to see working version):

https://codesandbox.io/s/epic-johnson-oxy7b?file=/src/App.tsx

with the following code in renderInput:

 const renderInput = (params: AutocompleteRenderInputParams) => {
    console.log(params);
    const { InputLabelProps, inputProps, InputProps } = params;
    return (
      <div>
        <label {...InputLabelProps}>foo</label>
        <input {...InputProps} {...inputProps} />
      </div>
    );
  };

How can I use the <input /> component for renderInput prop on <Autocomplete />?

like image 942
dǝɥɔS ʇoıןןƎ Avatar asked May 30 '20 23:05

dǝɥɔS ʇoıןןƎ


1 Answers

UPDATE

The 4.10.1 release of Material-UI (on June 1, 2020) included a new example in the documentation for this exact case: https://material-ui.com/components/autocomplete/#custom-input.

Pull request: https://github.com/mui-org/material-ui/pull/21257


The most useful example to look at in the documentation is the Customized Autocomplete example which uses InputBase instead of TextField. This example contains the following code for renderInput:

         renderInput={(params) => (
            <InputBase
              ref={params.InputProps.ref}
              inputProps={params.inputProps}
              autoFocus
              className={classes.inputBase}
            />
          )}

The InputProps passed to TextField are placed on a div that wraps the <input>, so most of those props are not appropriate to put directly on the <input> element as you were. In the code above from the documentation example, you can see that it only uses one thing from params.InputProps which is the ref. This ref is used for controlling the anchor element for the listbox of options. A ref is also placed on the <input> itself, but that ref is used for very different purposes. With your code, only one of those refs was getting used.

Below is a working example (based on the Combo Box example since your sandbox has a lot of other customizations that aren't directly related to this question) that uses <input> instead of TextField:

import React from "react";
import Autocomplete from "@material-ui/lab/Autocomplete";

export default function ComboBox() {
  return (
    <Autocomplete
      id="combo-box-demo"
      options={top100Films}
      getOptionLabel={option => option.title}
      style={{ width: 300 }}
      renderInput={params => (
        <div ref={params.InputProps.ref}>
          <label {...params.InputLabelProps}>My Label </label>
          <input {...params.inputProps} autoFocus />
        </div>
      )}
    />
  );
}

Edit Autocomplete using input instead of TextField

like image 53
Ryan Cogswell Avatar answered Nov 16 '22 03:11

Ryan Cogswell