close React Dialog with a button - javascript

I want to open the diaglog when the screen is visited so I set the default state to true. I made a custom button. When I click on it, the state should change to false and the dialog should close. However, the dialog doesnt close. What am I doing wrong and how else can I close the dialog?
<Dialog open={openReminder}>
<DialogTitle>Reminder</DialogTitle>
<DialogContent>
<DialogContentText>Don't forget to take your daily walk!</DialogContentText>
<div className={classes.reminderContainer}>
<DialogButton
text={"Ok, thanks!"}
onPress={() => setOpenReminder(false)}
/>
</div>
</DialogContent>
</Dialog>
export const DialogButton = ({ onPress, text }) => {
const classes = useStyles();
return (
<Button onPress={onPress} className={classes.button}>
{text}
</Button>
);
};

Issue is with the onPress event try using onClick,
<Button onClick={onPress} className={classes.button}>
{text}
</Button>

Two things which I note :
You need to change onPress to OnClick inside like this :
<Button onClick={onPress} className={classes.button}>
{text}
</Button>
Check inside your Dialog component that you explicitly hide it when 'open' prop is set to false.

<DialogButton text={"Ok, thanks!"} onPress={()=>setOpenReminder(!openReminder)}/>
<Button onClick={onPress} className={classes.button}>
{text}
</Button>

Change the onPress with onClick in your child component like this.
<Button onClick={onPress} className={classes.button}>
{text}
</Button>
check out if it works.

Related

how correctly 'reset' useState when close modal reactJS

I would like to explain my problem of the day.
Currently I use a modal in this modal I select a value, this works correctly.
my problem and the following, when I click on the cancel button or the cross to close.
and if I open the modal again, the value select before and still present
I would like to return to its initial state when I click on cancel or the cross
and of course when I open the modal no value in select
iam open to any proposal thank you very much.
ps: leadsOptions in select is data ofc , ps 2 : maybe a useeffect/ prevStateReset to Initial State ?
import React, { useState, useEffect } from "react"
function LeadModal({ isOpen, onClose }) {
const [leadId, setLeadId] = useState(null);
return (
<Modal
open={isOpen}
getOpen={onClose}
>
<PanelHeader>
<PanelTitle>
add lead
</PanelTitle>
<SvgIcon
onClick={onClose}
/>
</PanelHeader>
<PanelBody className="space-y-1 mb-2 ">
<Label>
Sélect lead
</Label>
<div>
<Select
options={leadsOptions}
placeholder="leads"
getValue={(values) => {
setleadId(values.value);
}}
value={leadId}
/>
</div>
</PanelBody>
<PanelFooter>
<div>
<Button onClick={onClose}>
Annuler
</Button>
</div>
</PanelFooter>
</>
</Modal>
);
}
You are not clearing your state data when you open the modal again. Just update the state value with the initial value before closing or canceling the modal or something like this.
<SvgIcon onClick={() => {setLeadId(null); onClose();}} />

Stopping propogation of button that contains tooltip with link not working on Button

I am using the Material UI Button Component and in the button, there is text. And right next to that text, I have a tooltip. And in that tooltip, there is a link to an article. The idea is that I want the user to have a chance to be able to click the 'read more' link inside the tooltip before clicking the actual button. The issue is that when clicking the 'read more' link that is inside the tooltip, it actually clicks the button instead. I have tried to use the e.stopPropagation event that supposedly stops the component from bubbling to other elements. But it still doesnt prevent the button from being clicked instead of the 'read more' link that is within the tooltip. Please see my code below:
render() {
const { buttonStyleOverride, classes } = this.props;
const { buttonDisabled } = this.state;
return (
<Button
name="buyItem"
variant="outlined"
style={buttonStyleOverride}
className={classes.button}
color="primary"
disabled={buttonDisabled}
onClick={
this.addItems,
e => e.stopPropagation()
}>
Buy Pikafoods
<TooltipIcon
title="You can read more about pikafoods here."
learnMoreLink="https://pokemon.com/articles/pikafoods"
style={{ position: 'relative', top: '-2px' }} />
</Button>
);
}
}
It's really strange a clickable tooltip inside a button, not very user friendly.
However you have to stop the propagation in the tooltip event, not in the button, like this:
import { Button } from "#material-ui/core";
import AccessibilityIcon from "#material-ui/icons/Accessibility";
export default function App() {
return (
<div className="App">
<Button
name="buyItem"
variant="outlined"
color="primary"
onClick={(e) => console.log("button")}
>
Buy Pikafoods
<AccessibilityIcon
onClick={(e) => {
console.log("tooltip");
e.stopPropagation();
}}
/>
</Button>
</div>
);
}

Button doesn't work if I use template literals to toggle CSS classes in React

I have a CSS module called styles and this React code. It's a div with two buttons inside. I use the isMenuActive state to verify if the menu is active or not. If it is active, the CSS class 'active' gets in and the menu appears, otherwise not.
<div className={`${styles.customerOptionsMenu} ${isMenuActive ? styles.active : null}`}>
<button onClick={() => { console.log('hi') }}>
<span className="material-icons">edit</span>Editar
</button>
<button onClick={() => {console.log('hi')}}>
<span className="material-icons">delete</span>Deletar
</button>
</div>
When I click the buttons, nothing happens.
But If I store the button as a global variable in developer tools and run button.click() it works fine if I remove the template literals:
<div className={styles.customerOptionsMenu + styles.active}>
<button onClick={() => { console.log('hi') }}>
<span className="material-icons">edit</span>Editar
</button>
<button onClick={() => {console.log('hi')}}>
<span className="material-icons">delete</span>Deletar
</button>
</div>
It works fine.
Why??? And what should I do to keep changing the classes when isMenuActive changes?
Edit: Full code with the button that changes isMenuActive
const [isMenuActive, setIsMenuActive] = useState(false)
const onBlur = () => { setIsMenuActive(!isMenuActive)}
return(
<td>
<button onBlur={onBlur} className={styles.customerOptions} onClick={() => setIsMenuActive(!isMenuActive)}>
<span className="material-icons">more_horiz</span>
</button>
<div className={`${styles.customerOptionsMenu} ${isMenuActive ? styles.active : null}`}>
<button onClick={() => { console.log('hi') }}>
<span className="material-icons">edit</span>Editar
</button>
<button onClick={() => {console.log('hi')}}>
<span className="material-icons">delete</span>Deletar
</button>
</div>
</td>
)
New edit: The answer is in the comments by Pandaiolo. The problem was the onBlur={onBlur} code, when I removed it from the button everything worked fine!
To handle changing classnames you can use the classnames package to do something like this:
import cx from "classnames";
<div className={cx(styles.customerOptionsMenu, { styles["active"]: isMenuActive })}>
<button onClick={() => { console.log('hi') }}>
<span className="material-icons">edit</span>Editar
</button>
<button onClick={() => {console.log('hi')}}>
<span className="material-icons">delete</span>Deletar
</button>
</div>
I think the space is fine in your template literal, because it references two different class names. You probably want to use ${isMenuActive ? styles.active :''} otherwise null becomes the string "null", which is probably harmless unless you have a class .null that applies some styles, but that is basically not what you want.
But maybe the onBlur is called after the click?
click
button becomes focus
button blurs ?
Not sure. But in that case it would toggle the state two times, cancelling its effect. Maybe try with just the onClick and without the onBlur at first?
And you can add a console.log('isMenuActive', isMenuActive) before the return statement to see it's value along rerenders, see if it matches what you expect.
The isMenuActive is not defined. Place it in as a parameter as so:
export default function App(isMenuActive) {
return (
<div className="App">
<div className={`${styles.customerOptionsMenu} ${isMenuActive ? styles.active : null}`}>
<button onClick={() => { console.log('hi') }}>
<span className="material-icons">edit</span>Editar
</button>
<button onClick={() => {console.log('hi')}}>
<span className="material-icons">delete</span>Deletar
</button>
</div>
</div>
);
}

How to Show the same modal with different content onClick different buttons?

I am trying to load different content of Modals onClick of different button.
Save the model content in state
In onClick pass the new content to the function and do setState
Change the visibility according to the logic
Below is the code to send the argument to React member functions
onClick = {(e) => this.showModel(e , newContent) }
Can elaborate more if you share your code
Thanks
{["first","second"].map(option => {
return (
<Button
size="small"
color="secondary"
variant="raised"
onClick={this.handleClickOpen}
>
{option}
</Button>
);
})}
<Dialog
open={this.state.open}
onClose={this.handleClose}
>
<DialogTitle id="alert-dialog-title">
{"Use Google's location service?"}
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
hello /here must be different names/
</DialogContentText>
</DialogContent>
</Dialog>

conditional passing component as array prop in react

How can I conditionally pass the footer's button component? cancelBtnBasicModal and okBtnBasicModal the button is still there without text label.
Below is a modal component, it worked, but if I don't pass in
render() {
const { titleBasicModal, showBasicModal, handleOkBasicModal, handleCancelBasicModal,
contentBasicModal, cancelBtnBasicModal, okBtnBasicModal, loading } = this.props
return (
<div>
<Modal
visible={showBasicModal}
title={titleBasicModal}
onCancel={handleCancelBasicModal}
footer={[
<Button onClick={handleCancelBasicModal}>
{cancelBtnBasicModal}
</Button>,
<Button key="submit" type="primary" size="large" loading={loading} onClick={handleOkBasicModal}>
{okBtnBasicModal}
</Button>
]}
>
{contentBasicModal}
</Modal>
</div>
);
}
I tried
footer={[
{cancelBtnBasicModal && <Button onClick={handleCancelBasicModal}>
{cancelBtnBasicModal}
</Button>},
<Button key="submit" type="primary" size="large" loading={loading} onClick={handleOkBasicModal}>
{okBtnBasicModal}
</Button>
]}
But won't work coz footer prop accept array.
You need to pass an Array, spread operation is for rescue.
You can do something like that:
footer={[
...(cancelBtnBasicModal ? [
<Button onClick={handleCancelBasicModal}>
{cancelBtnBasicModal}
</Button>]: []),
<Button key="submit" type="primary" size="large" loading={loading} onClick={handleOkBasicModal}>
{okBtnBasicModal}
</Button>
]}
You can separate that logic by setting an array footerBtns with the default button (okBtnBasicModal in this case) and then we add the next button if it's passed through props.
Finally assign footerBtns to footer in the Modal component.
render() {
const { titleBasicModal, showBasicModal, handleOkBasicModal,
handleCancelBasicModal, contentBasicModal, cancelBtnBasicModal,
okBtnBasicModal, loading } = this.props
let footerBtns = [
<Button key="submit" type="primary" size="large" loading={loading}
onClick={handleOkBasicModal}>
{okBtnBasicModal}
</Button>
]
/* using unshift to add the button to the beginning of the Array */
cancelBasicModal && footerBtns.unshift(
<Button onClick=
{handleCancelBasicModal}>{cancelBtnBasicModal}
</Button>
);
return (
<div>
<Modal
visible={showBasicModal}
title={titleBasicModal}
onCancel={handleCancelBasicModal}
footer={footerBtns}>
{contentBasicModal}
</Modal>
</div>
);
}
More info on using unshift()

Categories

Resources