SideNav is not working


Topic: SideNav is not working

Venky asked 6 years ago

Expected behavior When window size is increased or decreased side nav is not getting opened

Actual behavior Can able to see the icon but on click of it nothing is visible except the overlay

Resources (screenshots, code snippets etc.) I've used the same config which is given in the code snippet


Jakub Mandra staff premium answered 6 years ago

When I use MDBSideNavLink I'm getting an error like this

You should not use <Route> or withRouter() outside a <Router>

SideNavLink or NavbarLink are implementations of react-router-dom Link's, so to use them you have to wrap your App in BrowserRouter, like so (no need to install the package, it comes with mdbreact):

//import packages
import React, { Component } from 'react';
import { BrowserRouter } from 'react-router-dom';
import {
  MDBContainer
} from 'mdbreact';

//import CSS
import './App.css';

//import components
import LeftPanel from './components/LeftPanel';

//class
class App extends Component {

  render() {

    return (

      <BrowserRouter>
        <MDBContainer fluid className="p-0">
          <LeftPanel />
        </MDBContainer>
      </BrowserRouter>

    );

  }

}

export default App;

Expected Behavior - On window resize the Side Nav should either collapsed or opened

We actually have examples with complex navigation layouts here: https://mdbootstrap.com/docs/react/navigation/compositions/#double-nav-fixed-sidenav-navbar

I think you should try this, it should fulfill your needs, or at least clarify the matter.

That was my mistake in the previuos answer about resizing, I misunderstood the problem. To implement SideNav close/open on resize functionality, you just need to specify the breakWidth on which the SideNav should collapse (it is working under the hood).

Your SideNav from LeftPanel.js:

<MDBSideNav href="#recommendations" triggerOpening={this.state.sideNavbarCollapse} breakWidth={1300} className="deep-purple darken-4 w-25">

Best regards,

Jakub


Venky commented 6 years ago

Hi,

Thanks for the solution. It's working fine :)


Jakub Mandra staff premium answered 6 years ago

Hi,

To open/close on resize you need some extra code:

componentDidMount = () => {
    this.handleResize();
    window.addEventListener("resize", this.handleResize);
  }

  componentWillUnmount = () => {
    window.removeEventListener("resize", this.handleResize);
  }

  handleResize = () =>
    this.setState({
      windowWidth: window.innerWidth
    });

But I'm not sure why only the overlay is visible onClick. Have you just installed mdb in the new project? Can you show us your index.js with css imports?

Best,

Jakub


Venky commented 6 years ago

Hi,

My src folder structure is like this

**css**
    custom.css
**images**
**js**
    index.js
    **components**
        Component-1
        Component-2
        ...........
        Component-N
**mdbr**
    css
    font
    img
    scss
    mdbreact.esm.js
    mdbreact.js
**index.html**

In my index.js file, I've imported the CSS like this

//import CSS
import "@fortawesome/fontawesome-free/css/all.min.css";
import 'bootstrap-css-only/css/bootstrap.min.css';
import '../mdbr/css/mdb.css';
import '../css/custom.css';

Please let me know for any further information

Thanks :)


Jakub Mandra staff premium commented 6 years ago

If your css imports are before App.js import all should be good there. F.e.:

import React from 'react';
import ReactDOM from 'react-dom';
import "@fortawesome/fontawesome-free/css/all.min.css";
import 'bootstrap-css-only/css/bootstrap.min.css'; 
import 'mdbreact/dist/css/mdb.css';
import App from './App';

But I see that you store the js files in your dir, can you describe how did you install the package?

Also maybe this installation description would help: https://mdbootstrap.com/docs/react/getting-started/quick-start/

Best


Venky commented 6 years ago

Hi,

I've installed mdbreact as suggested in https://mdbootstrap.com/docs/react/getting-started/quick-start/

This is my package.json

{
  "name": "insights-research",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "axios": "^0.18.0",
    "mdbreact": "git+https://oauth2:USED_MY_PRIVATE_TOKEN_HERE@git.mdbootstrap.com/mdb/react/re-pro.git",
    "react": "^16.8.4",
    "react-dom": "^16.8.4",
    "react-router-dom": "^5.0.0",
    "react-scripts": "2.1.8"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "proxy": "http://localhost:9999"
}

This is my src folder structure

public
    index.html
src
    components
        LeftPanel.js
    images
        logo.png
    App.css
    App.js
    App.test.js
    index.css
    index.js
    serviceWorker.js
package.json

index.js file

//import packages
import React from 'react';
import ReactDOM from 'react-dom';

//import CSS
import "@fortawesome/fontawesome-free/css/all.min.css";
import "bootstrap-css-only/css/bootstrap.min.css";
import "mdbreact/dist/css/mdb.css";
import './index.css';

//import components
import App from './App';

import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('insights-research'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

App.js

//import packages
import React, { Component } from 'react';
import {
    MDBContainer
} from 'mdbreact';

//import CSS
import './App.css';

//import components
import LeftPanel from './components/LeftPanel';

//class
class App extends Component {

    render() {

        return (

            <MDBContainer fluid className="p-0">
                <LeftPanel />
            </MDBContainer>

        );

    }

}

export default App;

In the components folder I've a component like this

LeftPanel.js

//import packages
import React, { Component } from 'react';
import {
    MDBContainer, MDBTooltip, MDBBtn, MDBBadge, MDBIcon,
    MDBNavbar, MDBNavbarBrand, MDBNavbarNav, MDBNavbarToggler, MDBNav, MDBNavItem, MDBNavLink,
    MDBRow,
    MDBDropdown, MDBDropdownMenu, MDBDropdownItem, MDBDropdownToggle,
    MDBTabContent, MDBTabPane,
    MDBListGroup, MDBListGroupItem,
    MDBCollapse,
    MDBSideNav, MDBSideNavNav, MDBSideNavCat, MDBSideNavLink
} from 'mdbreact';

//import Images
import logo from '../images/logo.png';

//class
export default class LeftPanel extends Component {

    constructor(props) {
        super(props);
        this.state = {
            sideNavbarCollapse: false,
            windowWidth: 0
        };
    }

    componentDidMount() {
        this.handleResize();
        window.addEventListener("resize", this.handleResize());
    }

    componentWillUnmount = () => {
        window.removeEventListener("resize", this.handleResize());
    }

    handleResize = () => {
        this.setState({
            windowWidth: window.innerWidth
        });
    }

    toggleSideNavBar = () => {
        this.setState({
            sideNavbarCollapse: !this.state.sideNavbarCollapse
        });
    }

    render() {

        return (

            <MDBContainer fluid className="source_container">

                <div style={{height: "100vh"}}>

                    <div style={{height: "10%"}}></div>

                    <MDBRow>

                        <MDBBtn size="sm" onClick={() => this.toggleSideNavBar()}>
                            <MDBIcon icon="bars" />
                        </MDBBtn>

                    </MDBRow>

                    <MDBSideNav logo={logo} href="#recommendations" hidden triggerOpening={this.state.sideNavbarCollapse} breakWidth={this.state.windowWidth} className="deep-purple darken-4 w-25">

                        <MDBSideNavNav>

                            <MDBSideNavCat name="Submit blog" id="submit-blog" icon="chevron-right">
                                <MDBSideNavLink>Submit listing</MDBSideNavLink>
                                <MDBSideNavLink>Registration form</MDBSideNavLink>
                            </MDBSideNavCat>

                            <MDBSideNavCat name="Instruction" id="instruction" iconRegular icon="hand-pointer">
                                <MDBSideNavLink>Submit listing</MDBSideNavLink>
                                <MDBSideNavLink>Registration form</MDBSideNavLink>
                            </MDBSideNavCat>

                            <MDBSideNavCat name="About" id="about" icon="eye">
                                <div>Instruction</div>
                                <div>Monthly meetings</div>
                            </MDBSideNavCat>

                            <MDBSideNavCat name="Contact me" id="contact-me" iconRegular icon="envelope">
                                <div>FAQ</div>
                                <div>Write a message</div>
                            </MDBSideNavCat>

                        </MDBSideNavNav>

                    </MDBSideNav>

                </div>

            </MDBContainer>

        );

    }

}

Expected Behavior - On window resize the Side Nav should either collapsed or opened

Actual Behavior - We are able to see the icon and on click of it able to get the side nav, but on window resizing the Side Nav is not getting opened

When I use MDBSideNavLink I'm getting an error like this

You should not use <Route> or withRouter() outside a <Router>

Please let me know for any further info

Thanks :)


Venky answered 6 years ago

Hi,

I've a small question for SideNav, let's say I've a SideNav which has multi level accordions

For example the SideNav using in MDB site like MDB Pro and Getting Started accordion and so on... in the same way can we have an accordion inside one more accordion.

For reference

<MDBSideNavNav>
    <MDBSideNavCat name="MDB Pro" id="mdb_pro" icon="chevron-right"></MDBSideNavCat>
    <MDBSideNavCat name="Getting Started" id="getting_started" icon="chevron-right">
        <MDBSideNavItem>ABC</MDBSideNavItem>
        <MDBSideNavItem>DEF</MDBSideNavItem>
        <MDBSideNavItem>GHI</MDBSideNavItem>
    </MDBSideNavCat>
    <MDBSideNavCat name="Multi Level Accordion" id="multi_level_accordion" icon="chevron-right">
        <MDBSideNavCat iconRegular name="Level 1" id="level_1" icon="hand-pointer">
            <MDBSideNavItem>Level 1 Item 1</MDBSideNavItem>
            <MDBSideNavItem>Level 1 Item 2</MDBSideNavItem>
        </MDBSideNavCat>
        <MDBSideNavCat iconRegular name="Level 2" id="level_2" icon="hand-pointer">
            <MDBSideNavItem>Level 2 Item 1</MDBSideNavItem>
            <MDBSideNavItem>Level 2 Item 2</MDBSideNavItem>
        </MDBSideNavCat>
    </MDBSideNavCat>
    <MDBSideNavCat name="About" id="about-cat" icon="eye">
        <MDBSideNavItem>Instruction</MDBSideNavItem>
        <MDBSideNavItem>Monthly meetings</MDBSideNavItem>
    </MDBSideNavCat>
    <MDBSideNavCat name="Contact me" id="contact-me-cat" icon="envelope">
        <MDBSideNavItem>FAQ</MDBSideNavItem>
        <MDBSideNavItem>Write a message</MDBSideNavItem>
    </MDBSideNavCat>
</MDBSideNavNav>

I've tried something like this, but didn't get what I'm exactly looking for. Can you please provide a solution for this

Thanks :)


Jakub Mandra staff premium answered 6 years ago

Hi,

By default, sideNav doesn't support nested dropdowns, but you can simply implement it by hand. Just add isOpen property to your nested SideNavCat and handle the changes onClick.

Example:

import React from 'react'; import { MDBIcon, MDBSideNavCat, MDBSideNavNav, MDBSideNav, MDBSideNavLink, MDBContainer, MDBRow, MDBBtn } from 'mdbreact';

class SideNavPage extends React.Component {
  state = {
    isOpen: false,
    nestedOpen: false
  }

  handleToggle = () => {
    this.setState({
      isOpen: !this.state.isOpen
    });
  };

  handleNestedToggle = () => this.setState({ nestedOpen: !this.state.nestedOpen });

  render() {
    const { isOpen } = this.state;
    return (
      <MDBContainer>
        <MDBRow>
          <MDBBtn onClick={this.handleToggle}><MDBIcon icon="bars" size="5x" /></MDBBtn>
        </MDBRow>
        <MDBSideNav
          logo="https://mdbootstrap.com/img/logo/mdb-transparent.png"
          hidden
          triggerOpening={isOpen}
          breakWidth={1300}
          className="deep-purple darken-4"
        >
          <MDBSideNavNav>
            <MDBSideNavCat
              name="Submit blog"
              id="submit-blog"
              icon="chevron-right"
            >
              <MDBSideNavLink>Submit listing</MDBSideNavLink>
              <MDBSideNavLink>Registration form</MDBSideNavLink>
              <MDBSideNavCat tag="ul" name="Contact me" id="nested" iconRegular icon="envelope" isOpen={this.state.nestedOpen} onClick={this.handleNestedToggle}>
                <MDBSideNavLink>FAQ</MDBSideNavLink>
                <MDBSideNavLink>Write a message</MDBSideNavLink>
              </MDBSideNavCat>
            </MDBSideNavCat>
          </MDBSideNavNav>
        </MDBSideNav>
      </MDBContainer>
    );
  }
}

export default SideNavPage;

Best,

Jakub


Venky commented 6 years ago

Thanks for the piece of code :)


Jakub Mandra staff premium commented 6 years ago

If you need anything else please let me know :)


Venky commented 6 years ago

Hi Jakub,

Everything is working fine, but one more small question from the previous discussion.

MDBSideNavLink is currently working as a tag, instead can we've a normal item lets's say (MDBSideNavItem) which should act as accordion header and can be highlight (active) when clicked on it and when we click on any other accordion the previous selection (MDBSideNavItem) should be de highlighted

For example

<MDBSideNavNav>
    <MDBSideNavLink>Single Selection 1</MDBSideNavLink>
    <MDBSideNavLink>Single Selection 2</MDBSideNavLink>
    <MDBSideNavLink>Single Selection 3</MDBSideNavLink>
    <MDBSideNavCat name="Accordion 1" id="accordion_1" icon="chevron-right">
        <MDBSideNavLink>A11</MDBSideNavLink>
        <MDBSideNavLink>A12</MDBSideNavLink>
        <MDBSideNavLink>A13</MDBSideNavLink>
    </MDBSideNavCat>
    <MDBSideNavCat name="Accordion 2" id="accordion_2" icon="chevron-right">
        <MDBSideNavLink>A21</MDBSideNavLink>
        <MDBSideNavLink>A22</MDBSideNavLink>
        <MDBSideNavLink>A23</MDBSideNavLink>
    </MDBSideNavCat>
    <MDBSideNavCat name="Accordion 3" id="accordion_3" icon="chevron-right">
        <MDBSideNavLink>A31</MDBSideNavLink>
    </MDBSideNavCat>
    <MDBSideNavLink>Single Selection 4</MDBSideNavLink>
    <MDBSideNavLink>Single Selection 5</MDBSideNavLink>
<MDBSideNavNav>

When I click on Single Selection 1 it should be highlighted (active)

When I click on Single Selection 3 it should be highlighted (active) and the previous Single Selection 1 should be de-highlighted

In the same way when I click on Accordion 1 it should be highlighted (this happening now, but remaining highlighted should be de-highlighted)

I hope I'm not confusing you with this piece of code ;)

Please let me know for any further information

Thanks :)


Jakub Mandra staff premium commented 6 years ago

You could attach class active when your at the route of the link.

with react-router-dom: <MDBSideNavLink classNames={this.props.location.pathname === 'yourPath' && 'active'} should work

Best,

Jakub


Venky answered 6 years ago

Hey Jakub,

Thanks for that answer, that will solves my other issue, but my main issue is like within the same page if I click on any side nav element it should highlight same as like MDBSideNavCat active

From the previous comment

can we've a normal item lets's say (MDBSideNavItem) which should act as accordion header and can be highlight (active) when clicked on it and when we click on any other accordion the previous selection (MDBSideNavItem) should be de highlighted

Please let me know for any clarifications on the same

Thanks :)


Jakub Mandra staff premium commented 6 years ago

I think I did not understand that clearly.

You need to have an element in your SideNav, which is not a navigation element? It opens modal for example?

SideNavCat can be highlighted due to its inner state (dropdown open/close). Other components were meant to work as navigation links.

I think that we could improve this functionality, so I'm sending the request to the development team.

Currently, you can use <li><a className="collapsible-header active">Item</a></li> as a custom element.

Best,

Jakub


Venky commented 6 years ago

Hey Jakub,

Thanks for the solution :)


Jakub Mandra staff premium commented 6 years ago

If there is anything else I could do for you do not hesitate to ask me. I'll be happy to help :)


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Resolved

Specification of the issue
  • User: Free
  • Premium support: No
  • Technology: MDB React
  • MDB Version: 4.11.0
  • Device: Laptop
  • Browser: Chrome
  • OS: Window 10
  • Provided sample code: No
  • Provided link: No
Tags