1

I'm trying to build a multi level ReactJs dropdown menu. I'm using the following post/code as base:the following post and this jsfiddle code as starting point of my ReactJs component:

class DropdownMenu extends Component {
  static propTypes = {
    config: PropTypes.array.isRequired
  };

  getMenuItemTitle = (menuItem, index, depthLevel) => {
    return menuItem.title;
  };

  getMenuItem = (menuItem, depthLevel, index) => {
    let title = this.getMenuItemTitle(menuItem, index, depthLevel);

    if (menuItem.submenu && menuItem.submenu.length > 0) {
      return (
        <li>
          {title}
          <DropdownMenu config={menuItem.submenu} submenu={true} />
        </li>
      );
    } else {
      return <li>{title}</li>;
    }
  };

  render = () => {
    let { config } = this.props;

    let options = [];
    config.map((item, index) => {
      options.push(this.getMenuItem(item, 0, index));
    });

    if (this.props.submenu && this.props.submenu === true)
      return <ul>{options}</ul>;

    return <ul className="dropdown-menu">{options}</ul>;
  };
}

export default DropdownMenu;

CSS file:

.dropdown-menu {
    height: 35px;
    list-style: none;
    margin: 0;
    padding: 0;
    float: left;
    text-align: center;
}

.dropdown-menu li {
    display: inline-block;
    position: relative;
    float: left;
}

.dropdown-menu li a {
    display: inline-block;
    width: 200px;
    line-height: 35px;
    text-decoration: none;
}

.dropdown-menu li li a {
    font-size: 12px;
}

.dropdown-menu li:hover {
    background: blue;
}

/*--- Sublist Styles ---*/
.dropdown-menu ul {
    position: absolute;
    display: none;
}

/*--- Hide Sub Sublists ---*/
.dropdown-menu li:hover ul ul {
    display: none;
}

/*--- Sublevel UL's display and position on hover ---*/
.dropdown-menu li:hover ul {
    display: block;
}
.dropdown-menu li li:hover ul {
    margin-left: 200px;
    margin-top: -35px;
    display: block;
}
nu-li {
    padding: 10px;
}

.dropdown-submenu {
    position: absolute;
    left: 0px;
    top: 0px;
}

And finally my configuration file:

  "navItems": [
    {
      "title": "Option 1",
      "submenu": null
    },
    {
      "title": "Option 2",
      "submenu": [
        {
          "title": "Option 2.1",
          "submenu": [
            {
              "title": "Option 2.1.1",
              "submenu": null
            },
            {
              "title": "Option 2.1.2",
              "submenu": null
            }
          ]
        },
        {
          "title": "Option 2.2",
          "submenu": [
            {
              "title": "Option 2.2.1",
              "submenu": null
            },
            {
              "title": "Option 2.2.2",
              "submenu": null
            }
          ]
        }
      ]
    }
  ]

I'm getting a messy menu, with options above other options and I'm sure I'm missing something simple.

How can I turn my component in a real multi level dropdown menu?

1
  • Can you create a runnable example so we could try to debug it? Commented Aug 28, 2018 at 5:10

2 Answers 2

3

This questions is getting old, but for the sake of clearity, I added a jsfiddle to your question. For fiddle to work with your code i had to remove your propTypes and used internal props in ReactJS, see more here and then render it directly instead of exporting it.

I then saw the menu being a bit weird where the width of the menu item's was not sat, so i changed this:

.dropdown-menu li {
    display: inline-block;
    position: relative;
    float: left;
}

.dropdown-menu li a {
    display: inline-block;
    width: 200px;
    line-height: 35px;
    text-decoration: none;
}

to this:

.dropdown-menu li {
    display: inline-block;
    position: relative;
    float: left;
    width: 200px;
    line-height: 35px;
    text-decoration: none;
}

However, I dont see your messy menu let me know if you still have problems.

Sign up to request clarification or add additional context in comments.

Comments

0

I quickly modified the code of Lagoni, so that it also get and displays the depth of the submenu.

It gets it from the props and increments it at each recursion:

<DropdownMenu config={menuItem.submenu} depthLevel={depthLevel+1} submenu={true} />`

This way, you can effectively use it to, for instance, set the class according to the depth level. For example, make a gradient of color every time you go deeper, or increase the indentation.

jsfiddle

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.