I'm writing a classical modal component in Vuejs made out of a wrapper, a dark overlay ( that covers the whole page behind it ) and the actual content.
The challenge is that I would like to write this
<button>Trigger Modal 1</button>
<Modal :id="modal1">
Some content
</Modal>
<button>Trigger Modal 2</button>
<Modal :id="modal2">
More content
</Modal>
And get the following rendered code
<button>Trigger Modal 1</button>
<button>Trigger Modal 2</button>
<div class="modal-wrapper">
<div id="modal1">Some content</div>
<div id="modal2">More content</div>
</div>
I'm doing this because I don't want to repeat any of the common elements of each modal, since there can be a lot of them on a page.
What I tried so far
On beforeMount check if this is the first Modal component being rendered ( by checking the DOM for .modal-wrapper ) and if it's in there, append the current instance there, if not add create it using document.createElement. But what I get is a .modal-wrapper element for every modal, probably because the beforeMount event get's fired at once for all the elements present at render time.
Any ideas how I can accomplish this?
Related
I'm new to react and I'm trying to render one component in different html files (because I'm working in an existing project), each of them with different text.
I'm thinking of something like this:
class ctaSection extends React.Component{
render(){
return(
<div className="cta-section">
<div className="md:w-9c">
<h5 className="uppercase">{this.props.h5}</h5>
<h3>{this.props.h3}</h3>
</div>
<div className="cta-button">
<a href="#">
<button className="w-full">{this.props.button}</button>
</a>
</div>
</div>
);
}
}
export default ctaSection;
Then, in my index.js, I'm rendering like this, passing the props:
let ctaPage1 = document.getElementById('cta-section-page-1');
let ctaPage2 = document.getElementById('cta-section-page-2');
ReactDOM.render(<CtaSection h3='my text for page 1' h5='my h5 for page 1' button='hello'/>, ctaPage1);
ReactDOM.render(<CtaSection h3='text for page 2' h5='something' button='click me'/>, ctaPage2);
I'm not sure if this is the best and simpler way to do this, because I'm calling ReactDOM.render twice for same component, and I got this error:
Uncaught Invariant Violation: Target container is not a DOM element.
This works fine if I render the component once, but not for multiple instances.
What is the best way to do it?
I've thought about this more, and I'm not experienced with adding React to existing websites, but here's what I'd suggest:
I would have 1 JS file per HTML page that imports CtaSection, each of those files would look like such:
// page1.js
import CtaSection from '../CtaSection'; // or wherever it is
let ctaPage = document.getElementById('cta-section-page');
ReactDOM.render(<CtaSection h3='my text for page 1' h5='my h5 for page 1' button='hello'/>, ctaPage);
You would just need to make sure each html page uses the corresponding JS file.
// page1.html
<body>
<div id="cta-section-page"></div>
<script src="page1.js"></script>
</body>
Repeat for each page.
So I have a DIV element that, when pressed, I want to open a new tab in a different window. The only problem is, whenever the page is refreshed or any other div element is pressed, th function is initiated as well and opens a page in another window. I'll include my code below, but I'm not sure why this is happening seeing as how I'm using onClick={window.open("https://www.thechinesewriter.com") Like I said, I only want a new tab to open when the div is pressed, not when any other items on the page are clicked or even when the page itself is refreshed.
import React from "react";
import "./Column1.css";
class Column1 extends React.Component {
render() {
return(
<React.Fragment>
<div className="rectImage">
<img className="imagePost" src={this.props.image} />
</div>
<div onClick={window.open("https://www.thechinesewriter.com")} className="downloadBut1">
<h2>
Source
</h2>
</div>
<div className="downloadBut2">
<h2>
Repository
</h2>
</div>
</React.Fragment>
)
}
}
export default Column1;
You need to call the function as a callback like this.
<div onClick={() => window.open("https://www.thechinesewriter.com")} className="downloadBut1">
Otherwise this gets called every time the component gets rendered.
You use an expression, which will execute everytime the component is rendered.
<div onClick={window.open("https://www.thechinesewriter.com")} className="downloadBut1">
You probably mean to use a function
<div onClick={() => window.open("https://www.thechinesewriter.com")} className="downloadBut1">
I'm using Ant Design and React js for my Project.
Problem
I have a button in Popover and having click event for that button. The problem is button click event is not triggering.
JS Code
const content = (
<div className="RecurringPopover">
<button onClick={this.handleClick}> Popover Button </button>
</div>
);
Full Code with scenario in stackblitz
You have defined content outside the class and then supplying this.handleClick as a click handler to it. However outside class, this does not point to the class. You should define content inside class and use this.content to access that.
handleClick() {
alert('test');
}
// put it inside class
content = (
<div className="RecurringPopover">
<button onClick={this.handleClick}> Popover Button </button>
</div>
);
render() {
return (
<div>
<Row>
<Col span={12}>
// Use this.content instead of just content
<Popover content={this.content} title="Title">
<span type="primary">Hover me (Popover Button)</span>
Just bring the 'content' to inside the class, and pass it to component via 'this.content', it will work.
I'm relevantly new to React and I am having trouble on how to tackle this logic:
Essentially I am creating a table using flexbox, and I also want it so that when you click on one of the rows, it expands and reveals another row (for example, it will give a small description what it is about).
So far what I have is just the table.
class Application extends React.Component {
render() {
const renderDataRows = (
[
<div key={0} className='row'>
<div className='cell description'> Mortage Bill
</div>
<div className='cell amount'>$0,000,000</div>
<div className='cell amount'>$2.50</div>
<div className='cell amount'v>000%</div>
</div>,
<div key={1} className='row'>
<div className='cell description'> Electric Bill
</div>
<div className='cell amount'>$0,000,000</div>
<div className='cell amount'>$2.50</div>
<div className='cell amount'v>000%</div>
</div>,
]
)
const containerTable = (
<div className='table-container'>
{renderDataRows}
</div>
)
return (
<div>
{containerTable}
</div>
)
}
}
More specifically, what would be the best way to structure the hidden rows? Create as a child of the cells, or siblings?
I am assuming I will need state to keep in track what is current open, etc?
I've attached Codepen link to mess around
This can be done in the following way:
Let all the cells be in a single parent div and let the cell description be another sibling div (although using would be better). Put a class on the sibling div such as hidden. Not add a click handler on the cells div. Whenever this div is clicked, update the state with that div's id/key. Now use this to set the hidden class to the other divs. Compare this.state.key with the current id/key and show or hide accordingly. I am not giving the specific code.
Note: Instead of storing the divs in the renderDataRows, just put the data in it and map over it to create all the divs. That way you can easily manipulate the hidden class and any other variation in a single place without having to update it separately for each row of data.
I have the following problem:
I want to write jsx code like
<div className="my-section">
<Window>
<div>Window content</div>
</Window>
</div>
<div className="window-container">
</div>
somewhere in my react content, but I want the window to render in a special DOM element with other windows, something like
<div class="my-section"></div>
<div class="window-container">
<div class="window">
<div>Window Content</div>
</div>
</div>
And to do this transparently I need to tell the component to render to a special DOM node from within the component. Is there a way to do this? If not, how should I accomplish the functionality I am looking for from within React?
You're looking for the special this.props.children list.
When you create a React component instance, you can include additional React components or JavaScript expressions between the opening and closing tags like this:
<Parent><Child /></Parent>
Parent can read its children by accessing the special this.props.children prop.
This will allow you to get the children defined inside your element, then insert them at an arbitrary point for render.
render() {
return (
<div className="window container">
<div className="window">{this.props.children}</div>
<div className="window"></div>
...
</div>
);
}