datepicker is traped inside the button menu - javascript

Hi im new in react and i have been using react-datepicker but i got this problem, i made a custom button that when is clicked it should display the datepicker and well it does it, the problem is that it is trapped inside the menu of the button, and what i need is it to popout outside the menu (actually i need to close the menu when selected and just see the datepicker)
any kind of help would be apreciated
as you can see my datepicker is inside a menu
this is my menu and datepicker code
<Menu
className="main-toolbar__menu"
anchorEl={this.state.anchors.options_settings}
open={Boolean(this.state.anchors.options_settings)}
onClose={() => this.handleDropdownClose('options_settings')}
>
<MenuItem
onClick={() => {
this.toggleCalendar()
}}
>
<DatePicker
customInput={<ExampleCustomInput />}
selected={this.state.startDate}
onChange={this.handleChange}
/>
</MenuItem>
<MenuItem
onClick={() => {
this.handleModal('addNotificationModal', true)
this.handleDropdownClose('options_settings')
}}
>
<span>Notification Preferences</span>
</MenuItem>
</Menu>

You can Move your datepicker outside the Menu component and toggle it based on the toggle logic and a ternary expression.
state = {
showCalendar:false
}
toggleCalendar = () => {
this.setState({showCalendar:!this.state.showCalendar})
//or whatever logic you have for toggleCalendar already
}
{this.state.showCalendar ? <DatePicker
customInput={<ExampleCustomInput />}
selected={this.state.startDate}
onChange={this.handleChange}
/> : null }
<Menu
className="main-toolbar__menu"
anchorEl={this.state.anchors.options_settings}
open={Boolean(this.state.anchors.options_settings)}
onClose={() => this.handleDropdownClose('options_settings')}
>
<MenuItem
onClick={() => {
this.toggleCalendar()
}}
>
</MenuItem>
<MenuItem
onClick={() => {
this.handleModal('addNotificationModal', true)
this.handleDropdownClose('options_settings')
}}
>
<span>Notification Preferences</span>
</MenuItem>
</Menu>

Related

How to make Sider selected key be responsive?

What I'm trying to do is get which is the key of the sider the user is using (without ReactDOM and with functional components)
my sample code here:
export default function DrawerSider() {
const history = useHistory();
const [selectedKey, setSelectedKey] = useState("sub1")
const handleSelectKey = function(key, history_string) {
setSelectedKey(key)
history.push(history_string)
console.log(key)
}
return (
<Sider width={200} className="site-layout-background">
<Menu
defaultSelectedKeys={selectedKey}
mode="inline"
style={{ height: "100%", borderRight: 0 }}
>
<Menu.Item
key="sub1"
icon={<HomeOutlined />}
onClick={() => handleSelectKey("sub1","/dashboard/resumo")}
>
Dashboard
</Menu.Item>
<SubMenu key="sub2" icon={<UserOutlined />} title="Usuários">
<Menu.Item
key="1"
icon={<PlusCircleOutlined />}
onClick={() => handleSelectKey("1","/usuarios/novo")}
>
Adicionar usúario
</Menu.Item>
<Menu.Item
key="2"
icon={<TableOutlined />}
onClick={() => handleSelectKey("2","/usuarios/todos")}
>
Todos usúarios
</Menu.Item>
</SubMenu>
<SubMenu key="sub3" icon={<FormOutlined />} title="Formulários">
<Menu.Item
key="3"
icon={<PlusCircleOutlined />}
onClick={() => handleSelectKey("3","/formularios/novo")}
>
Adicionar formulário
</Menu.Item>
</SubMenu>
</SubMenu>
</Menu>
</Sider>
);
}
Obs: I'm using ant design lib
Someone knows how to make it works?
I tried to use a const on click event to set a state of the selected key , but it didn't work
There is no onClick on Menu.Item
only Menu component has onClick or onSelect, both will give you callback of the "clicked" key, the differences is onClick is for any menu item click (including expanding menu) while on select is when you select an actual menu item.
There are 2 ways to get the history string:
1 - use the history string as menuItem key:
the issue would be you cannot have 2 menu item that has same history key
2 - have a map which maps the menu key to history string
see below demo:
https://codesandbox.io/s/inline-menu-antd-4-18-2-forked-bgwyj?file=/index.js
const handleOnSelect = ({ item, key, keyPath, selectedKeys, domEvent }) => {
console.log(item);
console.log(keyPath);
console.log(selectedKeys);
console.log(domEvent);
handleSelectKey(key);
};
...
..
<Menu
onSelect={handleOnSelect}
...
>
...
</Menu>
You need to save the selected key as part of the component's state. You can set the current selected key as part of the onClick.
const selectedKey, setSelectedKey = useState("defaultSelectedKey")
Not sure what the useHistory hook is for but if you need to set that onClick as well as the selectedKey, move it all into one function like so
const handleSelectKey = function(key, history_string) {
setSelectedKey(key)
history.push(history_string)
}
...
onclick={() => handleSelectedKey("3", "/usuarios/novo")}
https://ant.design/components/menu/
EDIT
Based on research into your design library, your onclick and handle select must be at the top level of the menu component. Just copy the syntax that they use in their example code.
https://ant.design/components/menu/

Reactjs onClick <MenuItem> passing INT instead of STRING

Below given code is using material-ui with reactjs. I am filtering the information of products through this sidebar function. In which there are 2 filers size and color. When we click on Expansion Panel, options will displayed and than we click on desired option (which is not returning the selected color). On the other hand same Expansion Panel is returning the correct selected "size". What i can do so that onClick={colorReducer} function return correct color. Any help will be appreciated
const Sidebar = () => {
const [size, setSize] = React.useState(0);
const [color, setColor] = React.useState("");
const sizeReducer = (e) => {
setSize(e.target.value); //This is working fine
};
const colorReducer = (e) => {
console.log(color); //It gives 0 as output, instead of selected color (type string)
setColor(e.target.value);
};
return (
<div className={classes.div}>
<ExpansionPanel>
<ExpansionPanelSummary>
<InputLabel id="label">Size</InputLabel>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<ListItem>
<MenuItem value="6" onClick={sizeReducer}>
6
</MenuItem>
<MenuItem value="7" onClick={sizeReducer}>
7
</MenuItem>
<MenuItem value="8" onClick={sizeReducer}>
8
</MenuItem>
<MenuItem value="9" onClick={sizeReducer}>
9
</MenuItem>
</ListItem>
</ExpansionPanelDetails>
</ExpansionPanel>
<ExpansionPanel>
<ExpansionPanelSummary>
<InputLabel id="label">Color</InputLabel>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<ListItem>
{setColors.map((val) => (
<MenuItem value={val} onClick={colorReducer}> //This is not returning "0", instead of color
{val}
</MenuItem>
))}
</ListItem>
</ExpansionPanelDetails>
</ExpansionPanel>
</div>
);
};
export default Sidebar;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<MenuItem> renders to <li> element. Interestingly, value is an allowed attribute for li but it can only take numbers. That's why it works for setSize but doesn't for setColor.
A proper way to do what you want is not to relegate to DOM but stay in React-land. So, instead of reading from event.target, you should provide value in a handler:
<MenuItem onClick={() => setColor(val)}>
{val}
</MenuItem>
{setColors.map((val) => (
<MenuItem value={val.toString()} onClick={colorReducer}>
{val}
</MenuItem>
))}
Update this part, you've passed int value in above mentioned part of code.

Not able to select Item from Semantic-ui-react Search In-Menu Dropdown / Formik

I am struggling with Search In-Menu dropdown in semantic ui react library
https://react.semantic-ui.com/modules/dropdown/#types-search-in-menu
I am doing this
<Dropdown
name='customRoomType'
id='customRoomType'
text={values.customRoomType} //tried onchange here but not works
>
<Dropdown.Menu>
<Dropdown.Menu scrolling>
{tagOptions.map((option) => (
<Dropdown.Item key={option.value}
className={option.value}
onChange={(e, { value }) => {
{console.log('value ',value)}
setFieldValue('customRoomType', value)
}}
onBlur={handleBlur}
selectonblur={'false'}
{...option} />
))}
</Dropdown.Menu>
</Dropdown.Menu>
</Dropdown>
Dropdown selection doesn't trigger any event handler
I took this React semantic-ui Dropdown onChange not working as a reference but this link doesn't help
You put the onChange and onBlur events on <Dropdown.Item> instead of on <Dropdown>
Try if it works like this:
<Dropdown
name='customRoomType'
id='customRoomType'
// Check here that this is the same value that you set in onChange handler.
text={values.customRoomType}
// onChange and onBlur are parts of Dropdown and not of Dropdown item
onChange={(e, { value }) => {
{console.log('value ',value)}
setFieldValue('customRoomType', value)
}}
onBlur={handleBlur}
>
<Dropdown.Menu>
<Dropdown.Menu scrolling>
{tagOptions.map((option) => (
<Dropdown.Item key={option.value}
className={option.value}
// might also be moved.
selectonblur={'false'}
{...option} />
))}
</Dropdown.Menu>
</Dropdown.Menu>
</Dropdown>

Material UI+React hovering on tabs will not open and close properly

currently I am working on a project with React and Material UI. I want to hover on tabs that will open an menu, but this doesn't really work. I am hoping that you guys can help me (and maybe tell me if I'm approaching this correctly)
Where my tabs are basing of: https://imgur.com/a/HeiL2xo
My current project: https://imgur.com/a/Ik5NEkF
AppBarTop class
class AppBarTop extends Component {
state = {
value: 0,
open: false,
anchorEl: null
};
handleMenuClick = (index) => {
}
handleMenuOpen = (index, event) => {
const {currentTarget} = event;
this.setState({
open: !this.state.open,
anchorEl: currentTarget,
value: index
})
};
handleMenuClose = () => {
this.setState({
open: false,
anchorEl: null,
})
}
handleInputSearch = () => {
};
render() {
const {classes} = this.props;
const {anchorEl, open} = this.state;
return (
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<img src={buddies} alt={"buddies"} height={50} width={50}/>
<div className={classes.grow}/>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon/>
</div>
<InputBase
placeholder="Search…"
onChange={this.handleInputSearch}
classes={{
root: classes.inputRoot,
input: classes.inputInput
}}
/>
</div>
<div className={classes.grow}/>
<List>
{TopMenu.map((item, index) => (
<Tab key={index} component={Link} to={{pathname: item.pathname}}
classes={{root: classes.tabItem}} label={item.label}/>
))}
</List>
</Toolbar>
<Paper className={classes.grow}>
<Tabs
value={this.state.value}
indicatorColor="primary"
textColor="primary"
centered>
{BottomMenu.map((item, index) => (
<Tab
key={index}
onMouseOver={this.handleMenuOpen.bind(this, index)}
data-key={index}
classes={{root: classes.tabItem}}
label={item.label}
aria-owns={open ? 'menu-list-grow' : undefined}
aria-haspopup={"true"}/>
))}
</Tabs>
<Popper open={open} anchorEl={anchorEl} id="menu-list-grow">
<Paper>
<MenuList>
{BottomMenu[this.state.value].items.map((item, index) => (
<MenuItem key={index} onClick={this.handleMenuClose}>{item}</MenuItem>
))}
</MenuList>
</Paper>
</Popper>
</Paper>
</AppBar>
</div>
);
}
}
export default withStyles(styles)(AppBarTop)
The key problem here is that the onMouseOver event handler is fired multiple times as you move around the <Tab> component. Your handleMenuOpen function is not built to handle this.
I've replicated your issue in a CodeSandbox here: https://codesandbox.io/s/qkw8rr4mk4
The following 3 points will fix your menu issues:
Change handleMenuOpen to be functional by explicitly setting open: true
Use onMouseEnter rather than onMouseOver. This is not required but it makes for more predictable functionality as onMouseEnter is only called once
To automatically close your menu when your mouse leaves them add the onMouseLeave={this.handleMenuClose.bind(this)} property to your parent <div> component
A CodeSandbox with the above 3 points implemented can be found at: https://codesandbox.io/s/6x9w9m6n7r

React semantic-ui - Closable menu tabular / tab

<Menu tabular>
{
menus.map((menu, index) => (
<Menu.Item
key={index}
name={menu.name}
active={this.props.location.pathname === menu.path}
onClick={() => {this.props.handleOpenClick(menu)}}
>
{menu.name}
<Button onClick={() => {this.props.handleCloseClick(index)}}>X</Button>
</Menu.Item>
))
}
</Menu>
I want to create a dynamic tabular layout with closable feature by using Menu and tabular option. I put the Button component inside a Menu.Item and implement the onClick event.
When the buton is clicked, it's also calling handleOpenClick() function on the Menu.Item component. I need to call the handleCloseClick() only.
Is there any suggestion ?
Sorry for my bad english
Try adding e.stopPropagation().
<Menu tabular>
{
menus.map((menu, index) => (
<Menu.Item
key={index}
name={menu.name}
active={this.props.location.pathname === menu.path}
onClick={() => {this.props.handleOpenClick(menu)}}
>
{menu.name}
<Button onClick={e => {
e.stopPropagation();
this.props.handleCloseClick(index);
}}>X</Button>
</Menu.Item>
))
}
</Menu>

Categories