Material UI hide element onClick or when checkbox is checked - reactjs

I'm trying to hide element when button is clicked or when checkbox is checked. I tried to Google the solution but can't find anything. Can anyone help with this?
I want to hide that first MenuItem which has Input inside of it and it needs to be hidden when Button is clicked which is inside of second MenuItem or Checkbox is checked which is inside of third MenuItem. Also it needs to return back to normal when clicking Button again, or when checkbox is not checked.
<MenuItem>
<Input />
<MenuItem/>
<MenuItem>
<Button onClick={handleClick}>
Hide onClick!
</Button
</MenuItem
<MenuItem>
<Checkbox />
</MenuItem>
I assume I need to do something like this. Inside handleClick I need to set input MenuItems display to none.
const [hide, setHide] = useState(false);
const handleClick = () => {
}
So basically I think I need to change style of element onClick or checked. I don't have much to show because I don't have any clue how to do that.

change this
<MenuItem>
<Input />
<MenuItem/>
to this
{ hide && (<MenuItem>
<Input />
<MenuItem/>) }
and the function must be like this
const handleClick = () => {
setHide(prev => !prev)
}

use the conditional rendering for this.
{hide && (
<MenuItem>
<Input />
</MenuItem>
)}
now, whenever the hide state is true, <Input/> menuItem will be rendered and for false, it'll be hidden.
To mutate the hide state from both CheckBox and Button, create a handler that will set the state.
const toggleHide = () => {
setHide((oldState) => !oldState);
};
Now call this toggleHide function on the click of the Button and onChange of the Checkbox.
Note:- for better result onClick listeners can be added to the MenuItem instead of the Button and CheckBox.

Related

Unable to Stop Propogation of Checkbox when on top of Collapse with Antd 4.x Library

I am using Antd 4.x library. I have a Collapse and a popover that shows on Click of button on Collapse which has a Checkbox in it. I would like to Stop Propagation when checking/unchecking the checkbox, i.e. the Collapse opens/closes when checking/unchecking
Although when I click on Label of Checkbox the Collapse doesn't open/close but when the I do it on the checkable part of checkbox it happens.
I would like to Stop the open/close of Collapse when checking/unchecking of checkbox on popover
Demo Link to show the issue
TIA
You can wrapped your Panel extra content in a div and add onClick to stopPropagation. Also, you do not have to handle stopPropagation in Setting Button & Checkbox.
const onChange1 = (e: { target: { checked } }) => {
console.log(`checked = ${e.target.checked}`);
};
const genExtra = () => (
<div onClick={(e) => e.stopPropagation()}>
<Popover content={<Checkbox onChange={onChange1}>Checkbox</Checkbox>} title='Title'>
<SettingOutlined />
</Popover>
</div>
);
First of all, you have to understand that when an event occurs, the event always has an event source, that is, the object that caused the event. An event cannot be generated out of thin air. This is the occurrence of an event.
When the event occurs, the event will start to propagate. In your case, when we click the checkbox, a click event will be generated, but the checkbox cannot handle this event. The event must be propagated from the checkbox to reach the code that can handle the event. (for example, we assign a function name stopPropagation to the Fragment's onClick property, which is to let "stopPropagation" handle the Chekbox's click event).
import React, { Fragment } from "react";
function stopPropagation(e) {
//The stopPropagation() method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases.
if (e && e.stopPropagation) {
e.stopPropagation();
} else {
//If it is IE browser
window.event.cancelBubble = true;
}
}
const genExtra = () => (
<Fragment onClick={(e) => stopPropagation(e)}>
<Popover
content={<Checkbox onChange={onChange1}>Checkbox</Checkbox>}
title="Title"
>
{/* <Button type="primary" shape="circle" icon={<SearchOutlined />} /> */}
<SettingOutlined
onClick={(event) => {
event.stopPropagation();
}}
/>
</Popover>
</Fragment>
);
For your reference: https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

The action menu is not getting closed even if I click somewhere on page, the menu remains open until I explicitly click on the Action button again

//This is dropdown component
const Dropdown: FC<any> = ({ list, item, title },props) => {
const isDisabled = item && item.users.length > 0 ? false : true;
const [show, setShow] = useState(false);
const toggleMenu = () => {
setShow(!show);
};
return (
<div>
<Button
title={title || "Action"}
onClick={toggleMenu}
iconName="downarrow"
iconPosition="left"
variant="outlined"
color="primary"
/>
)
The action menu is not getting closed even if I click somewhere on page, the menu
remains open until I explicitly click on the Action button again.
If you want the action menu to close when you click anywhere on the page using onClick won't help it. Use onBlur and use it on the button as -
<Button
title={title || "Action"}
onClick={toggleMenu}
onBlur={() => setShow(true)}
iconName="downarrow"
iconPosition="left"
variant="outlined"
color="primary"
/>
Or alternatively, what you can do is -
Create a reference to your outer div.
Add event listener mousedown (or click) to the document whenever this component appears on screen (eg. mount) and also don’t forget to remove the event on unmount too.
Inside the event (handleClick) this.{Any ref name you give}.contains(e.target) will return true if whatever you are clicking is inside the “node” ref.
Now you have it, you can now do whatever you feel like, close the modal, close the dropdown menu list, anything is allowed.
The above 4 points were taken from the article - https://medium.com/#pitipatdop/little-neat-trick-to-capture-click-outside-react-component-5604830beb7f.

Using hover and click in materia ui ToolTip causes issues in closing the tooltip

I am able to use hover and click functionality separately in material ui Tooltip.
Now i want following functionality using both.
when i hover the tooltip should open. If i click the tooltip should remain open unless i close it.
I have done following to achive hover and onclick
1. initially disableHoverListener is false as a result am able to show tooltip on hover
2. when i click on the button to open the tool tip i set open = true. The tooltip remains open. If i try to close the tool tip am able to set the open = false. but the tooltip doesnot close until i move the mouse.
Can someone guide me in solving the problem
Here is the code for whatever I could understand from your description.
You want the tooltip to show on hover (default behaviour). But if you make it controlled component. i.e you want to set open true on click and false otherwise the default behaviour won't work.
Working Example: CodeSandbox
Here's code hope it helped.
const [show, setShow] = React.useState(false);
const handleClick = () => {
if (show) {
setShow(false);
} else {
setShow(true);
}
};
return (
<div
style={{ display: "inline" }}
onMouseOver={() => setShow(true)}
onMouseLeave={() => setShow(false)}
>
<Tooltip title="You want to see me!" open={show} onClick={handleClick}>
<IconButton aria-label="delete">
<DeleteIcon />
</IconButton>
</Tooltip>
</div>
);

Material UI Popper over TextField how to keep popper open if the popper options are selected

I am using React Material UI, and I have a Textfield which if I focus on it will deploy a Popper with a simple Menu. If the Textfield loses the focus then the Popper closes itself. The thing is I need to select any option from the menu without close the Popper, but when I do that the Textfield loses the focus. What I need is to keep the Popper on only if I click outside of the Textfield or the Menu.
Everything is on this codesandbox.
I tried this:
const selected = prop => {
console.log(prop);
}
...
<Paper elevation={3} className={classes.paper}>
<MenuList>
<MenuItem onClick={() => selected('first')}>
First Option
</MenuItem>
<MenuItem onClick={() => selected('next')}>
Next Option
</MenuItem>
<MenuItem onClick={() => selected('last')}>
And Last Option
</MenuItem>
</MenuList>
</Paper>
</Popper>
Also tried with ClickAwayListener wrapping both components, the TextField and the Popper:
<ClickAwayListener onClickAway={blur}>
<>
<TextField ... />
<Popper ...>
...
</Popper>
</>
</ClickAwayListener>
Unsuccessfully both times... How can I achieve this?
Although the solution by #Dekel is working well enough.
But in my opinion, it would be better if we would use React.useRef() for focusing on the text field.
Here is the updated solution link:
https://codesandbox.io/s/goofy-frost-bb88l?file=/src/MyApp.js
const textFieldRef = React.useRef();
Inside return ()
<TextField
aria-describedby={id}
onFocus={focus}
onBlur={blur}
placeholder="Focus on me"
inputRef={textFieldRef}
/>
On selecting any menu list item
const selected = event => {
console.log("Selected ", event.target.innerText);
textFieldRef.current.focus();
};
I think it's best to implement this using the Autocomplete, but since the OP requested another solution - here is another option:
Once blur - check the element that caused the blur. If that element is one of the items in the popper - don't blur:
if (e.relatedTarget && e.relatedTarget.classList.contains("MuiListItem-root")) {
return;
}
The full blur function will look like this:
const blur = (e) => {
if (e.relatedTarget && e.relatedTarget.classList.contains("MuiListItem-root")) {
e.target.focus();
return;
}
setAnchorEl(null);
};

material UI CardHeader action drop-down

I am trying to add a FormControl, a Select component and a MenuItem to the action prop of the CardHeader IconButton.
Currently the code looks like this:
Rendering:
<CardHeader
action={
<IconButton
onClick={this.renderFilterRequest()}
>
<Edit />
</IconButton>
}
/>
onClick method:
renderFilterRequest() {
const { selection } = this.state;
return (
<div>
<FormControl>
<Select
value={selection}
onChange={this.handleFilterChange}
>
<MenuItem value='1'>January</MenuItem>
<MenuItem value='2'>February</MenuItem>
</Select>
</FormControl>
</div>
);
}
The error I get is onClick listener to be a function, instead got a value of object type. What is the right way to render the dropdown menu on CardHeader action click?
You are returning some div from from this.renderFilterRequest, And you are also calling the function, so the value of onClick becomes the div. But they were meant to be functions, right?
So it should have been just: onClick={this.renderFilterRequest}.
This function also returned a div but there is no way to attach it to rendering logic in render.
You need to put the MenuItems in your render method and show/hide them depending on the state.
Your onClick listener should be a function that changes the state so that the MenuItems become visible.
Here is a simple demo how this should be done:

Resources