When clicked, the close option won't close the dialog box, and I don't understand why. I did check a few solutions, but those didn't work. I would like to know what I need to do to fix this. The box loads just fine. The screenshot of the box and the code are below:
The code:
const AdvanceFilterScreen = () => {
........
........
const [districtDialogOpen, setDistrictDialogOpen] = useState(false);
const openDialog = () => {
setDistrictDialogOpen(prev => !prev)
};
const closeDialog = () => {
setDistrictDialogOpen(prev => !prev)
};
return (
<div>
{district ? <Dialog open={openDialog} onClose={closeDialog}>
<DialogTitle className="districtOverview">{"District Overview"}</DialogTitle>
<DialogContent>
<div className="overAll">
<DistrictTable district={district} setFilterButtonValue={setFilterButtonValue} ></DistrictTable>
</div>
</DialogContent>
<DialogActions>
<div className="closeButton" onClick={closeDialog}>Close</div>
</DialogActions>
</Dialog>
: <FilterSearchButton name={name} category={category} district={district} status={status} serialNumber={serialNumber} setFilterButtonValue={setFilterButtonValue}></FilterSearchButton>}
</div>
);
};
export default AdvanceFilterScreen;
PS: The idea is to show the dialog box every time the By District option is clicked and a value is selected. If you notice the snip closely, you'll see that behind the dialog box is a dropdown that has Kolkata selected in it as its value. This dropdown appears only when the By District option is clicked
Your condition to open the dialog has issue, just use this:
{districtDialogOpen ? <Dialog open={openDialog} onClose={closeDialog}>
You're displaying the dialog whenever district has a truthy value, and you're not using your districtDialogOpen state value anywhere.
Change this line:
{district ? <Dialog open={openDialog} onClose={closeDialog}>
to:
{districtDialogOpen ? <Dialog open={openDialog} onClose={closeDialog}>
...and you should be good.
Related
I have a problem with a dialog not closing properly.
Dialog open is set to a state variable intialized as true, and immediately changed to false.
The dialog doesn't close properly, and the app does not respond.
I have demonstrated this in the following sandbox where the button can not be clicked, though it should be available.
EDIT:
To make clear. The dialog is not supposed to ever open. But the button outside the dialog (with the text "a button") should be clickable.
https://codesandbox.io/s/adoring-benji-300mcm
This code will work:
export default function App() {
const [open, setOpen] = useState(false);
console.log(open);
return (
<div>
<Dialog open={open} height="100px" width="100px" id="111">
<button onClick={() => setOpen(false)}>close</button>
</Dialog>
<button onClick={() => console.log("click")}>a button</button>
</div>
);
}
You don't need the useEffect to change state immediately, you could just pass false as a desired initial value to the state. Now the button "a button" is working.
EDIT:
To make the code working without removing useEffect, add conditional rendering:
export default function App() {
const [open, setOpen] = useState(true);
useEffect(() => setOpen(false), []);
console.log(open);
return (
<div>
{open && (
<Dialog open={open} height="100px" width="100px" id="111">
<button onClick={() => setOpen(false)}>close</button>
</Dialog>
)}
<button onClick={() => console.log("click")}>a button</button>
</div>
);
}
My best guess is that in your code the Dialogue gets rendered anyways, even though it is not displayed, because at first "open" was true. So in order for it not to be rendered, or to be rendered conditionally, you should check state.
I want to change the appearence of an button after clicking it.
I have tried adding focus: / active:, but react is re-rendering the component on-click, so it doesn't work.
In Javascript I would add an event-handler to every button that would automatically change the appearence after being clicked, how am I able to recreate that in react/tailwind-css, since tailwind is not working with dynamic className changes?
Is there a good practice, or should I add if statements in order to make it work?
This is what I am trying to recreate.
HTML:
<button>MY BUTTON</button>
<button>MY BUTTON</button>
<button>MY BUTTON</button>
JS:
let button_list = document.querySelectorAll("button");
button_list.forEach(element=>{
element.addEventListener("click",function(){
button_list.forEach(remove_background=>{
remove_background.style.background="white";
});
this.style.background="black";
});
});
I would recommend a state variable to store the active button. Here's a simple example:
const ButtonList = () => {
const [activeButtonIndex, setActiveButtonIndex] = useState(0);
return (
<>
<button
className={activeButtonIndex === 0 ? "bg-white" : "bg-black"}
onClick={() => setActiveButtonIndex(0)}
>
My Button
</button>
<button
className={activeButtonIndex === 1 ? "bg-white" : "bg-black"}
onClick={() => setActiveButtonIndex(1)}
>
My Button
</button>
<button
className={activeButtonIndex === 2 ? "bg-white" : "bg-black"}
onClick={() => setActiveButtonIndex(2)}
>
My Button
</button>
</>
);
};
Let's say I have a button that opens a Dialog component. The button has custom theming/styling to specify various states, one of them being the :focus state:
const useStyles = makeStyles({
root: {
"&:focus": {
backgroundColor: "#3A7DA9"
}
}
});
export default function App() {
const [open, setOpen] = useState(false);
const classes = useStyles();
return (
<div className="App">
<Button
id="button-that-opens-modal"
className={classes.root}
onClick={() => setOpen(true)}
>
Open the modal
</Button>
<Dialog open={open}>
<h3>This is the modal</h3>
<Button onClick={() => setOpen(false)}>
Close
</Button>
</Dialog>
</div>
);
}
What I've noticed is that every time I have this pattern, (where a button opens a dialog modal), when the modal is closed, the #button-that-opens-modal is left with a :focus state, which looks bad in terms of styling. Here's a quick gif:
Codesandbox demonstrating the issue
Is this a known issue? I don't see why the :focus should be automatically applied to the button when the modal closes. How can I stop this?
I tried this:
I can add a ref to the button, and make sure to manually unfocus the button in various places. Adding it in the onExited method of the Dialog works, but flashes the focus state for a second:
export default function App() {
const [open, setOpen] = useState(false);
const buttonRef = useRef();
const classes = useStyles();
return (
<div className="App">
<Button
ref={buttonRef}
className={classes.root}
onClick={() => setOpen(true)}
>
Open the modal
</Button>
<Dialog
open={open}
TransitionProps={{
onExited: () => {
buttonRef.current?.blur(); // helps but creates a flash
}
}}
>
<h3>This is the modal</h3>
<Button onClick={() => {setOpen(false)}}>
Close
</Button>
</Dialog>
</div>
);
}
sandbox showing this very imperfect solution
And even if I found exactly the right event handler to blur the button such the styling looks correct, this is not something I want to do for every Dialog in an app that has many Button - Dialog pairs. Is there a Material-UI prop I can use to disable this 'auto-focus' back on the button, rather than having to create a ref and manually .blur it for every Dialog?
This is for accessibilty purpose. You can disable it by adding prop disableRestoreFocus on your Dialog :)
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>
);
I have a box which makes itself visible when a button is clicked. The box has a text field and a button. When that button is clicked, the box must hide again. But my problem is the box hides first and for a split second, i still can see the antd components.
box = () => {
<div style={{visibility: this.state.visibility}}>
<Input type= 'text' />
<Button onClick={() => {this.hideBox()}}>Send</Button>
</div>
}
showBox = () => {
this.setState({visibility: 'visible'});
}
hideBox = () => {
this.setState({visibility: 'hidden'});
}
render(){
return(
<div>
<Button onClick={() => {this.showBox()}}>Show</Button>
{this.box()}
</div>
)
}
I don't know how to make them hide at the same time.
Thank you for the help.
style={{display: `${this.state.visibility ? 'block' : 'none'}`}}
because antd components has it's default style: transition:"all 0.3s".
styles in devtool
if you hide it with style, I suggest using dispaly:block/none,instead of visibility.