javascriptreactjstypescriptmaterial-uimui-autocomplete

groupBy autocomplete sorting of options in Material UI


I am using Material UI Autocomplete and react for generating grouped autocomplete dropdown.

Below is the data

let top100Films = [
  { title: "The Shawshank Redemption", genre: "thriller" },
  { title: "The Dark Knight", genre: "super hero" },
  { title: "The Godfather: Part II", genre: "thriller" },
  { title: "12 Angry Men", genre: "war" },
  { title: "Schindler's List", genre: "war" },
  { title: "superman", genre: "super hero" },
  { title: "The Godfather", genre: "thriller" },
  {
    title: "The Lord of the Rings: The Return of the King",
    genre: "adventure"
  }
];

I want sort by first by genre and then title. I am able to sort by genre but not able to sort by title Below is the code

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

export default function Grouped() {
  top100Films = top100Films.sort((a, b) =>
    a.genre.toLowerCase() > b.genre.toLowerCase() ? 1 : -1
  );
  return (
    <Autocomplete
      id="grouped-demo"
      options={top100Films}
      groupBy={(option) => option.genre}
      getOptionLabel={(option) => option.title}
      sx={{ width: 300 }}
      renderInput={(params) => (
        <TextField {...params} label="With categories" />
      )}
    />
  );
}

// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top

let top100Films = [
  { title: "The Shawshank Redemption", genre: "thriller" },
  { title: "The Dark Knight", genre: "super hero" },
  { title: "The Godfather: Part II", genre: "thriller" },
  { title: "12 Angry Men", genre: "war" },
  { title: "Schindler's List", genre: "war" },
  { title: "superman", genre: "super hero" },
  { title: "The Godfather", genre: "thriller" },
  {
    title: "The Lord of the Rings: The Return of the King",
    genre: "adventure"
  }
];

Below is the link to codesandox

https://codesandbox.io/s/grouped-autocomplete-options-sorting-zrsb34?file=/demo.js:663-1132

How do I achieve it.

Thanks in advance!


Solution

  • Try to change your sort condition like this:

    export default function Grouped() {
      const sortedFilms = top100Films.sort((a, b) => {
        if (a.genre.toLowerCase() === b.genre.toLowerCase()) {
          return a.title.toLowerCase() > b.title.toLowerCase() ? 1 : -1;
        }
        return a.genre.toLowerCase() > b.genre.toLowerCase() ? 1 : -1;
      });
      return (
        <Autocomplete
          id="grouped-demo"
          options={sortedFilms}
          groupBy={(option) => option.genre}
          getOptionLabel={(option) => option.title}
          sx={{ width: 300 }}
          renderInput={(params) => (
            <TextField {...params} label="With categories" />
          )}
        />
      );
    }
    

    Link to sandbox