Add a image to React Bootstrap dropdown - reactjs

I'm using React Bootstrap and React Router Bootstrap for my Navbar, and I am making a user profile dropdown menu list.
I'd like to be able to have an user's avatar show up in place of the 'title' property. (The same idea as the user profile dropdown on Github)
Is this possible? I don't see any options to use an image instead of title for NavDropdown
<Navbar inverse>
<Navbar.Header>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<Nav pullRight>
<NavDropdown eventKey={ 3 } id="profile-dropdown" >
<LinkContainer to="/profile/edit" >
<NavItem eventKey={ 3.4 } > Edit </NavItem>
</LinkContainer>
<LinkContainer to="/logout">
<Logout eventKey={ 3.5 } />
</LinkContainer>
</NavDropdown>
</Nav>
</Navbar.Collapse>
</Navbar>
Would a SplitButton or straight Dropdown be a better option? I don't really see much that the "NavDropdown" is adding to the HTML.

The NavDropdown's title property can take any React element as a value. This is what I did:
<Nav pullRight>
<NavDropdown eventKey={1}
title={
<div className="pull-left">
<img className="thumbnail-image"
src={src}
alt="user pic"
/>
{user.username}
</div>
}
id="basic-nav-dropdown">
<MenuItem eventKey={1.1} href="/profile">Profile</MenuItem>
<MenuItem divider />
<MenuItem eventKey={1.3}>
<i className="fa fa-sign-out"></i> Logout
</MenuItem>
</NavDropdown>
</Nav>
You'll probably need to adjust the css a little bit.

You can also use the <Image /> component, e.g.
const UserMenu = (
<Image
src={'https://github.com/mshaaban0.png'}
alt="UserName profile image"
roundedCircle
style={{ width: '40px' }}
/>
)
<NavDropdown id="nav-dropdown-dark-example" title={UserMenu}>
//....
</NavDropdown>

Related

React-Bootstrap Navbar issue

Can somebody help me align my navbar? Nothing I do makes the top part line up normally. I think the issue might be when navbar gets toggled whether the user is logged in and an admin or not. I'm wondering if is because of the divs and if I have to make a separate component now. It is also really big for no good reason.
<Navbar.Brand href="/homepage" className="logo">
<h2>BookShopper</h2>
{/* <img src = 'logo.png' height = '100px' width = '300px'/> */}
</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Form className="d-flex">
<FormControl
className = "justify-content-center"
type="search"
placeholder="Search"
className="me-2"
aria-label="Search"
/>
</Form>
{isLoggedIn ? (
<div>
<Nav className="me-auto">
<Nav.Link href="/edit">Profile</Nav.Link>
{/* The navbar will show these links after you log in */}
<Nav.Link href="#" onClick={handleClick}>
Logout
</Nav.Link>
<Nav.Link href="/cart">
<BsFillBasket3Fill />
</Nav.Link>
</Nav>
{isUserAdmin && (
<div>
<Nav className="me-auto">
<NavDropdown
title="Market Place"
id="collasible-nav-dropdown"
>
<NavDropdown.Item href="/stock">Stock</NavDropdown.Item>
<NavDropdown.Item href="/users">Users</NavDropdown.Item>
<NavDropdown.Item href="/add-book">
Add Book
</NavDropdown.Item>
</NavDropdown>
</Nav>
</div>
)}
</div>
) : (
<div>
{/* The navbar will show these links before you log in */}
<Nav>
<Nav.Link href="/login">Login</Nav.Link>
<Nav.Link href="/cart">
<BsFillBasket3Fill />
</Nav.Link>
</Nav>
</div>
)}
</Navbar.Collapse>
{/* </Container> */}
</Navbar>
I just want the elements to line up horizontally and look normal.
With your code you are creating two Navs (if logged in AND user admin). Move Nav outside of the ternary operator to create it only once and set navigation links according to your logic.
Basically you want:
When not logged in: Show "Login" and "Basket"
When logged in: Show "Profile", "Logout" and "Basket"
When logged in AND also having admin rights: Show "Profile", "Logout", "Basket" and "Market Place"
I've created a sandbox, fixed the problem with double Navs and tried to simplified your boolean logic as well: https://codesandbox.io/s/interesting-darkness-i0u64k?file=/src/App.js

Issue with React-Boostrap's Offcanvas and breakpoints

I'm currently trying to implement an offcanvas style navbar using react-boostrap, and am trying to make it responsive so that menu icon disappears and the contents are displayed on the nav bar itself when the screen reaches above a certain size.
I used the example from their site but have changed the value of the expand property and added a collapse component: https://react-bootstrap.netlify.app/components/navbar/#navbar-offcanvas
import {
Navbar,
Container,
Offcanvas,
NavDropdown,
Form,
FormControl,
Button,
Nav,
} from "react-bootstrap";
const Navigation = () => {
return (
<Navbar bg="light" expand="1g" collapseOnSelect>
<Container fluid>
<Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand>
<Navbar.Toggle aria-controls="offcanvasNavbar" />
<Navbar.Collapse id="offcanvasNavbar">
<Navbar.Offcanvas
id="offcanvasNavbar"
aria-labelledby="offcanvasNavbarLabel"
placement="end"
>
<Offcanvas.Header closeButton>
<Offcanvas.Title id="offcanvasNavbarLabel">
Offcanvas
</Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
<Nav className="justify-content-end flex-grow-1 pe-3">
<Nav.Link href="#action1">Home</Nav.Link>
<Nav.Link href="#action2">Link</Nav.Link>
<NavDropdown title="Dropdown" id="offcanvasNavbarDropdown">
<NavDropdown.Item href="#action3">Action</NavDropdown.Item>
<NavDropdown.Item href="#action4">
Another action
</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action5">
Something else here
</NavDropdown.Item>
</NavDropdown>
</Nav>
<Form className="d-flex">
<FormControl
type="search"
placeholder="Search"
className="me-2"
aria-label="Search"
/>
<Button variant="outline-success">Search</Button>
</Form>
</Offcanvas.Body>
</Navbar.Offcanvas>
</Navbar.Collapse>
</Container>
</Navbar>
);
};
The menu icon should disappear and the contents expand onto the navbar at 992 horizontal res, but nothing changes.
I also tried to use a normal navbar from their examples, but then replace the body with an offcanvas body like so:
<Navbar collapseOnSelect expand="lg" bg="light">
<Container>
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Navbar.Offcanvas
id="offcanvasNavbar"
aria-labelledby="offcanvasNavbarLabel"
placement="end"
>
<Offcanvas.Header closeButton>
<Offcanvas.Title id="offcanvasNavbarLabel">
Offcanvas
</Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
<Nav className="justify-content-end flex-grow-1 pe-3">
<Nav.Link href="#action1">Home</Nav.Link>
<Nav.Link href="#action2">Link</Nav.Link>
<NavDropdown title="Dropdown" id="offcanvasNavbarDropdown">
<NavDropdown.Item href="#action3">Action</NavDropdown.Item>
<NavDropdown.Item href="#action4">
Another action
</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action5">
Something else here
</NavDropdown.Item>
</NavDropdown>
</Nav>
<Form className="d-flex">
<FormControl
type="search"
placeholder="Search"
className="me-2"
aria-label="Search"
/>
<Button variant="outline-success">Search</Button>
</Form>
</Offcanvas.Body>
</Navbar.Offcanvas>
</Navbar.Collapse>
</Container>
</Navbar>
And while this did actually make the icon disappear correctly, none of the menu's contents would appear onto the bar as they are supposed to.
I've been taking bits out and putting bits in for long enough now that I could have probably created my own by now haha, but I really want to figure out what it is I'm missing.
Any help would be amazing!

Nav not collapsing when a NavItem is selected on mobile devices

I'm building a navbar that is expected to be responsive when it switches to mobile devices. In other words, collapse when mobile, then when the navitems are selected / clicked, it should route to the path and collapse all navitems to a toggle-style bar. However, below a snapshot of what I got and it's associated code:
CODE:
render() {
return (
!this.state.isAuthenticating &&
<div className="App">
<Navbar fluid collapseOnSelect>
<Navbar.Header>
<Navbar.Brand>
<LinkContainer to="/">
<a>
<img src={logo} alt="logo" height="70" width="75"/>
<p>hybriData</p>
</a>
</LinkContainer>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<Nav pullRight>
{this.state.isAuthenticated
? <Fragment>
<LinkContainer to="/settings">
<NavItem>Settings</NavItem>
</LinkContainer>
<NavItem eventKey={1} onClick={this.handleLogout}>Logout</NavItem>
</Fragment>
: <Fragment>
<LinkContainer to="/About Us">
<NavItem eventKey={2}>About Us</NavItem>
</LinkContainer>
<LinkContainer to="/Contact">
<NavItem eventKey={3}>Contact</NavItem>
</LinkContainer>
<LinkContainer to="/works">
<NavItem eventKey={5}>Works</NavItem>
</LinkContainer>
<LinkContainer to="/signin">
<NavItem eventKey={6}>SignIn</NavItem>
</LinkContainer>
</Fragment>
}
</Nav>
</Navbar.Collapse>
</Navbar>
</div>
);
}
I also integrated some of this solution react-bootstrap how to collapse menu when item is selected using the expanded and onSelect props of the navbar and nav's activeKey and onSelect props to achieve desired functionality but to no fruition. How can I implement desired functionality of having all navitem's collapsed when any path(s) is navigated to , clicked / selected? Thank you
Here is a simplified working example. It's about the order of items. If you look at the bootstrap CSS, you see some styles like
.nav > li {
position: relative;
display: block;
}}
The > symbol is a selector that selects all immediate descendants or children (first 'wrap layer' only, not applied to second 'wrap layer'), namely if you have
<ul class="nav">
<div>
<li>something</li>
<li>something</li>
</div>
</ul>
the styles are not applied, while
<ul class="nav">
<li>something</li>
<li>something</li>
</ul>
works. In your case, try replacing the <Fragment> with <Nav> and remove the outer <Nav>.
Another part you may want to modify is the LinkContainer wrapping the NavItem part. Usually we have <li> (NavItem) wrapping <a> (Link) but not the other way round.
Although react-bootstrap makes the code easier to read, it abstracts the details and may be harder to get something working. If you have difficulty with react-bootstrap, I suggest you to stick with pure bootstrap elements. The codes are slightly longer but the appearance is the same. You can follow w3schools to use bootstrap styles.

How to check if the route is active?

I want different color on my nav when its in my homepage. How to check if the homepage route is active, than i want to give different styles on my navbar ? (if else statement). I've tried to use window.location.href. It works, but i have to refresh my page first.
$(function() {
if (window.location.href.indexOf("/") > -1) {
$('nav').addClass('nav-scroll');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<Navbar default collapseOnSelect fixedTop>
<Nav pullRight>
<Navbar.Brand>
<Link to="/">WakafKita</Link>
</Navbar.Brand>
<Navbar.Toggle />
</Nav>
<Navbar.Collapse>
<Nav pullLeft>
<NavItem eventKey={1} componentClass={Link} href="/" to="/">
Beranda
</NavItem>
<NavItem eventKey={2} componentClass={Link} to="/menu">
Menu
</NavItem>
<NavItem eventKey={3} componentClass={Link} to="/menu">
Menu
</NavItem>
<NavDropdown eventKey={4} title="Akun" id="basic-nav-dropdown">
<MenuItem eventKey={4.1} componentClass={Link} href="/masuk" to="/masuk">Masuk</MenuItem>
<MenuItem eventKey={4.1} componentClass={Link} href="/daftar" to="/daftar">Daftar</MenuItem>
</NavDropdown>
</Nav>
<Navbar.Form className="navInput">
<form>
<FormGroup>
<InputGroup>
<InputGroup.Addon className="nbg">
<Glyphicon glyph="search" />
</InputGroup.Addon>
<FormControl type="text" placeholder="Cari Judul, Nama, atau Campaign" />
</InputGroup>
</FormGroup>
</form>
</Navbar.Form>
</Navbar.Collapse>
</Navbar>
If you are using react router version4, then you must be getting history as props and you can check the active route with the help of:
history.pathname
Or else you can go javascript way
window.location
If you are using react-router4 you should able to use Link component for navigation also this component includes props like activeClassName and activeStyle that help you to modify active mode.
for more information visit :
Active links tutorial

Hide collapse navbar after link click, react-redux, react-bootstrap

I'm beginner in react, so, need your help.
I used collapsible bootstrap navbar, have no ideas how to make it collapse after link click on mobile. Native bootsrap property collapseOnSelect not working, or i did something wrong.
const AppBar = () => (
<Navbar collapseOnSelect>
<Navbar.Header>
<Navbar.Brand>
<div className="logo-wrap">
<Link to="define">
<img height='50' src='./../assets/img/logo.png' className="logo"/>
</Link>
</div>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<Nav>
<LinkContainer to="define" className="nav-link"><NavItem eventKey={1}>Home</NavItem></LinkContainer>
<LinkContainer to="about" className="nav-link"><NavItem eventKey={1}>About</NavItem></LinkContainer>
<LinkContainer to="features" className="nav-link"><NavItem eventKey={1}>Features</NavItem></LinkContainer>
<LinkContainer to="pricing" className="nav-link"><NavItem eventKey={1}>Pricing</NavItem></LinkContainer>
<LinkContainer to="areaMap" className="nav-link"><NavItem eventKey={1}>Area Map</NavItem></LinkContainer>
</Nav>
<Nav pullRight>
<LinkContainer to="login" className="nav-link"><NavItem eventKey={2}>Log In</NavItem></LinkContainer>
<LinkContainer to="registration"><NavItem eventKey={2}><Button className="sign-up">Sign Up</Button></NavItem></LinkContainer>
</Nav>
</Navbar.Collapse>
</Navbar>
);
export default AppBar;
const [expanded, setExpanded] = useState(false);
Second in the Navbar we add this prop:
<Navbar expanded={expanded}>
Third, we add an onClick event to the toggle handler that changes the menu visibility status:
<Navbar.Toggle onClick={() => setExpanded(expanded ? false : "expanded")} />
Fourth we add the prop
<Link to="/" onClick={() => setExpanded(false)}>Menu</Link>

Resources