I wanted to load react navbar submenu on mouseover instead of click.
https://react-bootstrap.github.io/components/navbar/
import { Nav,NavDropdown,Navbar } from "react-bootstrap";
<Navbar bg="light" expand="lg">
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav>
<NavDropdown title="Beneficiary" id="basic-nav-dropdown" className="Dropdown">
<NavDropdown.Item onClick={() => this.recordList('Approved List',this.state.approvedRecords)}>Approved</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item onClick={() => this.recordList('Rejected List',this.state.rejectedRecords)}>Rejected</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item onClick={() => this.recordList('Referred Back List',this.state.refBackRecords)}>Referback</NavDropdown.Item>
</NavDropdown>
</Nav>
</Navbar.Collapse>
</Navbar>
Any help would be appreciated.
Here, I played with it for a minute
so as I first suggested we would add a local const and a function for handling dropdown visibility
const [visible, setVisible] = useState(false);
const handleHover = () => {
setVisible((prevVisible) => (prevVisible = !prevVisible));
};
And then simply
<Navbar.Collapse id="basic-navbar-nav" onMouseEnter={handleHover}>
<Nav>
<NavDropdown
title="Beneficiary"
id="basic-nav-dropdown"
className="Dropdown"
show={visible}
>
...
As I suspected you'll have to handle the mouseleave event as well, so far in my function
setVisible((prevVisible) => (prevVisible = !prevVisible));
we're toggling the visibility on mouseenter, but you get the gist :)
LMK if I can help any further, or if you come across a better solution
Well, according to their docs, that cannot be done out of the box..
You could add your own function to NavDropdown on Mouseenter.. Provided you're using react hooks it would be something like
const [isDropdownVisible, setDropdownVisible] = useState(false);
const handleHover = () => {
setDropdownVisible(true)
}
Of course you'll have to set submenu to be visible={isDropdownVisible}
and then on a parent you could just say onmouseenter={handleHover}
You might have to handle onmouseleave as well, I'm not sure.
Hope this will be a valuable guideline :)
Good luck
Related
I am using react, I am building a single page application and I don't want to use react-router
I just have one page and sections , and a hash for each section (or component in react ) , I want the active navigation-link to change on scroll, or I want to change the window location hash on scroll so that the active class will work on scroll....
please help
const ref = React.useRef(null);
const handleScroll = () => {
if (ref.current ) {
setSticky(ref.current.getBoundingClientRect().top <= 0);
}
};
React.useEffect(() => {
window.addEventListener('scroll', handleScroll);
window.addEventListener("scroll", () => {
setScroll(window.scrollY > 200 );
});
return () => {
window.removeEventListener('scroll', () => handleScroll);
};
}, []);
return (<Container fluid className='p-0'>
<Navbar ref={ref} fixed={isSticky ? 'top': '' } className='nav_bar ' expand="lg">
<Navbar.Toggle aria-controls="basic-navbar-nav" ><FontAwesomeIcon style={{color:'#fff'}} icon={faBars}/></Navbar.Toggle>
<Navbar.Collapse id="basic-navbar-nav">
<Nav className='ml-5'>
<Nav.Item>
<Nav.Link className={`${scroll ? 'active':''} nav_link px-5`} href="#home">home</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link className={`${scroll ? 'active':''} nav_link px-5`} href='#about' >about</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link className={`${scroll ? 'active':''} nav_link px-5`} href='#portfolio' >portfolio</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link className={`${scroll ? 'active':''} nav_link px-5`} href='#contact' > contact
</Nav.Link>
</Nav.Item>
</`Nav`>
</`Navbar.Collapse`>
</`Navbar`></Container>
);
}
i tried this method but i failed and all links show active at once
There is a Link component in react scroll which comes with 3 props: activeClass,spy and to.
activeClass->change the style of list element in navbar when scroll is over
the component.
spy -> tell react-scroll to make which element active or apply activeClass to
which element.
to->is the element it should scroll to.
An example of how to wrap element.
<Link activeClass="active" smooth spy to="about">About </Link>
Related to this question, whose top answers no longer work. By default, the NavDropdown only appears when clicked on, however I need this dropdown to display on hover. I struggled loading 'React-Bootstrap' into stackoverflow to create a reproducible example, however here is a basic Navbar using react-bootstrap, that features my attempt to display the dropdown on hover:
const [isStatsOpen, setIsStatsOpen] = useState(true);
<Navbar>
<Navbar.Brand>
<Link to='/'>
<img alt='company logo' src={My Logo} />
</Link>
</Navbar.Brand>
<Navbar.Toggle aria-controls='basic-navbar-nav' />
<Navbar.Collapse id='basic-navbar-nav'>
<Nav className='mr-auto'>
<NavDropdown title='Statistics'
onMouseEnter={() => setIsStatsOpen(true)}
onMouseLeave={() => setIsStatsOpen(false)}
open={isStatsOpen}
>
<NavDropdown.Item as={Link} to='/stats/'> Stats 1</NavDropdown.Item>
<NavDropdown.Item as={Link} to='/stats2/'>Stats 2</NavDropdown.Item>
</NavDropdown>
</Nav>
<Nav className='ml-auto'>
<DivisionSelect />
<AppSelect />
</Nav>
</Navbar.Collapse >
</Navbar >
From the linked post above, there were 2 responses with 10+ votes, however neither of these solutions work. As it pointed out in one of the comments: This doesn't work in newer versions, the dropdown isn't rendered until it's first click. You'd need to trigger the onclick before you could control via css.
After inspecting the page, I can confirm that this person is correct - there is no menu for which to display until after the NavDropdown has been clicked upon. Once clicked, the menu is there, and then the solutions from this other post do work. Given this as the case, how can I resolve this issue? Is it possible for my react component to automatically "click" the Navdropdowns on load, that way the menus will appear on hover?
Thanks!
Does this help you? Old good vanilla javascript.
I added an id at NavDropdown and called the old, classic document.getElementById method and then triggered the click event.
useEffect(() => {
document.getElementById("test").click();
}, []);
<NavDropdown
id="test"
title="Statistics"
https://codesandbox.io/s/react-bootstrap-demo-z36c5
In this link to the earlier version of the question, the highly voted answer that starts with export class Nav extends React.Component { does work, so long as the open prop is updated to show.
I am having a profile page on my site where the user can select the menu from dropdown. And I am having the same menu set in same page as "side menu" user can select from either one. My problem is if the user selects from the drop-down it is not navigating to that particular menu. Could anyone help me to achieve this? Below is the code I have tried please anyone correct me if I am doing something wrong in below code. If the user clicks from the side menu it is navigating properly. I have written different components for that. But if the user tries to navigate the menu from the same page the menu is not navigating.
function HeaderMenu(props: any) {
const handleProfile = (hashTag: any) => {
Router.push(`/MyDetails${hashTag}`);
}
return (
<div>
<header className={styles.headerClass}>
<Navbar className={`${styles.navbar}`} variant="dark" expand="lg">
<Navbar.Toggle onClick={() => setSideMenuOpen(!sideMenuOpen)} aria-controls="basic-navbar-nav" />
<Col md="12" lg="3">
<ul className={styles.resetList}>
<li>
<Button variant="link" onClick={() => handleProfile('#Schooling')}></Button>
</li>
<li>
<Button variant="link" onClick={() => handleProfile('#College Details')}>
</Button>
</li>
<li>
<Button variant="link" onClick={() => handleProfile('#Project')}></Button>
</li>
<li>
<Button variant="link" onClick={() => handleProfile('#settings')}></Button>
</li>
<li>
<Button variant="info" onClick={() => handleLogout()}>Sign out</Button>
</li>
</ul>
</NavDropdown>
export default connect(mapStateToProps)(Header);
React's HashRouter has an history state in props. To navigate to another page, you can use something like;
redirect = (path) => {
this.props.history.push(path);
}
You can also provide parameters (ie.: http://localhost:1337#profile?id=AB123) like so;
redirect = (path, param) => {
this.props.history.push({
pathname: path
search: param
});
}
Hope it helps.
I am very new to React Bootstrap and exploring how much it is customizable. While it's easy to hook into onSelect, I can't find any way to cancel the action itself. For example, if user has unsaved changes and should not go to the other route, then how onSelect can be prevented?
This is from React Bootstrap docs with a little change:
import React from 'react';
import {Navbar, Nav, NavItem, NavDropdown, MenuItem} from 'react-bootstrap';
// import './Header.scss';
function myOnSelect(eventKey, event) {
console.log(eventKey);
console.log(event);
alert(`Going ${eventKey}`);
return false // How to prevent from going there???
}
export const Header = props => {
const {brand} = props.topNav;
return (
<Navbar collapseOnSelect expand="sm" bg="light" variant="light" sticky="top"
onSelect={myOnSelect}>
<Navbar.Brand href="#home">{brand}</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav"/>
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="mr-auto">
<Nav.Link href="#features">Features</Nav.Link>
<Nav.Link href="#pricing">Pricing</Nav.Link>
<NavDropdown title="Dropdown" id="collasible-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>
<Nav>
<Nav.Link href="#deets">More deets</Nav.Link>
<Nav.Link eventKey={2} href="#memes">
Dank memes
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
);
};
Note: I do not mean going away to completely another page via a link, just another route inside the same page. It can be for "unsaved changes" or some other temporary reason, so disabling navbar menus is an overkill from UX point of view.
Extra twist to this is the project is going to use react-observable (with Redux and RxJS) for event/action logic, so it would be nice to understand how easy it is to hook React Boostrap into it. That is, some actions will need to be intercepted and handled in the epics and other middleware instead of following default React Bootstrap automation. So:
The example here can have some very specific solution, but could be nice to also hear how easy it is to do action-interceptions in other places of React Bootstrap or whether the javascript logic should be heavily customized or even abandoned.
I guess, for Navs the answer is somewhere in these arrangements: https://github.com/react-bootstrap/react-bootstrap/blob/master/src/AbstractNavItem.js
Maybe explicitly set activeKey property together with event.preventDefault(); can be used to build the desired control over nav.
We cannot stop the select from performing its onchange property. It will execute as soon as we select an option. Consider adding conditions in the myOnSelect function
function myOnSelect(eventKey, event) {
console.log(eventKey);
console.log(event);
if(condition) {
//do something
alert(`Going ${eventKey}`);
}
else {
//do something else
return false // How to prevent from going there???
}
}
I have a problem with the eventKey thing in NavDropdowns.
var Navigation = React.createClass({
handleSelect: function(eventKey){
console.log(eventKey);
},
render: function() {
return (
<Navbar brand='Navbar' toggleNavKey={0}>
<CollapsibleNav eventKey={0} onSelect={this.handleSelect}>
<Nav navbar>
<NavItem eventKey={1}>Home</NavItem>
</Nav>
<Nav navbar right hide>
<NavItem eventKey={2}>Login</NavItem>
<NavDropdown eventKey={3} title='NavDropdown' id='basic-nav-dropdown'>
<MenuItem eventKey={4}>Action 1</MenuItem>
<MenuItem eventKey={5}>Action 2</MenuItem>
</NavDropdown>
</Nav>
</CollapsibleNav>
</Navbar>
)
}
});
I want to be able in my selectHandler to tell what Nav element was clicked.
This works great for all elements except the NavDropdown:
Clicking the Dropdown does not trigger the selectHandler, which is fine.
But when I click one of the MenuItem, instead of giving me the eventKey, it gives me an event object.
How can I modify the NavDropdown so that it gives me the eventKey?
Edit: My versions are:
"react": "^0.14.0-beta3",
"react-bootstrap": "^0.25.100-react-pre.0",
It is a bug in react-bootstrap
https://github.com/react-bootstrap/react-bootstrap/issues/1268
The callback on onSelect event will receive 2 params. The first one is event obj. The second is EventKey. You can read it in doc. So if you want to get event key, you should try to call it in the second param
handleSelect: function(event,eventKey){
console.log(event)
console.log(eventKey);
},