show only one popover at a time on state change - reactjs

I want to show different popovers on different listitems using reactstrap but on state change the property of popover become true and show all popovers are displayed rather than just one that i clicked.
//setting popoveropen:false initially
this.state = {
popoverOpen: false
};
//on click this toggle function runs which change the popoverOpen state to true which displays all the popover
toggle() {
this.setState({
popoverOpen: !this.state.popoverOpen
})
}
//this is the jsx section where i have used popovers in list items on click of which the toggle function runs and change the popoverOpen State to true
render(){
return(
Members
Popover Title
body1
<ListGroupItem tag="button" id="Popover2" onClick=
{this.toggle2}>Labels<Popover placement="left" isOpen=
{this.state.popoverOpen}
target="Popover2" toggle={this.toggle}>
<PopoverHeader>Popover Title</PopoverHeader>
<PopoverBody>body2</PopoverBody>
</Popover>
</ListGroupItem>
</ListGroup>)}
just logic is missing in this code

Related

All buttons close on click of one button

please i am building a FAQs page and i made a series of buttons which when clicked displays a hidden paragraph underneath each button, now the issue is all buttons respond to one button being clicked on and they all display their respective paragraphs, i want each button to display it's own hidden paragraph alone.
this is the react code i used
class FAQ extends React.Component {
constructor () {
super()
this.state = {
isHidden: true,
}
}
toggleHidden () {
this.setState({
isHidden: !this.state.isHidden})
}
<div className="faq--button">
<button onClick={this.toggleHidden.bind(this)}>button to click</button>
{!this.state.isHidden && <p>lorem ipsum"</p>}
</div>
Currently isHidden is used for all buttons, which will have the same effect in each button. So you need to add separate states for each button. Like isHidden2, isHidden3....

Loading a particular dynamic button in reactjs using antd Button styling

Hello i want to loading a button when i am clicking it. My problem is that my buttons are created dynamic. I am using antd styling for the button. My code is below
<Button
loading={this.state.myLoader}
onClick={() => this.myFunction(r,i)}>
Clickme!
</Button>
I was trying using inside onclick method a state that can become true when this function in executed, my problem with this is when i click a button all the button are loading, but i want to loading only the selected button. How i can do this? Inside my onclick method i can take the id of the button that is clicked every time
Try this
this.state = {
myLoader: []
}
In onClick pass the index to the function
this.myFunction = (r, i) => {
const loader = [...this.state.myLoader];
loader[i] = true;
this.setState({myLoader: loader)};
}
in the button
<Button
loading={this.state.myLoader[i]}
onClick={() => this.myFunction(r,i)}>
Clickme!
</Button>

How to get previous clicked element on any click event in Reactjs?

I am trying to make an single selection in my app. I have a grid and inside it some images. When I clicked an image its parent which is a div background color change to red. I describe this event it is selected. I want to make deselect previous item when click any where. if clicked image is one of my item then new item should be selected and previous should be unselected. if clicked element is not one of my items just previus should be unselected. When I select an item then clicked one of the others it is working. However when I selected an item then click out of my items it is not working. In this stuation my prevClickedElement parameter refers to previous of previous clicked element. And I have no idea why state empty when update it in clickElement in context and in removePrevSelectedSquare in Piece component. Because of my app has multiple components and images I added to here. I am not sure this is the correct way. Because when I select an item component created items count times in this case 15. This is a performance problem?
I believe a good approach would be creating a component global state to save the current element unique id and creating a function to set the element id when it is clicked. After that you can create a function that reset this state whenever it is called and implement this function as an DOM event in a superior div, the parent of the images. Here is the ideia in form of a code snippet:
import React from 'react';
function Stackoverflow(props) {
const [selectedPicture, setSelectedPicture] = React.useState(null);
function resetSelectedPicture() {
setSelectedPicture(null)
}
return (
<div onClick={resetSelectedPicture}>
{pictures.map((picture, index) => {
const {id, src} = picture;
return (
<>
<img
src={src}
key={index}
id={id}
className={
selectedPicture.id === id
? 'selected-picture'
: 'unselected-picture'
}
onClick={setSelectedPicture(
() => picture
)}
/>
</>
);
})}
</div>
);
}
export default Stackoverflow;

How to pass a callback to a child without triggering it

I have a React app with modal, that pop-ups with rules of the game when one clicks a button. What I want to do is make it so when I click anywhere outside this pop up window it will close. i have three files. app.js, dialog.js, and outsidealerter.js . In my main app.js when I click a button it sets a state to visible, so my element takes it and renders based upon it. my outsideralerer.js basicly detects if there is a click outside anything wrapped with specific tags. Now the problem comes that i have a method that changes the state of visibility in app.js, so in order for outsderalerter.js to use it, I pass it to it so it can have access to my main state and change it so that when a click is outside the zone the pop up window disappears. Kind of works except it closes it down even if i click within a pop up window, because when i pass the value to outsidealerter it considers the whole body as a no click zone. My question is how can I prevent it from triggering and just pass it a value, or is it possible to change the state value of app.js from outsidealerter.js
App.js
updateState() {
this.setState({ isOpen: false });
}
<div id='rule-button'>
<button onClick={(e)=>this.setState({isOpen : true})} id="modalBtn" class="button">Open Rules</button>
</div>
<OutsideAlerter updateParent={ this.updateState.bind(this)}/>
<Dialog isOpen={this.state.isOpen} onClose={(e)=>this.setState({isOpen : false})}>
</Dialog>
outsidealerter.js
handleClickOutside(event) {
if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
//alert('You clicked outside of me!');
{this.props.updateParent()};
}
}
I think it will be simpler to have the modal take the full space of the window height and width and just make it invisible except for the content of what you want to show.
We can wrap the modal with onClick={hideModal} and wrap the inner content with onClick={e => e.stopPropagation()} which will prevent our wrapper for triggering the hideModal handler.
class ModalWrapper extends React.Component {
state = { isModalOpen: true };
toggleModal = () => {
this.setState(({ isModalOpen }) => ({
isModalOpen: !isModalOpen
}));
};
render() {
const { isModalOpen } = this.state;
return (
<div className="App">
<button onClick={this.toggleModal}>Open Modal</button>
{isModalOpen && <Modal hideModal={this.toggleModal} />}
</div>
);
}
}
function Modal({ hideModal }) {
return (
<div onClick={hideModal} className="modal">
<div onClick={e => e.stopPropagation()} className="modal__content">
Modal content
</div>
</div>
);
}
Working example

Image flickering issue in React when image is conditionally rendered

I have a header and I want to show an image on its right when the mouse is over the header.
I am maintaining a variable editMode in the state which is set to true/false
Then I am conditionally rendering the image using onMouseOver and onMouse events.
Now when I hover over the header, the edit mode is set to true and the image shows up and when I move the cursor out of the header, the editMode sets to false and the image disappears.
I am maintaining a variable editMode in the state which is set to true/false consditionally rendering the image using onMouseOver and onMouse:
Problem: When I hover over the edit icon, it starts flicker.
class TempComponent extends React.Component {
constructor() {
super()
this.editModeToggler = this.editModeToggler.bind(this)
this.state = {
editMode: false
}
}
editModeToggler() {
console.log('called')
this.setState({editMode: !this.state.editMode})
}
render() {
return(
<div>
<h3
onMouseOut={this.editModeToggler}
onMouseOver={this.editModeToggler}
>
Title
</h3>
{this.state.editMode?
<img src='http://www.rebanet.it/images/banners/iscrizioni.png' />
:
null
}
</div>
)
}
}
You can find this code running over here: http://jsfiddle.net/Lu4w4v1c/2/
How do I stop this flickering. I have also tried using onMouseEnter and onMouseLeave as suggested here but it did not work. I dont know how but using these two events resulted in opposite of what I want. The first time the component loaded, everything was fine but as soon as I hover over the icon the whole dynamics changes. The icon shows up when the mouse is not over the header and it does not show up when the mouse is over the header. Please help
The code with onMouseEnter and onMouseLeave is over here: http://jsfiddle.net/Lu4w4v1c/3/
When you have the listener on h3, initially the image is not rendered so for the first time everything seems to be working fine, but once the image is rendered and you hover over the image it responds to the mouseout event of the heading and hides the image immediately which in turn triggers a mouseover on the h3 resulting in the flickering behaviour.
To solve your problem you can simply attach the listener on the container. Updated your fiddle http://jsfiddle.net/Lu4w4v1c/4/ with
<div onMouseOut={this.editModeToggler}
onMouseOver={this.editModeToggler}>
<h3>
Title
</h3>
{this.state.editMode?
<img src='http://www.rebanet.it/images/banners/iscrizioni.png' />
:
null
}
</div>
If you have a container that is going to do onmouseover event that renders a div inside you should use onMouseLeave. The example fiddles has onmouseleave too.
https://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_event_mouseleave_mouseout
this shows the problem

Resources