React-Bootstrap Navbar issue - reactjs

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

Related

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!

How can I align a search box and button in the navigation bar?

I am facing some problems in getting the search text and the search button inline even though I am following a tutorial.
I am using react-bootstrap downloaded using yarn. This is my code in Navigation.js:
return (
<Navbar bg="dark" variant="dark">
<div class="container-fluid">
<Navbar.Brand href="#home">Movies</Navbar.Brand>
<Nav className="me-auto">
<Nav.Link href="#home">Home</Nav.Link>
</Nav>
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="ml-auto">
<Form inline>
<Form.Control type="text" placeholder="Search" className="mr-sm-2" />
<Button variant="outline-success">Search</Button>
</Form>
</Nav>
</Navbar.Collapse>
</div>
</Navbar>
);
In my App.js:
return (
<>
<Navigation/>
</>
);
However, the button is always below the search text. Have tried looking through other tutorials but none of the answers fixed the problem. May I check if anyone knows what is wrong here?

React-Bootsrap navbar dropdown not closing

I'm using React-bootstrap package on my react project.
I tried to use simple navbar with dropdown example from react-bootsrap offical demo page.
Here is the example. Dropdown opening when click to 'dropdown' link but it's not closing when trying to click anywhere outside of dropdown. So it's not behave like on example on demo. What can be problem with that?
<Navbar bg="light" expand="lg">
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link href="#home">Home</Nav.Link>
<Nav.Link href="#link">Link</Nav.Link>
<NavDropdown title="Dropdown" id="basic-nav-dropdown">
<NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
<NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
<NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
</NavDropdown>
</Nav>
<Form inline>
<FormControl type="text" placeholder="Search" className="mr-sm-2" />
<Button variant="outline-success">Search</Button>
</Form>
</Navbar.Collapse>
</Navbar>
It's probably a little late for this but I had the same issue. What I finally ended up doing was adding this:
componentDidUpdate() {
document.getElementById("root").click();
}
This forced a closure as soon as the page was loaded. This was put into my main component, or app.js if you so choose.
HTH

React passing state to children with Navbar

I have a simple react Navbar from bootstrap and I want to pass a userid from the navbar to a child.
I can do that working but when so, the child component is shown twice, once above the navbar and the second time below.
This happens only when I insert this command:
<UserConfig userid={this.state.user.userid} />
Here is a part of my App.js with the navigation
I tried many places to paste it in, but nothing worked
render() {
console.log(this.state.user.userid);
return (
<div className="App container" >
<UserConfig userid={this.state.user.userid} />
<Navbar fluid collapseOnSelect>
<Navbar.Header>
<Navbar.Brand>
<Link to="/">Hallo {jwt_decode(authentication.getAccessToken()).given_name}!</Link>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<Nav pullRight>
<LinkContainer to="/config">
<NavItem >Konfiguration</NavItem>
</LinkContainer>
<LinkContainer to="/logout">
<NavItem>Logout</NavItem>
</LinkContainer>
<LinkContainer to="/callback">
<NavItem>Callback</NavItem>
</LinkContainer>
</Nav>
</Navbar.Collapse>
</Navbar>
<Routes />
</div>
);
}
In my UserConfig.js I just use this.props.userid which shows the value only when the navbar is crashed.....
Could you please help me to get that working?
Actually I just want to pass down the userid from App.js to UserConfig.js WITHOUT destroying my navigation.
UserConfig
render() {
console.log(this.props.userid);
return (
<div className="Login">
<form onSubmit={this.handleSubmit}>
<FormGroup controlId="hersteller" >
<ControlLabel >Hersteller</ControlLabel>
<FormControl
autoFocus
type="text"
value={this.state.hersteller}
onChange={this.handleChange}
/>
</FormGroup>
......
What is the correct way to pass props to NavItem
From this question... try this:
<LinkContainer to="/config">
<NavItem data-userid={this.state.userid} >Konfiguration</NavItem>
</LinkContainer>
I am assuming that is config page you are trying to get the value too? You can then remove the UserConfig component above the navigation (which should remove the double render).

Add a image to React Bootstrap dropdown

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>

Resources