Is there a show attribute in react -popup - javascript

There is a trigger button in react popup, does it have show attribute ?
<Popup trigger={<button> Trigger</button>} position="right center">
<div>Popup content here !!</div>
</Popup>
I mean, my requiremnt is to show the popup when an event happens (when i click a cell in react table- triggers goes to a onclick function, if i can do somethnig in onclick to triggr the popup)
Something like:
<Popup show=this.state.showpopup position="right center">
<div>Popup content here !!</div>
</Popup>
this.state.showpopup will be set from onclick

The Popup has a prop called open which takes a boolean.
try:
open={this.state.showpopup}

I think you want to show the popup without using trigger props,
Try this
function component() {
const [showModal, setShowModal] = useState(false)
return (
<Fragment>
<button onClick={() => setShowModal(true)}>Trigger</button>
<Popup modal={showModal} position="right center">
<div>Popup content here !!</div>
</Popup>
</Fragment>
)
}

Related

Javascript attribute - onClick and onClickOverThere for dropDown

I have reactJs app and I have made a custom dropDown with a div that I set an onClick attribute to open dropDown and close it.
but also I want to close it when the user clicks to another part of the site.
<div
onClick={() => setNoneQuote(noneQuote ? false : true)}
className="selected-drop-down"
>
<span className="dropDownText">{selectedQuoteCurrency}</span>
<img
className="dropDownIcon"
src={require("../assets/image/arrow/dropDown-Arrow.png")}
width="15px"
alt="arrow"
/>
</div>
I try onMouseDown instead of onClick according to this answer ==> stackoverflow ,but I don't know why it doesn't work for me :(
const dropdownElement= document.querySelector("choose an id or a specific class")
window.onclick = function(event) {
if (event.target !== dropdownElement) {
dropdownElement.style.display = "none"; // or any other function that you want to call
}
}
this may not be the exact code to fix your problem but you can use the logic
You could do it in different ways, but I will show you solution that I used in one of my projects.
So, I used <header> and <main> tags where I had all my Components. And in those tags i used eventListener with a callback function, like this:
<header onClick={handleClick}>
<Nav />
<Greeting />
<Sidebar />
</header>
and
<main onClick={handleClick}>
<Description />
<Icons />
<Prices />
<Gallery />
<NecessaryInfo />
<Location />
<GalleryModal />
<ConditionsModal />
</main>
In a callback function handleClick I checked where user could click and to do that I used next logic of pure JS:
!e.target.classList.contains("menu-open") &&
!e.target.classList.contains("menu-links") &&
!e.target.parentElement.classList.contains("menu-links") &&
!e.target.parentElement.parentElement.classList.contains("menu-links") &&
closeSidebar();
Function closeSidebar() is simple:
const closeSidebar = () => {
setIsSidebarOpen(false)};
In your code instead of using setNoneQuote(noneQuote ? false : true) you could also use: setNoneQuote(!noneQuote). Exclamation mark before value always will change it to the oposite.

How to hide/show a div in React?

I want to create a button to show and hide a div.
In the first div (div1) I have a table and in the second div (div2) I have a chart.
When a user clicks the button (with bar icon), should see the div2 (chart) and when the user clicks again it should return div1 (table).
How can I do it?
tables.js
export function IncomeTables({firminfo, title, arr_number, financials, balance}) {
...
...
return <Card>
<div id="div1">
<Table>
<head>
<tr>
<th colSpan="5">{title} <button style={{float:"right"}} className="btn btn-primary" ><FaChartBar/></button></th>
</tr>
...
</thead>
...
</Table>
</div>
<div id="div2">
<BarChart>
...
</BarChart>
</div>
</Card>
This is how you do it:
export default function App() {
let [show, setShow] = React.useState(false);
return (
<div>
{show ? <div>Hello</div> : <div>Another div</div>}
<button
onClick={() => {
setShow(!show);
}}
>
Click
</button>
</div>
);
}
But when say instead of divs you render different types of components, when switching to another component, the previous one will be unmounted, and all state will be gone (due to reconciliation). In such cases you may want to store state in parent (e.g. App), so that state is not lost.
Or alternatively you may change display property of the div you want to show/hide, based on state variable; in that case state will not be lost, because you are not unmounting anything just changing a CSS property.

How to render a component outside the component that contains the function that renders the first component?

The situation is a bit complicated:
inside a component called "LeftSectionHeader" I have a div, which when clicked must render a component;
the component to be rendered is called "ProfileMenu", and is basically a div that must be rendered on top of "LeftSectionHeader" itself and another div;
All these components are rendered inside another component called "Main".
The problem is that if I define the function inside "LeftSectionHeader", "ProfileMenu" will be rendered inside, while I need it to not only be rendered outside, but even cover it; that's why you'll see some boolean vars inside "Main", because that is the only way i could render it, but it still doesn't cover the other divs. I'll attach the code of each component and how the final result should look below.
LeftSctionHeader:
function LeftSectionHeader(){
return(
<div class="left-section-header">
<div class="crop" ><img src="./images/profiles/anonimous.png" /></div>
</div>
);
}
The div belonging to the "crop" class is the one that must be clicked to render "ProfileMenu"
ProfileMenu:
function ProfileMenu(){
return(
<div class="profile-side-menu">
//A lot of boring stuff
</div>
);
}
There are some functions related to this component, but they are not important, so I didn't put them, just ignore it
Main:
var p=true;
var m=true;
function Main(){
return(
<div class="main">
<Header />
<div class="left-section">
{m ? <div><LeftSectionHeader /><LangMenu /></div> : <ProfileMenu />}
</div>
{p ? <PostPage /> : <NoPostsMessage />} //Ignore this line
</div>
);
}
Before clicking on the orange div
After clicking
This might help as guidline, hopefully!
function LeftSectionHeader({ onClick }){
return(
<div class="left-section-header" onClick={onClick}>
<div class="crop" ><img src="./images/profiles/anonimous.png" /></div>
</div>
);
}
function Main(){
const [showProfile, setShowProfile] = useState(false);
return(
<div class="main">
<Header />
<div class="left-section">
{!showProfile ? (
<div>
<LeftSectionHeader onClick={() => setShowProfile(true)} />
<LangMenu />
</div>
) : <ProfileMenu />}
</div>
{p ? <PostPage /> : <NoPostsMessage />} //Ignore this line
</div>
);
}
The simplest solution might be to pass a handler into the header component to toggle the menu:
function App () {
const [showMenu, setShowMenu] = useState();
return (
<div>
<Header onMenuToggle={() => setShowMenu(!showMenu)} />
{ showMenu && <Menu /> }
</div>
)
}
function Header ({ onMenuToggle }) {
<div onClick={onMenuToggle}>...</div>
}
Caveat: This will cause the entire App component to re-render when the menu state changes. You can mitigate this by either
A) placing the menu state closer to where it's actually needed, like in the sidebar component instead of at the top, or
B) using a context or other orthogonal state store.
Another approach would be to leave the state handling in the LeftSectionHeader component and then use a React portal to render the menu elsewhere in the DOM.

Load img tag source before css is applied in Reactjs

I want to input a picture in my Lightbox, but from what I see the problem is that the CSS is applied before the img source can be loaded inside of the tag
Problem: The Lightbox Activates without an image source.
It only works if I put an img source manually.
class LightboxTest extends Component {
state = {};
render() {
return (<React.Fragment>
<div
className={this.props.setActivity === false ? 'lightboxOff' : this.props.setActivity === true ? 'lightboxActive' : ''}
>
<img alt="" src={this.props.lbImages} />
</div>
</React.Fragment>);
}
}
export default LightboxTest;
I'm passing a boolean 'setActivity' per props to check whether an image has been clicked on to set the Lightbox Active and 'lbImages' as my source which should be loaded, when clicked on an image.
<div className="header">
{images.map((image) => (
<React.Fragment key={image.id}>
<img
alt=""
src={image.src}
key={image.id}
onClick={() => {
setLightboxImage(image.src);
}}
onClick={handleClick}
/>
</React.Fragment>
))}
</div>
When I remove the lightbox div tag the image appears with no issue when Clicked on.
Can I set like a priority?
you have two onClick handlers, so the second one isn't executed. Can be changed to:
onClick={() => {
setLightboxImage(image.src);
handleClick();
}}

Don't trigger onClick for nested child elements

I have a simple modal component:
function Modal(props) {
return (
<div className={cx(styles.overlay, { show: props.show })} onClick={props.onClose}>
<div className={styles.modal}>
<span className={styles.closeBtn} onClick={props.onClose} />
{props.children}
</div>
</div>
)
}
the onClose prop triggers closing the modal, hence I attach it to styles.overlay (dark overlay that you typically see on modals that when clicked dissmises it) and to styles.closeBtn (a close button for modal).
The whole flow works besides the fact that anything inside styles.overlay when clicked on also dismisses the modal, which is not functionality I was after, hence I need to only dismiss it if that specific element is clicked not its children.
function Modal(props) {
return (
<div className={cx(styles.overlay, { show: props.show })} onClick= {props.onClose}>
<div className={styles.modal} onClick={e => e.preventDefault()}>
<span className={styles.closeBtn} onClick={props.onClose} />
{props.children}
</div>
</div>
)
}
I think, the best way is to have your overlay and your modal in two separate div, but this should work.
Add onClick(e)={e.stopPropagation();} to the modal dialog's click handler; this should prevent it from propagating to the overlay.
Hope it works! Good luck!

Categories