reactjs-popup didn't open as ever after closeOnDocumentClick event triggered - reactjs

The demo case is here. To regenerate it, just do as follows:
click on [Click me.], then the popup will show;
click anywhere but the popuped block, the popup will hide;
click on [Click me.], it's expected that the popup window will show again, but the fact is just the opposite.
What's the problem? Any ideas?

Use onClose prop of reactjs-popup as shown below.
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
import Popup from "reactjs-popup";
class App extends Component {
constructor() {
super(
);
this.onClick = this.onClick.bind(this);
this._popUpClosed = this._popUpClosed.bind(this);
this.state = {
name: 'React',
open:false
};
}
_popUpClosed(){
this.setState({open: false});
}
onClick() {
this.setState({open: true});
}
render() {
return (
<div>
<Popup open={this.state.open} onClose={this._popUpClosed}/>
<Hello name={this.state.name} />
<button onClick={this.onClick}>
Click me.
</button>
</div>
);
}
}
render(<App />, document.getElementById('root'));

it seems like you need to make open false again so that the popup can show up when you change the state of open
you can change the onClick function like this
onClick() {
this.setState({open: !this.state.open});
}
like this you will need to double click in the second time. or better you can add a button in your pop up to close it

Related

OnClick Listeners not working after closing full-screen dialog using react-material-ui

I have a problem with a fullscreen dialog that is being closed when the associated "OnClose" function is called. The dialog closes, however i cannot be opened again.
Any idea on why this happens? It feels like there is an invisible dialog staying on the canvans that prevents event from being bubbled to the button, or something similar.
import React from "react";
import Button from "#material-ui/core/Button";
import Dialog from "#material-ui/core/Dialog";
import "./FooterBar.css";
import Slide from "#material-ui/core/Slide";
import AppBar from "#material-ui/core/AppBar";
import Toolbar from "#material-ui/core/Toolbar";
import IconButton from "#material-ui/core/IconButton";
import CloseIcon from "#material-ui/icons/Close";
class BarItem extends React.Component {
constructor(props) {
super(props);
this.state = {
title: props.title,
targetURL: props.targetURL,
dialogOpen: false
};
this.barItemClicked = this.barItemClicked.bind(this);
this.handleClose = this.handleClose.bind(this);
}
barItemClicked() {
this.setState({
dialogOpen: true
});
}
handleClose() {
this.setState({
dialogOpen: false
});
}
render(props) {
const Transition = React.forwardRef(function Transition(props, ref) {
return <Slide direction="up" ref={ref} {...props} />;
});
return (
<div>
<Button onClick={this.barItemClicked}>{this.state.title}</Button>
<Dialog
fullScreen
open={this.state.dialogOpen}
onClose={this.handleClose}
TransitionComponent={Transition}
>
<AppBar>
<Toolbar>
<IconButton
edge="start"
color="inherit"
onClick={this.handleClose}
aria-label="Close"
>
<CloseIcon />
</IconButton>
</Toolbar>
</AppBar>
</Dialog>
</div>
);
}
}
class FooterBar extends React.Component {
render() {
return (
<div class="footerbar">
<BarItem title="Impressum" targetURL="a" />
<BarItem title="Datenschutzerklärung" targetURL="b" />
<BarItem title="Kontakt" targetURL="c" />
</div>
);
}
}
export default FooterBar;
I expect the buttons of the Footerbar to re-open the dialog, but this does not happen.
It looks like the problem lies in your TransitionComponent, you're passing a new instance of it to your Dialog each time you render. Try declaring it outside of your BarItem class.
Also, depending on what you want to display in your modal, I would find it better to put the modal and handler in your FooterBar component. Take a look at this sandbox that I created from your code. Maybe it'll give you some ideas.
Let me know if it helps.

Trying to create a toggle function to set the state of 2 buttons from disabled to enabled based on an onClick event attached to a third button

I have a set of 3 buttons where I need to set the initial state for two buttons as disabled and then create an onClick event for a third button that would enable both buttons when clicked. I'm thinking of setting the disabled attribute in state and then creating the function for onClick that would target the state of both buttons and set it to false. My current code is below, any ideas on how to achieve this?
import React, { Component } from 'react';
import { render } from 'react-dom';
import { Button } from 'antd';
import "antd/dist/antd.css";
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
disabled: undefined
};
}
toggleSwitch(){
alert("you clicked the switch");
}
render() {
return (
<div>
<Button disabled={true}>Modify Docs</Button>
<Button disabled={true}>Upload Docs</Button>
<Button onClick={this.toggleSwitch}>Unlock Quote</Button>
</div>
);
}
}
render(<App />, document.getElementById('root'));
You're almost there.
In your render method, you've set disabled={true} which means that it will permanently stay true instead of checking the value of the disabled property in state.
The toggle method should simply negate the previous value of disabled.
import React, { Component } from 'react';
import { render } from 'react-dom';
import { Button } from 'antd';
import "antd/dist/antd.css";
import './style.css';
class App extends Component {
state = {
disabled: true,
};
toggleSwitch() {
// when toggling, we just negate the previous value
this.setState(previousState => ({
disabled: !previousState.disabled,
}))
}
render() {
// Buttons will use the same value from state
// to check if they should be disabled
const { disabled } = this.state;
// instead of setting disabled={true}, reference the disabled
// property from state
return (
<div>
<Button disabled={disabled}>Modify Docs</Button>
<Button disabled={disabled}>Upload Docs</Button>
{/* we set the text of the button depending on the value of disabled */}
<Button onClick={this.toggleSwitch}>
{disabled ? 'Unlock Quote' : 'Lock Quote'}
</Button>
</div>
);
}
}
render(<App />, document.getElementById('root'));
Also, consider using a toggle component of sorts instead of the third button for better user experience.

How to make `Menu` in material-ui don't reset scroll position after rerendering?

<Menu onChange={this.props.onChange}>
{ items }
</Menu>
I have a Menu with a lot of items like this, every time when I update the state, the scroll position of the menu is resetted.
I tested with ul
<ul>
{ item }
</ul>
it works, the position isn't resetted after rerendering.
here is the source code of material-ui/Menu.js, as I'm new to js, I can't find anything about why the scroll position is resetted.
here is the code, if you scroll to the bottom, and then click the 23 item, the scroll position will be resetted.
The problem was with the event handler, you need to add preventDefault() this stops the default action.
import React from "react";
import ReactDOM from "react-dom";
import { MuiThemeProvider, Menu, MenuItem, MenuList } from "material-ui";
export default class Hello extends React.Component {
constructor(props) {
super(props)
this.handleChange = this.handleChange.bind(this);
}
handleChange() {
event.preventDefault();
console.log("Hello");
}
render() {
const array = Array.from({ length: 25 }, i => 1);
const items = Object.keys(array).map(key => {
return <MenuItem key={key} value={key} primaryText={key} />;
});
return (
<MuiThemeProvider>
<Menu
onChange={this.handleChange}
>
{items}
</Menu>
</MuiThemeProvider>
);
}
}
finally, I use List instead of Menu to solve this problem.

React state not updating

So I'm making a simple React application that needs to show a modal when something is clicked. I use react-modal to achieve this and the modal is showing but I'm not able to close it again. Here's the code:
import React from 'react';
import ReactDOM from 'react-dom';
import Paper from "./Paper";
ReactDOM.render(
<Paper title={"Title"} notes={"Notes"}/>,
document.getElementById('root')
);
and the Paper definition:
import React, {Component} from 'react';
import Modal from 'react-modal';
class Paper extends Component {
constructor(props) {
super(props);
this.state = {modalIsOpen: false};
this.showModal = this.showModal.bind(this);
this.closeModal = this.closeModal.bind(this);
}
showModal() {
this.setState({modalIsOpen: true});
}
closeModal() {
this.setState({modalIsOpen: false});
}
render() {
return (
<div onClick={this.showModal}>
{this.props.title}
<Modal isOpen={this.state.modalIsOpen}>
<button onClick={this.closeModal}>close</button>
{this.props.notes}
</Modal>
</div>
);
}
}
The state just doesn't get updated if I check it in the developer tools and I have no idea why. Anyone who can help me?
I was able to reproduce your problem, which was actually a bit strange - even if I logged this.state.modalIsOpen in the setState callback after it was set to false, the value was still true. At any rate, I changed the code to perform a toggle instead and it resolved the issue:
https://codesandbox.io/s/q38nzl9yy9
toggleModal() {
this.setState({ modalIsOpen: !this.state.modalIsOpen });
}
render() {
return (
<div onClick={this.showModal}>
{this.props.title}
<Modal isOpen={this.state.modalIsOpen}>
<button onClick={this.closeModal}>close</button>
{this.props.notes}
</Modal>
</div>
);
}
I'm still digging into why the this context seems to be getting muddled, since this appears to be a straightforward example.

react - material-ui appbar icon touch event doesn't fire

When I click on the element AppBar, icon on the left, _handleClick() method should execute.
I can't get console message.
I'm using material-ui framework and the attribute onLeftIconButtonTouchTap is provided for a callback function for when the left icon is selected via a touch tap.
import React, { Component } from 'react'
import { AppBar, IconButton } from 'material-ui'
import MoreVertIcon from 'material-ui/lib/svg-icons/navigation/more-vert';
let injectTapEventPlugin = require("react-tap-event-plugin");
//Needed for onTouchTap
//Can go away when react 1.0 release
//Check this repo:
//https://github.com/zilverline/react-tap-event-plugin
injectTapEventPlugin();
class Header extends Component {
constructor(props) {
super(props);
this._handleClick = this._handleClick.bind(this);
}
_handleClick(e) {
e.preventDefault();
// Show/Hide the LeftMenu
window.console.log("Click!");
}
render() {
return (
<AppBar title="Arasaaccc"
iconElementLeft={ <IconButton>
<MoreVertIcon/>
</IconButton> }
onLeftIconButtonTouchTap={ this._handleClick }
isInitiallyOpen={ true } />
)
}
}
export default Header
However it works with another component:
class Prueba extends Component {
constructor(props) {
super(props);
this._handleClick = this._handleClick.bind(this);
}
_handleClick(e) {
e.preventDefault();
window.console.log("Click!");
}
render (){
return (
<h1 onClick={this._handleClick}>Prueba Prueba Prueba</h1>
)
}
}
export default Prueba;
If you specify an icon for the AppBar component, onLeftIconButtonTouchTap event does not work.
Either you don't specify an icon:
<AppBar title="Arasaaccc"
onLeftIconButtonTouchTap={ this._handleClick }
isInitiallyOpen={ true } />
Or you apply the event on the IconButton component:
<AppBar title="Arasaaccc"
iconElementLeft={ <IconButton onTouchTap={ this._handleClick } >
<MoreVertIcon />
</IconButton> }
isInitiallyOpen={ true } />
Edit: Note that, according to this GitHub issue, the problem should be solved. You still can't have a a _handleClick on both of iconElementLeft and onLeftIconButtonTouchTap, either one or the other.
I can't see any problems with your code, so my guess is you'll need the React-Tap-Event-Plugin. The docs say this dependency is temporary and will go away once react v1.0 is released.

Resources