Search code examples
javascriptreactjsmenuantdmenuitem

Menu content display issue


I need some help pls. I created a menu with section and courses; but the section-labels are repeating.

I would like all courses with the same section to be displayed on a single section lable.

Please see code and screenshot.

<Menu

                            defaultSelectedKeys={[clicked]}
                            inlineCollapsed={collapsed}
                            style={{ height: "100vh", overflow: "scroll" }}
                            mode="inline"
                        >

                            {course.lessons.map((lesson, index) => (

                                <SubMenu
                                    title={lesson.section}>
                                    <ItemGroup
                                        key={index}>

                                        <Item
                                            onClick={() => setClicked(index)}
                                            key={index}
                                            icon={<Avatar>{index + 1}</Avatar>}
                                        >

                                            {lesson.title.substring(0, 30)}
                                            {" "}
                                            {completedLessons.includes(lesson._id) ? (
                                                <CheckCircleFilled
                                                    className="float-end text-primary ml-2"
                                                    style={{ marginTop: "13px" }}
                                                />
                                            ) : (
                                                <MinusCircleFilled
                                                    className="float-end text-danger ml-2"
                                                    style={{ marginTop: "13px" }}
                                                />
                                            )}
                                        </Item>

                                    </ItemGroup>
                                </SubMenu>
                            ))}
                        </Menu>

Screenshot of the Menu


Solution

  • You need to group the lessons by section, then you must iterate over each lessons in the section.

    Here is a possible solution :

    // group lessons by section into an object {sectionName: [lesson1, lesson2]}
    const lessonsBySection = course.lessons.reduce(function(obj, lesson) {
      (obj[lesson.section] = obj[lesson.section] || []).push(lesson);
      return obj;
    }, {});
    
    // get all the sections (sorted alphabetically)
    const sections = Object.keys(lessonsBySection).sort();
    
    return (
      <Menu ...>
        {sections.map((section, sectionIndex) => (
          <SubMenu key={section} title={section}>
            <ItemGroup>
              {lessonsBySection[section].map((lesson, lessonIndex) => (
                <Item 
                  key={lesson._id}
                  onClick={() => setClicked(
                    courses.lessons.findIndex(l => l._id === lesson._id)
                  )}                
                  icon={<Avatar>{lessonIndex + 1}</Avatar>}
                >
                ...
                </Item>
              ))}
            </ItemGroup>
          </SubMenu>
        ))}
      </Menu>
    )