Material UI React Autocomplete Component

I'm currently working on integrating an Autocomplete component using the Material UI library.

However, I've encountered a challenge - I'm unsure of how to properly pass the value and onChange functions, especially since I have a custom TextField implementation that also requires these parameters. Should I duplicate the value and onChange props for both Autocomplete and TextField components? Or is there a more efficient solution available? Any assistance would be greatly appreciated! Below is my code snippet:

import { Autocomplete as MuiAutocomplete } from '@material-ui/lab'
import { FormControl } from 'components/_helpers/FormControl'
import { useStyles } from 'components/Select/styles'
import { Props as TextFieldProps, TextField } from 'components/TextField'

export type Props = Omit<TextFieldProps, 'children'> & {
  options: Array<any>
  value: string
  onChange: (value: string) => void

  disabled?: boolean
}

export const Autocomplete = (props: Props) => {
  const classes = useStyles()

  return (
    <FormControl
      label={props.label}
      error={props.error}
      helperText={props.helperText}
    >
      <MuiAutocomplete
        options={props.options}
        // value={props.value}
        // onChange={event =>
        //   props.onChange((event.target as HTMLInputElement).value as string)
        // }
        classes={{
          option: classes.menuItem,
        }}
        disabled={props.disabled}
        getOptionLabel={option => option.label}
        renderInput={params => (
          <TextField
            {...params}
            placeholder={props.placeholder}
            value={props.value}
            onChange={props.onChange}
          />
        )}
        renderOption={option => {
          return <Typography>{option.label}</Typography>
        }}
      />
    </FormControl>
  )
}

Answer №1

If you're working with Material UI, there are handy props available to manage the state of Autocomplete compared to input values.

For a detailed look at these props in action, you can check out the documentation here: https://material-ui.com/components/autocomplete/#controllable-states

In your specific case, make sure to include the inputChange and onInputChange props when using the Autocomplete component. These will be passed down to your TextField through parameters provided to the renderInput function.

Your final code should resemble something along the lines of the snippet below taken from the linked documentation:

<Autocomplete
  value={value}
  onChange={(event, newValue) => {
    setValue(newValue);
  }}
  inputValue={inputValue}
  onInputChange={(event, newInputValue) => {
    setInputValue(newInputValue);
  }}
  id="controllable-states-demo"
  options={options}
  style={{ width: 300 }}
  renderInput={(params) => <TextField {...params} label="Controllable" variant="outlined" />}
/>

Answer №2

import React, { useEffect, useState } from "react";
import { Autocomplete } from "@mui/material/node";
import { Controller, useFormContext } from "react-hook-form";
import { TextField } from "@mui/material";
import PropTypes from "prop-types";

 const valueFunction = (array, identifier) => {
  const temporary = array.length > 0 && array?.find((element) => element.id === identifier);
  return temporary;
};

AutocompleteSearch.propTypes = {
  options: PropTypes.arrayOf({
    title: PropTypes.string,
    id: PropTypes.string,
  }),
  name: PropTypes.string,
};

export default function AutoCompleteSearch({
  name,
  options,
  label,
  id,
  ...other
}) {
  const [temporaryValue, setTemporaryValue] = useState({});
  const { control, setValue } = useFormContext();

  useEffect(async () => {
    const foundItem = valueFunction(options, id);
    await setTemporaryValue(foundItem);
  }, [options, id]);

  return (
    <Controller
      control={control}
      name={name}
      rules={{ required: true }}
      render={({ fieldState: { error } }) => (
        <>
          <div >
            <Autocomplete
              id="controllable-states-demo"
              onChange={(_, val) => {
                setValue(name, val?.id);
                setTemporaryValue(val);
              }}
              onBlur={(elem) => {
                elem.target.value == "" && setValue(name, "");
              }}
              value={temporaryValue}
              options={options}
              getOptionLabel={(item) => (item.title ? item.title : "")}
              renderInput={(parameters) => (
                <>
                  <TextField
                    {...parameters}
                    label={label}
                    InputLabelProps={{
                      style: {
                        fontSize: "14px",
                        fontWeight: "400",
                        color: "#FF5B00",
                      },
                    }}
                 
                    size="small"
                    error={temporaryValue === null && !!error}
                    helperText={temporaryValue === null && error?.message}
                    {...other}
                  />
                </>
              )}
            />
          </div>
        </>
      )}
    />
  );
}
 <AutoCompleteSearch
   name="pharmacy_group_title"
   label="Pharmacy Group" 
   options={pharmacyGroups}                           // Array  {id , title}   
   id={defaultValues?.pharmacy_group_title}           // ID
  />

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can a href from a "<Link>" component be passed through a Higher Order Component (HOC) into an "<a>" tag?

I am currently facing a situation with the main component where I have the following code: <Link href={'test'}> <PrimaryAnchor>Welcome</PrimaryAnchor> </Link> Within the PrimaryAnchor component, the code looks like ...

How come accessing the superclass's property with a getter in TypeScript is not working as expected?

class A { protected _value:number; get value() { return this._value; } } class B extends A { set value(v:number) { this._value = v; } } var b = new B(); b.value = 2; console.log(b.value);//undefined Coding Pla ...

I'm encountering an issue with VUEJS components including my show route in their get call. How can I make my journals/:id pages function properly without encountering a Mime

I encountered a MIME type error stating: Refused to apply style from 'http://localhost:8080/journals/assets/css/main.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled. ...

How can you use jQuery.ajax to solely fetch the status code without downloading the entire document?

My application relies on the use of jQuery.ajax to check if a particular resource exists by constantly polling it. Once the resource is no longer returning a 404 status code, the app redirects to view that resource. However, I am concerned about downloadin ...

The slideUp function is not functioning as expected

I am trying to implement a slideUp effect on my webpage. Here is the code within my <body> tag: <script> $('#slide_up').click(function(){ $('p.text_study').slideUp('slow', function() { $ ...

Revamp the button's visual presentation when it is in an active state

Currently, I'm facing a challenge with altering the visual appearance of a button. Specifically, I want to make it resemble an arrow protruding from it, indicating that it is the active button. The button in question is enclosed within a card componen ...

Is there a way to dynamically add or modify a JavaScript timestamp component after the webpage has finished loading?

Context: Utilizing the SailsJS framework to showcase the timestamp of data model updates. The framework, originating from 'parasails', leverages Vue.js and offers the <js-timestamp :at="1573487792252"> component to display elapsed time like ...

How can we implement the MUI snackbar to only show when a successful login occurs in ReactJS?

How can I display the material-ui snackbar in ReactJS only upon successful login? What approaches can be used to achieve this in ReactJS? ...

Client.on facing issue with receiving data upon initial connection

Currently, I am utilizing the net module in order to establish a connection between my client and server. Below is the code snippet: const Net = require('net'); client = Net.connect(parseInt(port), host, function() { co ...

Incorporating Paths into a React/Firebase Application

As I begin integrating React Routes into my React/firebase application, I encountered an issue while trying to read data. Here is the code snippet that initially allowed me to retrieve the data: const fb = firebase .initializeApp(config) .database() .re ...

Enhance user experience by implementing an interactive feature that displays

I have a form for adding recipes, where there is an ingredients button. Each recipe can have multiple ingredients. When the button is clicked, an input field for adding ingredients should appear below the ingredient button. What I've attempted so far ...

Search field in DataTables appears to be misaligned

I'm in the process of developing a small website using JSP and DataTables (currently only for the first table). Here's what I have so far: As you can observe, there seems to be an alignment issue with the search field position. I'm n ...

Utilizing Vue Router to leverage specific getters from Vuex

I am currently facing an issue with accessing the authenticated user in my Vuex store within my router.js file. { path: '/admin/login', name: 'admin-login', component: AdminLogin, beforeEnter(to, from, next) { console.log(s ...

Troubleshooting React-Redux: Button click not triggering action dispatch

I am facing an issue where my action is not being dispatched on button click. I have checked all the relevant files including action, reducer, root reducer, configStore, Index, and Component to find the problem. If anyone can help me troubleshoot why my a ...

Determine if a mobile application has been installed using Vue.js

I am currently developing a web application and have implemented a check to determine whether the user is accessing it from a mobile device or laptop. Let's consider the link as: my-site.com In addition to the web version, my site also offers a mobi ...

Issue encountered with Azure DevOps during TypeScript (TS) build due to a type mismatch error: 'false' being unable to be assigned to type 'Date'. Conversely, the build functions correctly when run locally, despite the type being defined as 'Date | boolean'

I am facing an issue with my NestJS API while trying to build it using Azure DevOps pipeline. The build fails with the following error: src/auth/auth.controller.ts(49,7): error TS2322: Type 'false' is not assignable to type 'Date'. src/ ...

The method continues to receive null values from Ajax despite successfully retrieving the data from Facebook

My current challenge involves creating a login using Facebook. The console indicates that the requested data (email, first_name, etc.) is being retrieved successfully, but for some reason, the AJAX request keeps sending null data to the PHP method. Below ...

Encountering error TS2307 while using gulp-typescript with requirejs and configuring multiple path aliases and packages

Currently, I am working on a substantial project that heavily relies on JavaScript. To enhance its functionality, I am considering incorporating TypeScript into the codebase. While things are running smoothly for the most part, I have encountered an issue ...

Leveraging passport-google-oauth in combination with react-native

I'm currently integrating passport-google-oauth into my react-native project. However, upon running the application, I encounter an error: requiring unknown module util. I have already used both npm install .. and npm install ... --save commands for p ...

Addressing an error of "call stack full" in nextjs

I am currently working on a project in nextjs where I need my billboard to continuously scroll to show different information. The Nextjs debugger keeps showing me an error message that says 'call stack full'. How can I resolve this issue? con ...