React – Filtering Cards based on Selected Value from Autocomplete

I have a React application where I’m using Material-UI’s Autocomplete component to filter a cards based on a selected brand. The cards represent different car models, and I want to filter them when a user selects a brand from the Autocomplete dropdown.

Here’s the appropriate code:

The filter:


import * as React from 'react';
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';

const top100Cars = [
  { label: 'Toyota' },
  { label: 'Ford' },
  { label: 'Chevrolet' },
  { label: 'Tesla' },
  { label: 'Honda' },
  { label: 'BMW' },
  { label: 'Audi' },
  { label: 'Mercedes-Benz' },
  { label: 'Ferrari' },
  { label: 'Porsche' },
  { label: 'Lamborghini' },
  { label: 'Nissan' },
  { label: 'Volkswagen' },
  { label: 'Mazda' },
  { label: 'DeLorean' },
  { label: 'Dodge' },
];


export default function searchBar() {

  const [selectedBrand, setSelectedBrand] = React.useState(null);

  return (
    <Autocomplete
      disablePortal
      id="combo-box-demo"
      options={top100Cars}
      value={selectedBrand}
      onChange={(event, newValue) => {
        setSelectedBrand(newValue);
      }}
      sx={{
        width: 254, backgroundColor: 'white', borderRadius: 50,
      }}
      renderInput={(params) => (
        <TextField
          {...params}
          label="Марка"
          size='small'
        />
      )}
    />
  );
}

The code of one of the cards:

import * as React from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { styled } from '@mui/material/styles';
import Card from '@mui/material/Card';
import CardHeader from '@mui/material/CardHeader';
import CardMedia from '@mui/material/CardMedia';
import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';
import FormGroup from '@mui/material/FormGroup';
import IconButton, { IconButtonProps } from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import Rating from '@mui/material/Rating';
import Grid from '@mui/material/Grid';
import Button from '@mui/material/Button';
import LocationOnIcon from './SVGiCON';

type ExpandMoreProps = IconButtonProps & {
  expand: boolean;
};

const ExpandMore = styled((props: ExpandMoreProps) => {
  const { expand, ...other } = props;

  const label = { inputProps: { 'aria-label': 'Checkbox demo' } };

  return <IconButton {...other} />;
})(({ theme, expand }) => ({
  transform: !expand ? 'rotate(0deg)' : 'rotate(180deg)',
  marginLeft: 'auto',
  transition: theme.transitions.create('transform', {
    duration: theme.transitions.duration.shortest,
  }),
}));

type RecipeReviewCardProps = {
  to: string; // Specify the destination when the button is clicked
  // Add any additional props you may need
};

export const RecipeReviewCard: React.FC<RecipeReviewCardProps> = ({ to }) => {
  const [expanded, setExpanded] = React.useState(false);
  const navigate = useNavigate();

  const handleExpandClick = () => {
    setExpanded(!expanded);
  };
  const [state, setState] = React.useState({
    gilad: false,
    jason: false,
    antoine: false,
  });

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setState({
      ...state,
      [event.target.name]: event.target.checked,
    });
  };

  const { gilad, jason, antoine } = state;

  const [value, setValue] = React.useState<number | null>(2);

  const handleButtonClick = () => {
    navigate(to);
  };

  return (
    <Card style={{
      width: '312px', height: '285px', backgroundColor: "gray",
    }}>
      <CardHeader
        title="Ауди, А4"
        subheader="София, София-град"
        // titleTypographyProps={{
        //   fontSize: 22,
        // }}
        subheaderTypographyProps={{
          color: "white",
        }}
        style={{
          textAlign: 'center', fontSize: '1px', marginBottom: '-10px', marginTop: '-9px', color: "white",
        }}
      />
      <Grid container>
        <Grid item xs={6}>
          {/* Adjust the width and height of the image as needed */}
          <CardMedia
            component="img"
            height="84.28px"
            image="https://images.pexels.com/photos/244212/pexels-photo-244212.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
            style={{ marginLeft: '10px' }}
          />
        </Grid>
        <Grid item
          xs={6}
          sx={{
            width: '43px', top: '6px', left: '245px', height: '17px', // Set the width to 100% or adjust as needed
          }}>
          <Typography style={{
            display: 'flex', alignItems: 'center', marginLeft: '20px', fontSize: '14px', color: "white",
          }}>
            <LocationOnIcon style={{ marginRight: '10px', width: '15px', height: '15px' }} />
            Дизел
          </Typography>
          <Typography style={{
            display: 'flex', alignItems: 'center', marginLeft: '20px', fontSize: '14px', color: "white",
          }}>
            <LocationOnIcon style={{ marginRight: '10px', width: '15px', height: '15px' }} />
            Бял
          </Typography>
          <Typography style={{
            display: 'flex', alignItems: 'center', marginLeft: '20px', fontSize: '14px', color: "white",
          }}>
            <LocationOnIcon style={{ marginRight: '10px', width: '15px', height: '15px' }} />
            2013 г.
          </Typography>
          <Typography style={{
            display: 'flex', alignItems: 'center', marginLeft: '20px', fontSize: '14px', color: "white",
          }}>
            <LocationOnIcon style={{
              marginRight: '10px', width: '15px', height: '15px', color: "white",
            }} />
            290 000 км
          </Typography>
        </Grid>
      </Grid>

      <FormGroup style={{ marginLeft: '10px', marginTop: '11px' }}>
        <FormControlLabel
          style={{ marginBottom: '-10px', color: "white" }}
          control={
            <Checkbox
              checked={gilad}
              onChange={handleChange}
              name="gilad"
              size='small'
              style={{ color: 'white' }} />
          }
          label="Реален пробег"
        />
        <FormControlLabel
          style={{ color: "white" }}
          control={
            <Checkbox checked={jason}
              onChange={handleChange}
              name="jason"
              size='small'
              style={{ color: 'white' }} />
          }
          label="Първи собственик"
        />
      </FormGroup>
      <Typography
        component="legend"
        style={{ marginLeft: "8px", fontSize: '13px', color: "white" }}
      >Рейтинг
      </Typography>

      <Grid container>
        <Grid item xs={12} style={{ marginLeft: '8px', display: 'flex', alignItems: 'center' }}>
          <Rating name="read-only" value={value} readOnly size="small" />
          <Link to={to}>
            <Button
              variant="contained"
              color="success"
              style={{
                marginLeft: '88px',
                width: '103px',
                height: '24px',
                fontSize: '10px',
                borderRadius: '50px',
              }}
              onClick={handleButtonClick}
            >
              Виж повече
            </Button>
          </Link>
        </Grid>
      </Grid>
    </Card>
  );
};

This below is the container component that contains all of the cards

import * as React from 'react';
import Grid from '@mui/material/Grid';
import { RecipeReviewCard } from './CardTemplate';


export default function ResponsiveCardContainer() {
  return (
    <Grid container justifyContent="center" spacing={5} marginTop={10} paddingBottom={5}>
      <Grid item>
        <RecipeReviewCard to="/more-info/:id" />
      </Grid>
      <Grid item>
        <RecipeReviewCard to="/more-info/:id" />
      </Grid>
      <Grid item>
        <RecipeReviewCard to="/more-info/:id" />
      </Grid>
      <Grid item>
        <RecipeReviewCard to="/more-info/:id" />
      </Grid>
    </Grid>
  );
}

And this below is the code in the main.tsx

const DefaultComponent: React.FC = () => {
  return (
    <>
      {sections.map(({ component, sectionId }) => (
        <SectionContainer key={sectionId} sectionId={sectionId}>
          {component}
        </SectionContainer>
      ))}
      <MultiSearchBar />
      <ResponsiveCardContainer />
    </>
  );
};

It looks like this right now:

[![Here is how it looks right now][1]][1]

However, the filtering is not working as expected. When I select a brand, the cards are not updating accordingly. This because I don’t know how to implement the logic for this.

I know that maybe my existing implementation is not perfect, will appreciate any suggestions.

It is urgent task and I will be more than happy if someone help me!

Can someone help me?