Topic: Wrapping SideNavCat
Hi,
I would like to create a component to group together SideNav categories, so I could render them with one condition.
<MDBSideNavNav>
{ this.state.user.roles.includes('ROLE_ADMINISTRATOR') ? <AdministratorSideNav /> : null }
...
</MDBSideNavNav>
The AdministratorSideNav component looks like:
class AdministratorSideNav extends Component {
render() {
return [
<MDBSideNavCat
key='company-admin-cat'
name="Company Administration "
id="company-admin-cat"
icon="chevron-right">
<MDBSideNavItem href='/admin/location'>Locations</MDBSideNavItem>
<MDBSideNavItem href='/admin/user'>Users</MDBSideNavItem>
<MDBSideNavItem href='/admin/team'>Teams</MDBSideNavItem>
</MDBSideNavCat>,
... more MDBSideNavCat
];
}};
The rendering looks okay. The only problem is that clicking is not working. Clicking on the MDBSideNavCat (Company Administration in my example) only results in the ripple effect, but the category is not opening.
Is there any trick I am missing?
Regards, Laszlo
lpokoradi pro premium priority answered 5 years ago
App.jsx:
import React, {Component} from 'react';
import '@fortawesome/fontawesome-free/css/all.min.css';
import "bootstrap-css-only/css/bootstrap.min.css";
import "mdbreact/dist/css/mdb.css";
import NavigationPage from "./Navigation/NavigationPage";
import {BrowserRouter} from "react-router-dom";
class App extends Component {
constructor() {
super();
this.state = {
locations: null
};
}
componentDidMount() {
}
render() {
return (
<BrowserRouter>
<NavigationPage />
</BrowserRouter>
);
}
}
App.propTypes = {};
export default App;
lpokoradi pro premium priority answered 5 years ago
NavigationPage.jsx:
import React from "react";
import {
MDBInput,
MDBNavbar,
MDBNavbarNav,
MDBNavItem,
MDBNavLink,
MDBDropdown,
MDBDropdownToggle,
MDBDropdownMenu,
MDBDropdownItem,
MDBIcon,
MDBSideNavItem,
MDBSideNavCat,
MDBSideNavNav,
MDBSideNav,
MDBContainer
} from "mdbreact";
import {Link, Route, Switch} from "react-router-dom";
import AdministratorSideNav from "./SideNav/AdministratorSideNav";
class NavigationPage extends React.Component {
constructor(props) {
super(props);
this.state = {
isSideBarShown: false,
user: {
roles: ['ROLE_USER', 'ROLE_ADMINISTRATOR', 'ROLE_DELIVERY']
}
};
}
handleToggleClickA = () => {
this.setState({
isSideBarShown: !this.state.isSideBarShown
});
};
render() {
const mainStyle = {
paddingTop: "5rem"
};
const specialCaseNavbarStyles = {
WebkitBoxOrient: "horizontal",
flexDirection: "row"
};
return (
<div className="navy-blue-skin">
<MDBSideNav
logo="https://mdbootstrap.com/img/logo/mdb-transparent.png"
triggerOpening={this.state.isSideBarShown}
bg="https://mdbootstrap.com/img/Photos/Others/sidenav4.jpg"
mask="strong"
hidden>
<li>
<ul className="social">
<li>
<a href="#!">
<MDBIcon fab icon="facebook-f"/>
</a>
</li>
<li>
<a href="#!">
<MDBIcon fab icon="pinterest"/>
</a>
</li>
<li>
<a href="#!">
<MDBIcon fab icon="google-plus-g"/>
</a>
</li>
<li>
<a href="#!">
<MDBIcon fab icon="twitter"/>
</a>
</li>
</ul>
</li>
<MDBInput
type="text"
hint="Search"
style={{
color: "#fff",
padding: "0 10px 8px 30px",
boxSizing: "border-box"
}}
/>
<MDBSideNavNav>
{ this.state.user.roles.includes('ROLE_ADMINISTRATOR') ? <AdministratorSideNav /> : null }
<MDBSideNavCat
name="Submit blog"
id="submit-blog-cat"
icon="chevron-right">
<Link to="submit">Submit Listing</Link>
<MDBSideNavItem href="/test">Submit listing</MDBSideNavItem>
<MDBSideNavItem>Registration form</MDBSideNavItem>
</MDBSideNavCat>
</MDBSideNavNav>
</MDBSideNav>
<MDBNavbar double expand="md" fixed="top" scrolling>
<MDBNavbarNav left>
<MDBNavItem>
<div
onClick={this.handleToggleClickA}
key="sideNavToggleA"
style={{
lineHeight: "32px",
marginRight: "1em",
verticalAlign: "middle"
}}
>
<MDBIcon icon="bars" color="white" size="2x"/>
</div>
</MDBNavItem>
<MDBNavItem className="d-none d-md-inline" style={{paddingTop: 5}}>
Material Design for Bootstrap
</MDBNavItem>
</MDBNavbarNav>
<MDBNavbarNav right style={specialCaseNavbarStyles}>
<MDBNavItem active>
<MDBNavLink to="#!">
<MDBIcon icon="envelope" className="d-inline-inline"/>{" "}
<div className="d-none d-md-inline">Contact</div>
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink to="#!">
<MDBIcon far icon="comments" className="d-inline-inline"/>{" "}
<div className="d-none d-md-inline">Support</div>
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink to="#!">
<MDBIcon icon="user" className="d-inline-inline"/>{" "}
<div className="d-none d-md-inline">Account</div>
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBDropdown>
<MDBDropdownToggle nav caret>
<div className="d-none d-md-inline">Dropdown</div>
</MDBDropdownToggle>
<MDBDropdownMenu right>
<MDBDropdownItem href="#!">Action</MDBDropdownItem>
<MDBDropdownItem href="#!">Another Action</MDBDropdownItem>
<MDBDropdownItem href="#!">Something else here</MDBDropdownItem>
<MDBDropdownItem href="#!">Something else here</MDBDropdownItem>
</MDBDropdownMenu>
</MDBDropdown>
</MDBNavItem>
</MDBNavbarNav>
</MDBNavbar>
<main style={mainStyle}>
<MDBContainer fluid style={{height: 2000}} className="mt-5">
<Switch>
<Route path='/' exact render={()=><h1>Test</h1>}></Route>
<Route path='/admin/location' render={()=><h1>Location administration</h1>}></Route>
<Route path='/admin/user' render={()=><h1>User administration</h1>}></Route>
<Route path='/admin/team' render={()=><h1>Team administration</h1>}></Route>
</Switch>
</MDBContainer>
</main>
</div>
);
}
}
export default NavigationPage;
lpokoradi pro premium priority answered 5 years ago
AdministratorSideNav.jsx:
import React, {Component} from 'react';
import {MDBSideNavCat, MDBSideNavItem} from "mdbreact";
import {withRouter} from "react-router-dom";
class AdministratorSideNav extends Component {
render() {
return (
<React.Fragment>
<MDBSideNavCat
key="company-admin-cat"
name="Company Administration "
id="company-admin-cat"
icon="chevron-right">
<MDBSideNavItem href="/admin/location">Locations</MDBSideNavItem>
<MDBSideNavItem href="/admin/user">Users</MDBSideNavItem>
<MDBSideNavItem href="/admin/team">Teams</MDBSideNavItem>
</MDBSideNavCat>
<MDBSideNavCat
key='assessment-admin-cat'
name="Assessment Administration "
id="assessment-admin-cat"
icon="chevron-right">
<MDBSideNavItem href='test'>Submit listing</MDBSideNavItem>
<MDBSideNavItem>Registration form</MDBSideNavItem>
</MDBSideNavCat>
</React.Fragment>
);
}
};
export default withRouter(AdministratorSideNav);
lpokoradi pro premium priority answered 5 years ago
The "Submit blog" SideNavCat is working perfectly, but my AdministratorSideNav component is just rendered correctly, but the click event is not opening the category.
Piotr Glejzer staff answered 5 years ago
Ok, I figured it out.
So the main problem is that our component SideNavNav
has a React.Children
method on what type of component name is returning and it if is a SideNavCat
return a React.cloneElement
with prop onClick and isOpen what number is clicked and what component is open at the moment.
If you are returning elements like that:
{this.state.user.roles.includes('ROLE_ADMINISTRATOR') ? (
<>
<MDBSideNavCat
key='company-admin-cat'
name='Company Administration '
id='company-admin-cat'
icon='chevron-right'
>
<MDBSideNavItem href='/admin/location'>Locations</MDBSideNavItem>
<MDBSideNavItem href='/admin/user'>Users</MDBSideNavItem>
<MDBSideNavItem href='/admin/team'>Teams</MDBSideNavItem>
</MDBSideNavCat>
<MDBSideNavCat
key='assessment-admin-cat'
name='Assessment Administration '
id='assessment-admin-cat'
icon='chevron-right'
isOpenID='3'
>
<MDBSideNavItem href='test'>Submit listing</MDBSideNavItem>
<MDBSideNavItem>Registration form</MDBSideNavItem>
</MDBSideNavCat>{' '}
</>
) : null}
It is not working as I said because the first displayName is a react.fragment
instead SideNavCat
.
The solution for that is to split the above condition to separate objects. Like this:
{this.state.user.roles.includes('ROLE_ADMINISTRATOR') ? (
<MDBSideNavCat
key='assessment-admin-cat'
name='Assessment Administration '
id='assessment-admin-cat'
icon='chevron-right'
isOpenID='3'
>
<MDBSideNavItem href='test'>Submit listing</MDBSideNavItem>
<MDBSideNavItem>Registration form</MDBSideNavItem>
</MDBSideNavCat>
) : null}
{this.state.user.roles.includes('ROLE_ADMINISTRATOR') ? (
<MDBSideNavCat
key='company-admin-cat'
name='Company Administration '
id='company-admin-cat'
icon='chevron-right'
>
<MDBSideNavItem href='/admin/location'>Locations</MDBSideNavItem>
<MDBSideNavItem href='/admin/user'>Users</MDBSideNavItem>
<MDBSideNavItem href='/admin/team'>Teams</MDBSideNavItem>
</MDBSideNavCat>
) : null}
Here is a fully working NavigationPage
import React from "react";
import {
MDBInput,
MDBNavbar,
MDBNavbarNav,
MDBNavItem,
MDBNavLink,
MDBDropdown,
MDBDropdownToggle,
MDBDropdownMenu,
MDBDropdownItem,
MDBIcon,
MDBSideNavItem,
MDBSideNavCat,
MDBSideNavNav,
MDBSideNav,
MDBContainer
} from "mdbreact";
import { Link, Route, Switch } from "react-router-dom";
class NavigationPage extends React.Component {
constructor(props) {
super(props);
this.state = {
isSideBarShown: false,
user: {
roles: ["ROLE_USER", "ROLE_ADMINISTRATOR", "ROLE_DELIVERY"]
}
};
}
handleToggleClickA = () => {
this.setState({
isSideBarShown: !this.state.isSideBarShown
});
};
render() {
const mainStyle = {
paddingTop: "5rem"
};
const specialCaseNavbarStyles = {
WebkitBoxOrient: "horizontal",
flexDirection: "row"
};
return (
<div className="navy-blue-skin">
<MDBSideNav
logo="https://mdbootstrap.com/img/logo/mdb-transparent.png"
triggerOpening={this.state.isSideBarShown}
bg="https://mdbootstrap.com/img/Photos/Others/sidenav4.jpg"
mask="strong"
hidden
>
<li>
<ul className="social">
<li>
<a href="#!">
<MDBIcon fab icon="facebook-f" />
</a>
</li>
<li>
<a href="#!">
<MDBIcon fab icon="pinterest" />
</a>
</li>
<li>
<a href="#!">
<MDBIcon fab icon="google-plus-g" />
</a>
</li>
<li>
<a href="#!">
<MDBIcon fab icon="twitter" />
</a>
</li>
</ul>
</li>
<MDBInput
type="text"
hint="Search"
style={{
color: "#fff",
padding: "0 10px 8px 30px",
boxSizing: "border-box"
}}
/>
<MDBSideNavNav>
{this.state.user.roles.includes("ROLE_ADMINISTRATOR") ? (
<MDBSideNavCat
key="company-admin-cat"
name="Company Administration "
id="company-admin-cat"
icon="chevron-right"
>
<MDBSideNavItem href="/admin/location">
Locations
</MDBSideNavItem>
<MDBSideNavItem href="/admin/user">Users</MDBSideNavItem>
<MDBSideNavItem href="/admin/team">Teams</MDBSideNavItem>
</MDBSideNavCat>
) : null}
{this.state.user.roles.includes("ROLE_ADMINISTRATOR") ? (
<MDBSideNavCat
key="assessment-admin-cat"
name="Assessment Administration "
id="assessment-admin-cat"
icon="chevron-right"
isOpenID="3"
>
<MDBSideNavItem href="test">Submit listing</MDBSideNavItem>
<MDBSideNavItem>Registration form</MDBSideNavItem>
</MDBSideNavCat>
) : null}
<MDBSideNavCat
name="Submit blog"
id="submit-blog-cat"
icon="chevron-right"
>
<Link to="submit">Submit Listing</Link>
<MDBSideNavItem href="/test">Submit listing</MDBSideNavItem>
<MDBSideNavItem>Registration form</MDBSideNavItem>
</MDBSideNavCat>
<MDBSideNavCat
name="Submit blog1"
id="submit-blog-cat1"
icon="chevron-right1"
>
<Link to="submit">Submit Listing</Link>
<MDBSideNavItem href="/test">Submit listing</MDBSideNavItem>
<MDBSideNavItem>Registration form</MDBSideNavItem>
</MDBSideNavCat>
</MDBSideNavNav>
</MDBSideNav>
<MDBNavbar double expand="md" fixed="top" scrolling>
<MDBNavbarNav left>
<MDBNavItem>
<div
onClick={this.handleToggleClickA}
key="sideNavToggleA"
style={{
lineHeight: "32px",
marginRight: "1em",
verticalAlign: "middle"
}}
>
<MDBIcon icon="bars" color="white" size="2x" />
</div>
</MDBNavItem>
<MDBNavItem
className="d-none d-md-inline"
style={{ paddingTop: 5 }}
>
Material Design for Bootstrap
</MDBNavItem>
</MDBNavbarNav>
<MDBNavbarNav right style={specialCaseNavbarStyles}>
<MDBNavItem active>
<MDBNavLink to="#!">
<MDBIcon icon="envelope" className="d-inline-inline" />{" "}
<div className="d-none d-md-inline">Contact</div>
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink to="#!">
<MDBIcon far icon="comments" className="d-inline-inline" />{" "}
<div className="d-none d-md-inline">Support</div>
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBNavLink to="#!">
<MDBIcon icon="user" className="d-inline-inline" />{" "}
<div className="d-none d-md-inline">Account</div>
</MDBNavLink>
</MDBNavItem>
<MDBNavItem>
<MDBDropdown>
<MDBDropdownToggle nav caret>
<div className="d-none d-md-inline">Dropdown</div>
</MDBDropdownToggle>
<MDBDropdownMenu right>
<MDBDropdownItem href="#!">Action</MDBDropdownItem>
<MDBDropdownItem href="#!">Another Action</MDBDropdownItem>
<MDBDropdownItem href="#!">
Something else here
</MDBDropdownItem>
<MDBDropdownItem href="#!">
Something else here
</MDBDropdownItem>
</MDBDropdownMenu>
</MDBDropdown>
</MDBNavItem>
</MDBNavbarNav>
</MDBNavbar>
<main style={mainStyle}>
<MDBContainer fluid style={{ height: 2000 }} className="mt-5">
<Switch>
<Route path="/" exact render={() => <h1>Test</h1>}></Route>
<Route
path="/admin/location"
render={() => <h1>Location administration</h1>}
></Route>
<Route
path="/admin/user"
render={() => <h1>User administration</h1>}
></Route>
<Route
path="/admin/team"
render={() => <h1>Team administration</h1>}
></Route>
</Switch>
</MDBContainer>
</main>
</div>
);
}
}
export default NavigationPage;
lpokoradi pro premium priority answered 5 years ago
Hi Piotr,
Thanks for the reply, I already knew that workaround is working, but it doesn't help me to have clean code.
So will it be possible decoupling like I would like to?
Piotr Glejzer staff commented 5 years ago
Is not possible to do it without duplicated a code. I added task to fix this. Sorry about that.
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- User: Pro
- Premium support: Yes
- Technology: MDB React
- MDB Version: 4.25.2
- Device: PC
- Browser: Chrome
- OS: Windows 10
- Provided sample code: No
- Provided link: No
Piotr Glejzer staff commented 5 years ago
Did you try to put all URL address into
href
?lpokoradi pro premium priority commented 5 years ago
Sorry, but I don't get it. What do you mean "put all URL address into
href
"?Piotr Glejzer staff commented 5 years ago
Oh sorry, I thought about a different problem.
So, did you try to use props
isOpen
?lpokoradi pro premium priority commented 5 years ago
If I change the value of
isOpen
from false to true, in the React DevTools, yes the category opens as it should. But the question why it is not working.lpokoradi pro premium priority commented 5 years ago
I would create a snippet for you, but "Something bad happened during initialization ;("
Piotr Glejzer staff commented 5 years ago
You can copy and paste all code here, I will check