I am trying to open and close a dialog on a button click from another page/component.
But it is not working on clicking the button.
Any sugegstion what I am missing and doing wrong here with handeling modal.
Thanks in advance.
//TestComponent
class TestConnectDialog extends React.Component {
render() {
const {isOpen, onOk} = this.props;
return (
<Dialog
isopen={this.props.isopen}
onClose={this.props.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Test
</DialogContentText>
</DialogContent>
<DialogActions className="dialog-action">
<Button onClick={this.props.handleClose} className="primary-button">
Ok
</Button>
</DialogActions>
</Dialog>
);
}
};
export default TestConnectDialog;
// Home page
import TestConnectDialog from './TestConnectDialog';
class HomePage extends React.Component {
constructor(props) {
super(props);
this.state = {
isOpen: false
};
this.handleTestConnectClick = this.handleTestConnectClick.bind(this);
//this.handleCloseDialog = this.handleCloseDialog.bind(this);
}
handleTestConnectClick= () =>{
this.setState({ isOpen: true });
}
render() {
const {isOpen, onOk} = this.props;
return (
<div className="section">
<Button className="connect-test-button"
onClick={this.handleTestConnectClick}>
Test
</Button>
<TestConnectDialog isOpen={this.state.isOpen} />
</div>
);
}
};
export default HomePage;
Your prop name is spelled incorrectly, it should be this.props.isOpen also a quick little tip, it is possible to use just one function for opening/closing the modal.
Something like this will work:
handleTestConnectClick = () => {
this.setState(prevState => ({
...prevState,
isOpen: !prevState.isOpen
}));
}
here we use our previous state and with the ! operator we switch from true to false and vice versa
Update 2.0:
After taking a closer look at the Material UI documentation, I noticed that your dialog prop for setting the modal visibility is wrong. It should be open instead of isOpen.
import TestConnectDialog from './TestConnectDialog';
class HomePage extends React.Component {
constructor(props) {
super(props);
this.state = {
isOpen: false
};
//this.handleTestConnectClick = this.handleTestConnectClick.bind(this);
//this.handleCloseDialog = this.handleCloseDialog.bind(this);
// when using arrow functions you don't need to bind the this keyword
}
handleTestConnectClick = () => {
this.setState(prevState => ({
...prevState,
isOpen: !prevState.isOpen
}));
}
render() {
return (
<div className="section">
<Button className="connect-test-button"
// onClick={this.handleTestConnectClick}>
// change the onClick to the one below
onClick={ () => this.handleTestConnectClick() }
Test
</Button>
<TestConnectDialog isOpen={this.state.isOpen} handleTestConnectClick={this.handleTestConnectClick}/>
</div>
);
}
};
export default HomePage;
In TestConnectDialog component:
class TestConnectDialog extends React.Component {
render() {
return (
<Dialog
open={this.props.isOpen}
onClose={this.props.handleTestConnectClick}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Test
</DialogContentText>
</DialogContent>
<DialogActions className="dialog-action">
<Button onClick={this.props.handleTestConnectClick} className="primary-button">
Ok
</Button>
</DialogActions>
</Dialog>
);
}
};
export default TestConnectDialog;
You're passing the props <TestConnectDialog isOpen={this.state.isOpen} /> but trying to read it with isopen={this.props.isopen}.
Change your code to this: isopen={this.props.isOpen}
Update TestComponent component as given
class TestConnectDialog extends React.Component {
render() {
const {isOpen, onOk} = this.props;
return (
<Dialog
isopen={isOpen}
onClose={this.props.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Test
</DialogContentText>
</DialogContent>
<DialogActions className="dialog-action">
<Button onClick={this.props.handleClose} className="primary-button">
Ok
</Button>
</DialogActions>
</Dialog>
);
}
};
export default TestConnectDialog;
In the homepage component why is isOpen destructured from the prop and initialised in state. You have to use one, using both is confusing, you are working with that on the state but passing the one from the prop
Related
When I clicked over a draggable dialog, I want to move to the top of the screen.
I have tried with scrollTo(0, 0), but this seems to not doing anything over my dialog box. Any help over it how can I able to move this dialog box.
Many Thanks in advance.
I am following this Move draggable objects to top of the screen or Div? example but need this to be with on click.
class Homepage extends Component {
constructor(props) {
super(props);
this.state = {
Pending:[],
cancelled:[],
}
this.myRef = React.createRef();
}
componentDidMount() {
this.myRef.current.scrollTo(0, 0);
}
componentDidUpdate(prevProps, prevState) {
if(!prevProps.isModerator){
if(prevProps.Permission === Permission &&
this.props.Permission === Requested){
}
}
}
render() {
const {allowRequest, classes} = this.props;
const { Pending} = this.state;
return (
<>
{Pending.map((user, index) => {
return <Draggable bounds="parent" key={user.id} ref={this.myRef}>
<div className={classes["share-request-content"]} >
<Paper className="alert-container" square={true}>
<DialogTitle id="alert-title">
{/* Title here */}
</DialogTitle>
<DialogContent>
{/* Content here */}
</DialogContent>
<DialogActions className="dialog-action">
<Button autoFocus color="primary" onClick={() => allowRequest(user.id)}>
"Allow"
</Button>
</DialogActions>
</Paper>
</div>
</Draggable>
})
}
</>
)
}
}
Homepage.propTypes = {
Permission: PropTypes.string,
isModerator: PropTypes.bool.isRequired,
Pending: PropTypes.array,
cancelled: PropTypes.array,
};
export default withStyles(styles)(injectIntl(Homepage))
Use the position={{x:0, y:0}} property to manually control the position of the dialog.
You can find the references here: https://github.com/STRML/react-draggable
How to render JSX component from function to show it in the Screen.
This below is the code which is not rendering the function JSX component...
export default class HomeScreen extends Component{
state = {
isVisible:false
}
modal = ()=>{
return(<Text>Hello world</Text>);
}
render(){
return(
<View>
<Button onPress={this.setState({isVisible:true})}>Click me</Button>
{this.state.isVisible?this.modal:null}
</View>
);
}
}
And this Below code is working properly so i want to know what is error in first one.
export default class HomeScreen extends Component{
state = {
isVisible:false
}
modal = ()=>{
return(<Text>Hello world</Text>);
}
render(){
return(
<View>
<Button onPress={this.setState({isVisible:true})}>Click me</Button>
{this.state.isVisible?<Text>Hello world</Text>:null}
</View>
);
}
}
So Please tell me the error in first one what is problem due to which hello world text is not rendering through the JSX component return from the function modal.
Because you never called this.modal
You have to call it.
this.modal()
It's a function that needs to be invoked.
No Problem it happens.😁
First problem is that you dont execute the modal function.
Second you invoke the function onPress and doesn't pass a reference to a function, wrap it inside an arrow function onPress={() => this.setState({ isVisible: true })}
I will suggest to extract the Modal to a new component and include it only when state.isVisible is true
const Modal = () => <h3>Modal</h3>;
export default class HomeScreen extends Component {
state = {
isVisible: false
}
render() {
return (
<View>
<Button onPress={() => this.setState({ isVisible: true })}>Click me</Button>
{this.state.isVisible && <Modal />}
</View>
);
}
}
I have a functional component
const text = ({data}) => {
return (
<p onClick={()=> render more?}>info</p>
)}
const more = ({data}) => {
return (<p>..........</p>)
}
Is it possible to render more component on the onClick event?
Sure, you'll need a state variable. Use the state to determine whether to render more or not, and then set the state when the click happens. If you have react 16.8 or later, you can do this in a functional component with hooks:
import { useState } from 'react';
const MyComponent = ({data}) => {
const [showMore, setShowMore] = useState(false);
return (
<div>
<p onClick={() => setShowMore(true)}>info</p>
{showMore && <More data={data} />}
</div>
)}
}
Prior to 16.8, you'll need to use a class component.
class MyComponent extends React.Component {
state = {
showMore: false,
}
render() {
return (
<div>
<p onClick={() => this.setState({ showMore: true})}>info</p>
{this.state.showMore && <More data={this.props.data} />}
</div>
)}
}
}
I have data being mapped as a repeater. But I need to isolate the opening function (It's an accordion). I'm still learning my way through React. Basically, the accordions load with the state for open: false Once the ListItem is clicked, the HandleClick function toggles the state to open: true. A simple concept, I just need to isolate it so that it works independently. Whereas right now they all open and close at the same time.
Here is the state in a constructor and function
constructor(props) {
super(props);
this.state = {
open: true,
};
}
handleClick = () => { this.setState({ open: !this.state.open }); };
Here is my mapping script in ReactJS
{LicenseItems.map((item, index) => (
<div key={index}>
<ListItem
divider
button
onClick={this.handleClick}>
<ListItemText primary={<CMLabel>{item.accordion_name}</CMLabel>}/>
</ListItem>
<Collapse
in={!this.state.open}
timeout="auto"
unmountOnExit>
{item.content}
</Collapse>
</div>
))}
The in dictates whether it is open or not per MaterialUI-Next
Thanks in advance guys!
Not very pretty, but something like this should work:
constructor(props) {
super(props);
this.state = {
open: {},
};
}
handleClick = (idx) => {
this.setState(state => ({open: { [idx]: !state.open[idx]} }))
}
// in render
{LicenseItems.map((item, index) => (
<div key={index}>
<ListItem
divider
button
onClick={() => this.handleClick(index)}>
<ListItemText primary={<CMLabel>{item.accordion_name}</CMLabel>}/>
</ListItem>
<Collapse
in={!this.state.open[index]}
timeout="auto"
unmountOnExit>
{item.content}
</Collapse>
</div>
))}
It would be better to create separate Components for that, which have their own open state.
You should create two components for that:
Accordions.js
import React from 'react'
import Accordion from './Accordion'
const Accordions = props => {
return (
props.LicenseItems.map((item, index) => (
<Accordion key={index} item={item} />
))
);
}
export default Accordions;
Accordion.js
import React, { Component } from 'react'
class Accordion extends Component {
constructor(props) {
super(props);
this.state = {
open: true,
};
}
handleClick = () => { this.setState({ open: !this.state.open }); };
render() {
return (
<div>
<ListItem
divider
button
onClick={this.handleClick}>
<ListItemText primary={<CMLabel>{this.props.item.accordion_name}</CMLabel>}/>
</ListItem>
<Collapse
in={!this.state.open}
timeout="auto"
unmountOnExit>
{this.props.item.content}
</Collapse>
</div>
)
}
}
export default Accordion;
In my main component I can open a modal by clicking on an icon. The content of the modal is a separate component, which is calling a method.
If the method call is successful, I want to close the modal. But how can I do this?
Main component
class Example extends Component {
constructor(props) {
super(props)
this.state = {}
}
render() {
return (
<div>
<Modal trigger={ <Icon name='tags' /> } >
<Modal.Header>
<div>
<Header floated='left'>Title</Header>
<Button floated='right'>A Button</Button>
</div>
</Modal.Header>
<Modal.Content>
<ModalContent />
</Modal.Content>
</Modal>
</div>
)
}
}
Modal content
class ModalContent extends Component {
constructor(props) {
super(props)
this.state = {}
}
handleClick() {
method.call(
{ param },
(error, result) => {
if (result) {
// Now close the modal
}
}
);
}
render() {
return (
<Button onClick={this.handleClick} content='Save' />
)
}
}
You should add an onClose property to <Modal> element. See example below:
<Modal
trigger={<Button onClick={this.handleOpen}>Show Modal</Button>}
open={this.state.modalOpen}
onClose={this.handleClose}
>
Then you can add onClose function to a button in your modal. Full example from the docs:
https://react.semantic-ui.com/modules/modal#modal-example-controlled
Pass a onSuccess method as a props :
in the parent :
<ModalContent onSuccess={this.onModalSuccess}/>
in the child component :
handleClick() {
method.call(
{ param },
(error, result) => {
if (result) {
this.props.onSuccess()
}
}
);
}
In this way you keep your open/close logic in the parent component.
semantic-ui have property open. Just set true or false
class Example extends Component {
constructor(props) {
super(props)
this.state = {
open: false
}
open = () => this.setState({ open: true })
close = () => this.setState({ open: false })
render() {
return (
<div>
<Modal open={this.state.open} trigger={ <Icon name='tags' /> } >
<Modal.Header>
<div>
<Header floated='left'>Title</Header>
<Button floated='right'>A Button</Button>
</div>
</Modal.Header>
<Modal.Content>
<ModalContent />
</Modal.Content>
</Modal>
</div>
)
}
}