Toggle FieldSet from an other component - reactjs

How to make PrimeReact FieldSet controllable from an other (parent) component on React?
I have a boolean object toggled, i would like to pass it into child component.
When toggled = true, the FieldSet should be opened.
When toggled = false, the FieldSet should be closed.
import React from "react";
import { Fieldset } from "primereact/fieldset";
const FieldsetDemo = () => {
return (
<div>
<div className="card">
<h5>Toggleable</h5>
<Fieldset legend="Header" toggleable>
<p>
Lorem ipsum dolor sit amet.
</p>
</Fieldset>
</div>
</div>
);
};

Its easy. Working code sandbox: https://codesandbox.io/s/quizzical-snow-so91tv?file=/src/demo/FieldsetDemo.js
const FieldsetDemo = (props) => {
return (
<div>
<div className="card">
<h5>Toggleable</h5>
<Fieldset legend="Header" toggleable collapsed={props.collapsed}>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</p>
</Fieldset>
</div>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<FieldsetDemo collapsed={true} />, rootElement);

Related

Render custom components in React Markdown

I'm building my website documentation and I need to render custom component and it's props, such as <Callout>Hi! I'm a callout</Callout>.
I'm using contentlayer for the directory and react-markdown to render the content.
Here's my code.
<ReactMarkdown
rehypePlugins={[rehypeRaw]}
className={s.markdown}
components={{
code({ inline, children, ...props }) {
if (!inline) {
return (
<SyntaxHighlighter
style={coldarkDark}
language={'typescript'}
>
{String(children).replace(/\n$/, '')}
</SyntaxHighlighter>
)
}
return <code {...props}>{children}</code>
},
}}
>
{currentDoc.body}
</ReactMarkdown>
{currentDoc.body} is markdown. So, with this example, I'm passing this to <ReactMarkdown />:
Mollit nisi cillum exercitation minim officia velit laborum non Lorem
adipisicing dolore. Labore commodo consectetur commodo velit adipisicing irure
dolore dolor reprehenderit aliquip. Reprehenderit cillum mollit eiusmod
excepteur elit ipsum aute pariatur in. Cupidatat ex culpa velit culpa ad non
labore exercitation irure laborum.
<Callout>Hi! I'm a callout</Callout>
Hey! [link](https://github.com/rehypejs/rehype-react) right here
The idea is to catch your component Callout from your markdown and render it?
If so, I think i would use a custom "code language" in your markdown, and then parse it in yourcomponents callback from react-markdown.
For example, your markdown would be
Mollit nisi cillum exercitation minim officia velit laborum non Lorem
adipisicing dolore. Labore commodo consectetur commodo velit adipisicing irure
dolore dolor reprehenderit aliquip. Reprehenderit cillum mollit eiusmod
excepteur elit ipsum aute pariatur in. Cupidatat ex culpa velit culpa ad non
labore exercitation irure laborum.
```callout
Hi! I'm a callout
```
Something else....
React-markdown then render anything as code with a particular className using language-{code} which means in this case language-callout. So you need to catch it and render your callout depending on the className
code({ inline, className, children, ...props }) {
if (inline) return <code {...props}>{children}</code>
const value = String(children).replace(/\n$/, '');
if (className === "language-callout") return (
<Callout>{value}</Callout>
)
return (
<SyntaxHighlighter
style={coldarkDark}
language={'typescript'}
>
{value}
</SyntaxHighlighter>
)
}

i am not able to update modal state based on received props value from other component in reactjs

i am not able to update modal state based on received props value from other component in reactjs. i have tried all things but not working. please suggest on it it will be appreciable.
const ModalExample = ({ elem }) => {
const [modal, setModal] = useState(elem);
useEffect(() => {
console.log('elem', elem);
})
const toggle = () => {
setModal(false);
}
return (
<div>
<Modal isOpen={modal} toggle={toggle}>
<ModalHeader toggle={toggle}>Modal title</ModalHeader>
<ModalBody>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={toggle}>Do Something</Button>{' '}
<Button color="secondary" onClick={toggle}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
);
}
Instead of passing elem prop directly inside useState
do something like this.
const [modal, setModal] = useState(false)
useEffect(() => {
setModal(Boolean(elem)) // I suppose it is not boolean so make it boolean
},[elem])

How to prevent pre-loading of my modal when it is definied of false in localStorage?

I created a modal that opens when it has not been read yet and which no longer opens when it has been read. I have stored the value false in the localStorage and if it has been read it opens and then closes. I wish it would never open if it hasn't been read.
import React, { useEffect, useState } from "react";
import Loader from "react-loader-spinner";
export default function Modal() {
const [isOpen, setIsOpen] = useState(true);
useEffect(()=>{
const isRead = localStorage.getItem("value");
if (isRead){
setIsOpen(false)
} else if (!isRead){setIsOpen(true)};
},[])
return (
<>
{isOpen && (
<div>
<button
className="close" onClick={()=>{ setIsOpen(false) || localStorage.setItem("value", false)}}
/>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.
</p>
</div>
)}
{!isOpen && (
<Loader
className="spinner"
type="ThreeDots"
color="#F5F5F5"
height={100}
width={100}
timeout={1500}
/>
)}
</>
);
}
I have resolved my problem :
import React, { useEffect, useState } from "react";
import Loader from "react-loader-spinner";
export default function Modal() {
const [isOpen, setIsOpen] = useState(false);
useEffect(()=>{
const isRead = localStorage.getItem("value");
if (!isRead){
setIsOpen(true)
}
},[])
return (
<>
{isOpen && (
<div>
<button
className="close" onClick={()=>{ setIsOpen(false) || localStorage.setItem("value", true)}}
/>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.
</p>
</div>
)}
{!isOpen && (
<Loader
className="spinner"
type="ThreeDots"
color="#F5F5F5"
height={100}
width={100}
timeout={1500}
/>
)}
</>
);
}
The first problem is on this line
else if (!isRead){setIsOpen(true)}
Once isRead returns false i.e the modal was read and then you add the not operator it'll return true and that will set setIsOpen to true which opens the modal.
You can try this:
import React, { useEffect, useState } from "react";
import Loader from "react-loader-spinner";
export default function Modal() {
const [isOpen, setIsOpen] = useState(true);
useEffect(()=>{
const isRead = localStorage.getItem("value");
if (isRead){
setIsOpen(false)
}
},[])
return (
<>
{isOpen && (
<div>
<button
className="close" onClick={()=>{ setIsOpen(false) || localStorage.setItem("value", true)}}
/>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.
</p>
</div>
)}
{!isOpen && (
<Loader
className="spinner"
type="ThreeDots"
color="#F5F5F5"
height={100}
width={100}
timeout={1500}
/>
)}
</>
);
}

The same data for different list items. React.js

I'm new to React.js and I'm trying to make a study project. The problem I have is the following. I have a list of JSON objects (posts) that must be shown, and when clicking the title, the post details appear in a modal window. But independently on the post I click, the modal window always shows me only the first post's details. Here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>React App</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
</head>
<body>
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="./style.css">
<script type="text/babel">
const postsList = [
{
"id": "5",
"title": "Lorem Ipsum dolor",
"contents": "Commodo laborum sit nostrud reprehenderit cupidatat officia laboris. Ipsum minim culpa in enim. Voluptate dolor ea irure nisi incididunt enim magna. Cupidatat quis cillum velit culpa tempor esse irure nostrud ea consectetur officia fugiat irure qui. Enim quis officia do in. Velit veniam ipsum consequat aliqua duis voluptate. Minim nisi ex aute ad. Nisi Lorem ex tempor adipisicing labore. Quis occaecat fugiat pariatur labore culpa cillum laboris. Labore occaecat ut laborum sit ex do sit. Deserunt consectetur elit aute laboris est deserunt officia ullamco sit laboris officia aliquip. Aliqua ut sunt nostrud voluptate excepteur quis incididunt Lorem ut.",
"published": "12.12.1221, 12:10",
"author": {
"nickname": "paladdin"
}
},
{
"id": "3",
"title": "Ex sunt sunt aliqua",
"contents": "Ex sunt sunt aliqua reprehenderit aliqua occaecat. Minim anim commodo officia veniam proident aute cillum eu sunt aute nostrud. Laboris fugiat velit ut pariatur occaecat adipisicing pariatur occaecat. Duis sint enim et consectetur quis pariatur laborum excepteur. Ipsum aliquip qui laborum commodo consectetur do velit veniam occaecat. Ad nisi dolor cillum elit magna dolor voluptate ea. Enim in duis ea consequat sunt Lorem aute.\n\nEst elit sunt quis officia reprehenderit do elit commodo eiusmod esse voluptate. Sit ipsum commodo sint voluptate culpa labore elit magna ullamco nostrud. Laboris magna magna anim labore mollit irure voluptate. Aute non magna aliqua aliqua sunt. Velit mollit consectetur aliqua id tempor ut. Tempor cupidatat aliquip excepteur occaecat incididunt nulla Lorem sint.\n\nNon commodo anim deserunt in et aliquip incididunt ut consectetur sunt esse commodo deserunt et. Tempor fugiat laboris cillum laboris labore. Deserunt quis ad do labore amet culpa officia. Esse et officia nostrud tempor occaecat officia anim incididunt amet sunt excepteur Lorem. Aute occaecat magna velit nisi sit anim consequat velit qui pariatur. Esse incididunt id officia aliqua anim ut et.",
"published": "12.12.1221, 12:05",
"author": {
"nickname": "rebelizer"
}
},
{
"id": "1",
"title": "Hello my new world",
"contents": "Culpa dolor deserunt veniam irure amet officia excepteur labore nisi labore ad labore laborum aute. Ea irure sit exercitation ex. Aliquip dolore duis ullamco labore qui. Et anim irure laborum quis ipsum. Adipisicing culpa est ea velit veniam dolor nisi. Sit cupidatat velit commodo eu.\n\nUt nulla ut irure cillum irure sint sunt cupidatat tempor laboris incididunt elit occaecat fugiat. Reprehenderit enim cupidatat consectetur pariatur ad pariatur consequat veniam do fugiat Lorem laborum do velit. Nulla aute magna magna nisi officia et. Aute adipisicing eu eiusmod tempor exercitation sint non enim laboris dolor adipisicing.\n\nEa do sint pariatur voluptate ad culpa irure. Cillum pariatur deserunt fugiat elit. Exercitation labore amet deserunt magna. Velit veniam aute officia aliqua ipsum veniam pariatur. Aliquip ullamco fugiat officia non sunt ad consequat ipsum est esse commodo reprehenderit. Ad quis consectetur est exercitation fugiat eiusmod. Laborum reprehenderit esse qui irure.",
"published": "12.12.1221, 12:00",
"author": {
"nickname": "rupetra"
}
}
];
class Post extends React.Component {
render() {
const {post} = this.props;
return (
<div className = "card" style={{width: "100%"}}>
<div className = "card-header text-center">
<h2 data-toggle="modal" data-target="#post-details-modal">{post.title}</h2>
</div>
<div className = "card-body text-left">
{post.contents}
</div>
<div className = "card-footer text-right text-muted">
published on {post.published} by <i>{post.author.nickname}</i>
</div>
<div className="modal fade" id="post-details-modal">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title">{post.title}</h4>
<button type="button" className="close" data-dismiss="modal" aria-label="Close"> x </button>
</div>
<div className="modal-body">{post.contents}</div>
<div className="modal-footer text-muted">created by {post.author.nickname}</div>
</div>
</div>
</div>
</div>
);
}
}
class PostList extends React.Component {
render() {
const {posts} = this.props;
return posts.map((post) =>
<div key= {post.id} className="posts">
<Post post = {post}/>
</div>
);
}
}
class App extends React.Component {
render() {
return (
<div>
<div className="row"></div>
<div className="row">
<div className="col-1 text-right mt-4">
<div>
<i className="fas fa-keyboard fa-3x mb-5"></i>
</div>
<div>
<i className="fas fa-redo-alt fa-3x mb-5"></i>
</div>
</div>
<div className="col-8 posts-zone">
<PostList posts = {postsList}/>
</div>
<div className="col-3"></div>
</div>
<div className="row"></div>
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById("root"));
</script>
<div id="root"><div>
</body>
</html>
Solution:
Thanks to Tim Ogilvy, who gave me the rihgt idea, the following solution has been found:
In render() method I created 2 variables:
const dataTargetName = "#post-details-modal-" + post.id;
const postDetailsId = "post-details-modal-" + post.id;
and then:
<h2 data-toggle="modal" data-target={dataTargetName}>{post.title}</h2>
and:
<div className="modal fade" id={postDetailsId}>
You need to use a component with a state of open and closed. Bootstrap and jQuery are not the right solution here. Also you should be using stateless/pure components for most of this. Your issue is in the Post Component.
here you set what it should toggle:
<h2 data-toggle="modal" data-target="#post-details-modal">{post.title}</h2>
and then you set the ID to the same thing for every post in the iterator:
<div className="modal fade" id="post-details-modal">
Try this for example: (the toggle)
<h2
data-toggle="modal"
data-target={`#post-details-modal-${post.id}`}
>
{post.title}
</h2>
the post:
<div className="modal fade" id={`post-details-modal-${post.id}`}>
You should still consider using ReactBootstrap, but this might just get you out of the woods.
The principle: DOM Id's must be unique. You have multiple instances of the same ID so the browser is just going for the first.

Reactstrap Modal unmount on close

I have a Reactstrap Modal in my react app.
I would like the Modal to be unmounted as long as it is not used.
The way the Modal works in the docs example, it simply hides, but the Modal is still mounted.
How do I cause the Modal to unmount when the user closes it?
import React from 'react';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
class ModalExample extends React.Component {
constructor(props) {
super(props);
this.state = {
modal: false
};
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({
modal: !this.state.modal
});
}
render() {
return (
<div>
<Button color="danger" onClick={this.toggle}>{this.props.buttonLabel}</Button>
<Modal isOpen={this.state.modal} toggle={this.toggle} className={this.props.className}>
<ModalHeader toggle={this.toggle}>Modal title</ModalHeader>
<ModalBody>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={this.toggle}>Do Something</Button>{' '}
<Button color="secondary" onClick={this.toggle}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
);
}
}
export default ModalExample;
Inside your render(), optionally render modal based on this.state.modal value.
render() {
return (
<div>
<Button color="danger" onClick={this.toggle}>{this.props.buttonLabel}</Button>
{ this.state.modal && <Modal isOpen={this.state.modal} toggle={this.toggle} className={this.props.className}>
<ModalHeader toggle={this.toggle}>Modal title</ModalHeader>
<ModalBody>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={this.toggle}>Do Something</Button>{' '}
<Button color="secondary" onClick={this.toggle}>Cancel</Button>
</ModalFooter>
</Modal> }
</div>
);
}
}

Resources