React select with nested data

2.4k Views Asked by At

I am trying to make a nested select optgroup and tried the following,

const data = [
  {
    sectorId: 5,
    sectorName: "Sector One",
    departments: [
      {
        deptName: "Production",
        jobtitles: [
          {
            JobTitleID: 167,
            DepartmentID: 51,
            JobName: "Production Manager",
            Deleted: false,
            SortOrder: 5
          },
          {
            JobTitleID: 178,
            DepartmentID: 51,
            JobName: "Production Supervisor",
            Deleted: false,
            SortOrder: 3
          },
          {
            JobTitleID: 449,
            DepartmentID: 51,
            JobName: "Senior Wall Panel Designer",
            Deleted: false,
            SortOrder: 15
          }
        ]
      },
      {
        deptName: "Design/Engineering",
        jobtitles: [
          {
            JobTitleID: 294,
            DepartmentID: 52,
            JobName: "Senior Truss Designer",
            Deleted: false,
            SortOrder: 5
          }
        ]
      }
    ]
  },
  {
    sectorId: 24,
    sectorName: "Sector Two",
    departments: [
      {
        deptName: "Consulting",
        jobtitles: [
          {
            JobTitleID: 191,
            DepartmentID: 92,
            JobName: "Saw Shop Supervisor",
            Deleted: false,
            SortOrder: 1
          },
          {
            JobTitleID: 474,
            DepartmentID: 92,
            JobName: "Senior Truss Designer - Part Time",
            Deleted: false,
            SortOrder: 11
          }
        ]
      },
      {
        deptName: "Administration",
        jobtitles: [
          {
            JobTitleID: 461,
            DepartmentID: 114,
            JobName: "Sawyer",
            Deleted: false,
            SortOrder: 7
          },
          {
            JobTitleID: 278,
            DepartmentID: 114,
            JobName: "Service Manager",
            Deleted: false,
            SortOrder: 2
          }
        ]
      }
    ]
  }
];

const App = () => {
  return (
    <select>
      {data.map((levelOne, i) => (
        <optgroup label={levelOne.sectorName} key={i}>
          {levelOne.departments.map((levelTwo, j) => (
            <optgroup label={levelTwo.deptName} key={j}>
              {levelTwo.jobtitles.map((job, l) => (
                <>
                  <option key={job.JobTitleID} value={job.JobTitleID}>
                    {job.JobName}
                  </option>
                </>
              ))}
            </optgroup>
          ))}
        </optgroup>
      ))}
    </select>
  );
};

render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"> </div>

Sorry the above snippet has errors and you can also look at the working example here

This doesn't provide nested group of data and it stops with single level itself.

Current output:

Sector One
Sector Two

Expected output:

   Sector One

     Production

       -> Production Manager

       -> Production Supervisor

       -> Senior Wall Panel Designer

     Design/Engineering
    
       -> Senior Truss Designer

   Sector Two

     Consulting

       -> Saw Shop Supervisor

       -> Senior Truss Designer - Part Time

     Administration
    
       -> Sawyer

       -> Service Manager

Here only the jobtitles will be option, so as per the above data, the list that has -> will alone be option and others will be label.

So only using optgroup I have tried the above code, But don't know what mistake I am doing which results in not populating the data as per the expected result.

Kindly please help me to solve the above issue and make the above example work as like the expected output.

Adding any other react based library to achieve this also welcomed.

1

There are 1 best solutions below

1
On
  1. optgroup may not be nested, so only the sectorName is displayed;
  2. you can try to use the react-selector library. Here is an example react-select nested groups that I've found with nested levels.