Bootstrap5 modal not displaying in React.js after clicking on the button - javascript

I am using bootstrap5 to React. I successfully installed the bootstrap5 in React. Now I have to show the modal on my page so I added a button and modal code on my page.
Below is the code I am using for the modal. Now I click on the button then nothing is working. I am not getting my modal.
What is the issue here?
import React from "react";
function addEmployee(){
return(
<div className="addEmployee">
<button type="button" className="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdrop">Add Employee</button>
<div className="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabIndex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="staticBackdropLabel">Modal title</h5>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div className="modal-body">
...
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" className="btn btn-primary">Understood</button>
</div>
</div>
</div>
</div>
</div>
)
}
export default addEmployee;

Bootstrap 5 no longer depends on jQuery so you don't need a 3rd party library library like react-bootstrap to use Bootstrap in React. For example you can use the data-bs- attributes in the markup, or create a functional component for the Bootstrap modal with methods to show/hide the modal...
function ModalExample() {
const modalRef = useRef()
const showModal = () => {
const modalEle = modalRef.current
const bsModal = new bootstrap.Modal(modalEle, {
backdrop: 'static',
keyboard: false
})
bsModal.show()
}
const hideModal = () => {
const modalEle = modalRef.current
const bsModal= bootstrap.Modal.getInstance(modalEle)
bsModal.hide()
}
return(
<div className="addEmployee">
<button type="button" className="btn btn-primary" onClick={showModal}>Add Employee</button>
<div className="modal fade" ref={modalRef} tabIndex="-1" >
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="staticBackdropLabel">Modal title</h5>
<button type="button" className="btn-close" onClick={hideModal} aria-label="Close"></button>
</div>
<div className="modal-body">
...
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" onClick={hideModal}>Close</button>
<button type="button" className="btn btn-primary">Understood</button>
</div>
</div>
</div>
</div>
</div>
)
}
Demo of both methods

I would suggest you'd use react-bootstrap its a lot easier and the javascript has been done for you
React-Bootstrap replaces the Bootstrap JavaScript
Each component has been built from scratch as a React component, without unneeded dependencies like jQuery.
To get started just install the package npm install react-bootstrap bootstrap
look at this example
import { Modal, Button } from "react-bootstrap";
function Example() {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Button variant="primary" onClick={handleShow}>
Launch demo modal
</Button>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleClose}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
);
}
render(<Example />);
Gaurav Singhal's blog # PluralSight
You must use controlled components that use the internal state to set
the values and change the behavior of a component. Libraries like
jQuery do direct DOM manipulation, whereas React components use
Virtual DOM to modify the actual DOM on the browser. Using jQuery to
change your component's behavior is possible. Still, it will lead to
unexpected results and make it difficult to debug. React Bootstrap
implements each component in pure React, so you don't have to worry
about Bootstrap's dependency on jQuery
to check out their (react-bootstrap) documentation page ,here is the link you can follow/go to react-bootstrap

Related

.map returning first value in array

world... again.
I'm stumped by something that should be straightforward, but right now I cant see it. I'm trying to map over a simple array and display values. Each card should have a button that opens a bs modal which should show more information on the particular array object. but instead it returns infomation only on the first object in the array.
I think there's a concept here that I'm not getting and it's a shade embarassing. Thaank's in advance for your help.
import "./styles.css";
export default function App() {
const modalInfo = [
{ name: "james", number: "1" },
{ name: "Jackie", number: "2" },
{ name: "Ariane", number: "3" },
{ name: "Mike", number: "4" }
];
return (
<>
<div className="App">
{modalInfo.map((info) => (
<div className="card">
<h1>{info.name}</h1>
<button
type="button"
class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#staticBackdrop"
>
Show more
</button>
<div
class="modal fade"
id="staticBackdrop"
data-bs-backdrop="static"
data-bs-keyboard="false"
tabindex="-1"
aria-labelledby="staticBackdropLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">
#{info.number}
</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">{info.name}</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
>
Close
</button>
<button type="button" class="btn btn-primary">
Understood
</button>
</div>
</div>
</div>
</div>
</div>
))}
</div>
</>
);
}
This is the current error in console , I copied the code from sandbox and plugged it into another project with bootstrap:
Uncaught TypeError: 'querySelector' called on an object that does not
implement interface Element. findOne selector-engine.js:24
_showElement modal.js:217 show modal.js:143 y index.js:251 show backdrop.js:54 y index.js:251 r index.js:273 selector-engine.js:24:43
You must be getting some unique key error in your console.
Give a key to you card that acts a a unique id for your card.
<....
{modalInfo.map((info, index) => (
<div className="card" key={info.index}>
...>
You can give index as well as a unique id but that not correct way just for testing you can. But from what I see is the number property is incrementing by 1 as well so that's why I have kept index as the key.
id attributes must be unique in a document. You are re-using staticBackdrop in each map iteration so they're being duplicated.
When Bootstrap tries to grab the modal target by #staticBackdrop, it only gets the first one because that's what happens with repeated IDs.
Using the info.id properties from your sandbox link, try incorporating that into the id and data-bs-target attributes
{modalInfo.map((info) => (
<div className="card" key={info.id}> {/* keys are important, don't use index */}
<h1>{info.name}</h1>
<button
type="button"
className="btn btn-primary"
data-bs-toggle="modal"
data-bs-target={`#staticBackdrop_${info.id}`}
>
Show more
</button>
<div
className="modal fade"
id={`staticBackdrop_${info.id}`}
data-bs-backdrop="static"
data-bs-keyboard="false"
tabIndex="-1"
aria-labelledby={`staticBackdropLabel_${info.id}`}
aria-hidden="true"
>
{/* the rest of your markup goes here */}
</div>
</div>
))}
You also have a bunch of class attributes that should be className and a repeated id="staticBackdropLabel" that should get a similar treatment to staticBackdrop.

How to trigger bootstrap modal programatically in reactjs

Onclick of a button i need to validate some data, if it is true then i need to open modal or no. But in my condition modal is opening for every click unable to it programatically
function verifyOtp(){
if(sucsess){}
else{}
}
<button onClick={()}=>verifyOtp() data-toggle="modal" data-target="#successModal">
</button>
<div className="modal fade" id="successModal" tabindex="-1" role="dialog" aria-labelledby = "emailModalLabel" aria-hidden="true">
<div className="modal-dialog email-modal-dialog" role="document">
<div className="modal-content verify-modal-dialog">
<div className="modal-header email-modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<p className="modal-title email-modal-title" id="emailModalLabel">Succesfull</p>
</div>
</div>
</div>
You Need to use State here is the working-class component example of a model. if you are using functional components then use useState() hook instead of this.setState() method
import React from "react";
export default class AddNewList extends React.Component {
state = {
showModal: false
};
closeModal = () => {
this.setState({ showModal: false });
};
onSave = () => {
console.log("i saved the data.");
this.setState({ showModal: false });
};
verifyOtp = () => {
//your success value
if (true) {
this.setState({ showModal: true });
}
};
render() {
return (
<>
<div>
<button onClick={this.verifyOtp} className="btn btn-primary btn-lg">
Open Modal
</button>
</div>
{this.state.showModal && (
<div className="" id="addnewlist">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title"> Model Header</h4>
</div>
<div className="modal-body">
test
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-danger"
data-dismiss="modal"
onClick={this.closeModal}
>
Close
</button>
<button
type="button"
className="btn btn-outline-success"
onClick={this.onSave}
>
Save
</button>
</div>
</div>
</div>
</div>
)}
</>
);
}
}
Skeleton for the functional component
import React, {useState} from 'react'
const [showModel,setShowModel] = useState(false);
function AddNewList (){
closeModal = () => {
setShowModel(false);
};
onSave = () => {
setShowModel(false);
};
verifyOtp = () => {
//your success value
if (true) {
setShowModel(true);
}
};
return render();
}

Open a modal popUp in React

I have this button in react:
<button type="button" className="btn btn-primary" onClick={()=>openPopUp(object)}>
Manage Permissions
</button>
and when I click the buton I want to open this popUp:
PopUp.js:
const PopUp = (props) => {
return (
<div className="modal fade" tabIndex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">{props.object.name}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{props.object.permissions.map((permission) => {
return (
<li key={permission.code}>
{permission.name}
{props.showDeleteButton(permission.id, props.object.name)}
<p> </p>
</li>
)
})}
<form onSubmit={e => props.addPermission(e, props.object)}>
<label>
Insert a permission:
<input type="text" value={props.object.value} onChange={props.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
</div>
)
}
To do that, I did this, but the pop up wont open:
let openPopUp=(object)=>{
return <PopUp object={object} cont={cont} onChange={handleChange} addPermission={addPermission} showDeleteButton={showDeleteButton}/>
}
There is any error thrown, the popUp just doesn´t open.
It is because openPopUp is a onclick handler, it will not return anything to render. To achieve your goal, simply use a state variable with initial value as false, and update that value in openPopUp method. Use that bool for conditional rendering of PopUp component.
Like this:
constructor() {
super();
this.state = {
openPopUp: false,
object: null
}
}
openPopUp(object) {
this.setState({
openPopUp: true,
object: object
})
}
render() {
return (
<div>
....
{this.state.openPopUp &&
<PopUp object={this.state.object} cont={cont} onChange={handleChange} addPermission={addPermission} showDeleteButton={showDeleteButton} />}
....
</div>
)
}

Open a modal on another modal with ReactJS

I made a modal using Bootstrap, however I need a confirmation modal that goes above it. This second one will appear as a confirmation dialog for when one of the first modal's buttons are pressed.
This is roughly what my code looks like:
constructor(props) {
super(props)
this.state = {
displayConfirmModal: false
}
}
confirmModal () {
return (
<div ref={(ref) => { (this.modal = ref) }} className='modal fade' id='confirm' tabIndex={-1} role='dialog' aria-labelledby='GPA Modal'>
<section>
<h3>Are you sure of this?</h3>
<button
className='btn btn-danger'
onClick={()=> doTheThing()}>
Yes
</button>
<button
className='btn btn-danger'
onClick={()=> hideConfirmModal()}>
No
</button>
</section>
</div>
)
}
render () {
return (
<div>
<div ref={(ref) => { (this.modal = ref) }} className='modal fade' id='main' tabIndex={-1} role='dialog' aria-labelledby='GPA Modal'>
<section>
<a className='close' data-dismiss='modal' aria-label='Close' onClick={() => this.hideModal()}>close</a>
<div className='frame'>
<h1>My first modal</h1>
<button
className='btn btn-default'
onClick={() => { this.setState({displayConfirmModal: true})}}>
Open confirmation modal
</button>
</div>
</section>
</div>
{ this.state.displayConfirmModal ? this.confirmModal() : null }
</div>
)
}
As it is right now when I click on the Open confirmation modal button, it sets my displayConfirmModal state to true, but doesn't display the modal.
However, if I start the displayConfirmModal state on true, it does display it, and when I close it, it closes the whole thing.
How do I do this? And if so, is there a better alternative way of doing this?
Thanks!

Bootstrap modal in React.js

I need to open a Bootstrap Modal from clicking on a button in a Bootstrap navbar and other places (to show data for a component instance, ie. providing "editing" functionality), but I don't know how to accomplish this. Here is my code:
EDIT: Code updated.
ApplicationContainer = React.createClass({
render: function() {
return (
<div className="container-fluid">
<NavBar />
<div className="row">
<div className="col-md-2">
<ScheduleEntryList />
</div>
<div className="col-md-10">
</div>
</div>
<ScheduleEntryModal />
</div>
);
}
});
NavBar = React.createClass({
render: function() {
return (
<nav className="navbar navbar-default navbar-fixed-top">
<div className="container-fluid">
<div className="navbar-header">
<a className="navbar-brand" href="#">
<span className="glyphicon glyphicon-eye-open"></span>
</a>
</div>
<form className="navbar-form navbar-left">
<button className="btn btn-primary" type="button" data-toggle="modal" data-target="#scheduleentry-modal">
<span className="glyphicon glyphicon-plus">
</span>
</button>
</form>
<ul className="nav navbar-nav navbar-right">
<li><span className="glyphicon glyphicon-user"></span> Username</li>
</ul>
</div>
</nav>
);
}
});
ScheduleEntryList = React.createClass({
getInitialState: function() {
return {data: []}
},
loadData: function() {
$.ajax({
url: "/api/tasks",
dataType: "json",
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, error) {
console.error("/api/tasks", status, error.toString());
}.bind(this)
});
},
componentWillMount: function() {
this.loadData();
setInterval(this.loadData, 20000);
},
render: function() {
items = this.state.data.map(function(item) {
return <ScheduleEntryListItem item={item}></ScheduleEntryListItem>;
});
return (
<div className="list-group">
<a className="list-group-item active">
<h5 className="list-group-item-heading">Upcoming</h5>
</a>
{items}
</div>
);
}
});
ScheduleEntryListItem = React.createClass({
openModal: function() {
$("#scheduleentry-modal").modal("show");
},
render: function() {
deadline = moment(this.props.item.deadline).format("MMM Do YYYY, h:mm A");
return (
<a className="list-group-item" href="#" onClick={this.openModal}>
<h5 className="list-group-item-heading">
{this.props.item.title}
</h5>
<small className="list-group-item-text">
{deadline}
</small>
</a>
);
}
});
Modal = React.createClass({
componentDidMount: function() {
$(this.getDOMNode())
.modal({backdrop: "static", keyboard: true, show: false});
},
componentWillUnmount: function() {
$(this.getDOMNode())
.off("hidden", this.handleHidden);
},
open: function() {
$(this.getDOMNode()).modal("show");
},
close: function() {
$(this.getDOMNode()).modal("hide");
},
render: function() {
return (
<div id="scheduleentry-modal" className="modal fade" tabIndex="-1">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">
<span>×</span>
</button>
<h4 className="modal-title">{this.props.title}</h4>
</div>
<div className="modal-body">
{this.props.children}
</div>
<div className="modal-footer">
<button type="button" className="btn btn-danger pull-left" data-dismiss="modal">Delete</button>
<button type="button" className="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
)
}
});
ScheduleEntryModal = React.createClass({
render: function() {
var modal = null;
modal = (
<Modal title="Add Schedule Entry">
<form className="form-horizontal">
<div className="form-group">
<label htmlFor="title" className="col-sm-2 control-label">Title</label>
<div className="col-sm-10">
<input id="title" className="form-control" type="text" placeholder="Title" ref="title" name="title"/>
</div>
</div>
<div className="form-group">
<label htmlFor="deadline" className="col-sm-2 control-label">Deadline</label>
<div className="col-sm-10">
<input id="deadline" className="form-control" type="datetime-local" ref="deadline" name="deadline"/>
</div>
</div>
<div className="form-group">
<label htmlFor="completed" className="col-sm-2 control-label">Completed</label>
<div className="col-sm-10">
<input id="completed" className="form-control" type="checkbox" placeholder="completed" ref="completed" name="completed"/>
</div>
</div>
<div className="form-group">
<label htmlFor="description" className="col-sm-2 control-label">Description</label>
<div className="col-sm-10">
<textarea id="description" className="form-control" placeholder="Description" ref="description" name="description"/>
</div>
</div>
</form>
</Modal>
);
return (
<div className="scheduleentry-modal">
{modal}
</div>
);
}
});
Other comments and improvements to the code are appreciated.
I was recently looking for a nice solution to this without adding React-Bootstrap to my project (as Bootstrap 4 is about to be released).
This is my solution: https://jsfiddle.net/16j1se1q/1/
let Modal = React.createClass({
componentDidMount(){
$(this.getDOMNode()).modal('show');
$(this.getDOMNode()).on('hidden.bs.modal', this.props.handleHideModal);
},
render(){
return (
<div className="modal fade">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title">Modal title</h4>
</div>
<div className="modal-body">
<p>One fine body…</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" className="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
)
},
propTypes:{
handleHideModal: React.PropTypes.func.isRequired
}
});
let App = React.createClass({
getInitialState(){
return {view: {showModal: false}}
},
handleHideModal(){
this.setState({view: {showModal: false}})
},
handleShowModal(){
this.setState({view: {showModal: true}})
},
render(){
return(
<div className="row">
<button className="btn btn-default btn-block" onClick={this.handleShowModal}>Open Modal</button>
{this.state.view.showModal ? <Modal handleHideModal={this.handleHideModal}/> : null}
</div>
);
}
});
React.render(
<App />,
document.getElementById('container')
);
The main idea is to only render the Modal component into the React DOM when it is to be shown (in the App components render function). I keep some 'view' state that indicates whether the Modal is currently shown or not.
The 'componentDidMount' and 'componentWillUnmount' callbacks either hide or show the modal (once it is rendered into the React DOM) via Bootstrap javascript functions.
I think this solution nicely follows the React ethos but suggestions are welcome!
You can use React-Bootstrap (https://react-bootstrap.github.io/components/modal). There is an example for modals at that link. Once you have loaded react-bootstrap, the modal component can be used as a react component:
var Modal = ReactBootstrap.Modal;
can then be used as a react component as
<Modal/>.
For Bootstrap 4, there is react-strap (https://reactstrap.github.io). React-Bootstrap only supports Bootstrap 3.
getDOMNode() is deprecated. Instead use ref to access DOM element. Here is working Modal component (Bootstrap 4).
Decide whether to show or not to show Modal component in parent component.
Example: https://jsfiddle.net/sqfhkdcy/
class Modal extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
$(this.modal).modal('show');
$(this.modal).on('hidden.bs.modal', handleModalCloseClick);
}
render() {
return (
<div>
<div className="modal fade" ref={modal=> this.modal = modal} id="exampleModal" tabIndex="-1" role="dialog" aria- labelledby="exampleModalLabel" aria-hidden="true">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLabel">Modal title
</h5>
<button type="button" className="close" data- dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
...
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data- dismiss="modal">Close</button>
<button type="button" className="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
Edit:
Here are the necessary imports to make it work:
import $ from 'jquery';
window.jQuery = $;
window.$ = $;
global.jQuery = $;
I've only used bootstrap cdn (css + js) to achieve "reactstrap" like solution. I've used props.children to pass dynamic data from parent to child components. You can find more about this here. In this way you have three separate components modal header, modal body and modal footer and they are totally independent from each other.
//Modal component
import React, { Component } from 'react';
export const ModalHeader = props => {
return <div className="modal-header">{props.children}</div>;
};
export const ModalBody = props => {
return <div className="modal-body">{props.children}</div>;
};
export const ModalFooter = props => {
return <div className="modal-footer">{props.children}</div>;
};
class Modal extends Component {
constructor(props) {
super(props);
this.state = {
modalShow: '',
display: 'none'
};
this.openModal = this.openModal.bind(this);
this.closeModal = this.closeModal.bind(this);
}
openModal() {
this.setState({
modalShow: 'show',
display: 'block'
});
}
closeModal() {
this.setState({
modalShow: '',
display: 'none'
});
}
componentDidMount() {
this.props.isOpen ? this.openModal() : this.closeModal();
}
componentDidUpdate(prevProps) {
if (prevProps.isOpen !== this.props.isOpen) {
this.props.isOpen ? this.openModal() : this.closeModal();
}
}
render() {
return (
<div
className={'modal fade ' + this.state.modalShow}
tabIndex="-1"
role="dialog"
aria-hidden="true"
style={{ display: this.state.display }}
>
<div className="modal-dialog" role="document">
<div className="modal-content">{this.props.children}</div>
</div>
</div>
);
}
}
export default Modal;
//App component
import React, { Component } from 'react';
import Modal, { ModalHeader, ModalBody, ModalFooter } from './components/Modal';
import './App.css';
class App extends 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 className="App">
<h1>Bootstrap Components</h1>
<button
type="button"
className="btn btn-secondary"
onClick={this.toggle}
>
Modal
</button>
<Modal isOpen={this.state.modal}>
<ModalHeader>
<h3>This is modal header</h3>
<button
type="button"
className="close"
aria-label="Close"
onClick={this.toggle}
>
<span aria-hidden="true">×</span>
</button>
</ModalHeader>
<ModalBody>
<p>This is modal body</p>
</ModalBody>
<ModalFooter>
<button
type="button"
className="btn btn-secondary"
onClick={this.toggle}
>
Close
</button>
<button
type="button"
className="btn btn-primary"
onClick={this.toggle}
>
Save changes
</button>
</ModalFooter>
</Modal>
</div>
);
}
}
export default App;
I Created this function:
onAddListItem: function () {
var Modal = ReactBootstrap.Modal;
React.render((
<Modal title='Modal title' onRequestHide={this.hideListItem}>
<ul class="list-group">
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Morbi leo risus</li>
<li class="list-group-item">Porta ac consectetur ac</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
</Modal>
), document.querySelector('#modal-wrapper'));
}
And then used it on my Button trigger.
To 'hide' the Modal:
hideListItem: function () {
React.unmountComponentAtNode(document.querySelector('#modal-wrapper'));
},
You can use the model from the react-bootstrap from link and it's basically a function based
function Example() {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Button variant="primary" onClick={handleShow}>
Launch demo modal
</Button>
<Modal show={show} onHide={handleClose} animation={false}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleClose}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
);
}
and You can convert it into the class component
import React, { Component } from "react";
import { Button, Modal } from "react-bootstrap";
export default class exampleextends Component {
constructor(props) {
super(props);
this.state = {
show: false,
close: false,
};
}
render() {
return (
<div>
<Button
variant="none"
onClick={() => this.setState({ show: true })}
>
Choose Profile
</Button>
<Modal
show={this.state.show}
animation={true}
size="md" className="" shadow-lg border">
<Modal.Header className="bg-danger text-white text-center py-1">
<Modal.Title className="text-center">
<h5>Delete</h5>
</Modal.Title>
</Modal.Header>
<Modal.Body className="py-0 border">
body
</Modal.Body>
<Modal.Footer className="py-1 d-flex justify-content-center">
<div>
<Button
variant="outline-dark" onClick={() => this.setState({ show: false })}>Cancel</Button>
</div>
<div>
<Button variant="outline-danger" className="mx-2 px-3">Delete</Button>
</div>
</Modal.Footer>
</Modal>
</div>
);
}
}
You can try this modal:https://github.com/xue2han/react-dynamic-modal
It is stateless and can be rendered only when needed.So it is very easy to use.Just like this:
class MyModal extends Component{
render(){
const { text } = this.props;
return (
<Modal
onRequestClose={this.props.onRequestClose}
openTimeoutMS={150}
closeTimeoutMS={150}
style={customStyle}>
<h1>What you input : {text}</h1>
<button onClick={ModalManager.close}>Close Modal</button>
</Modal>
);
}
}
class App extends Component{
openModal(){
const text = this.refs.input.value;
ModalManager.open(<MyModal text={text} onRequestClose={() => true}/>);
}
render(){
return (
<div>
<div><input type="text" placeholder="input something" ref="input" /></div>
<div><button type="button" onClick={this.openModal.bind(this)}>Open Modal </button> </div>
</div>
);
}
}
ReactDOM.render(<App />,document.getElementById('main'));
Thanks to #tgrrr for a simple solution, especially when 3rd party library is not wanted (such as React-Bootstrap). However, this solution has a problem: modal container is embedded inside react component, which leads to modal-under-background issue when outside react component (or its parent element) has position style as fixed/relative/absolute. I met this problem and came up to a new solution:
"use strict";
var React = require('react');
var ReactDOM = require('react-dom');
var SampleModal = React.createClass({
render: function() {
return (
<div className="modal fade" tabindex="-1" role="dialog">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title">Title</h4>
</div>
<div className="modal-body">
<p>Modal content</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" className="btn btn-primary">OK</button>
</div>
</div>
</div>
</div>
);
}
});
var sampleModalId = 'sample-modal-container';
var SampleApp = React.createClass({
handleShowSampleModal: function() {
var modal = React.cloneElement(<SampleModal></SampleModal>);
var modalContainer = document.createElement('div');
modalContainer.id = sampleModalId;
document.body.appendChild(modalContainer);
ReactDOM.render(modal, modalContainer, function() {
var modalObj = $('#'+sampleModalId+'>.modal');
modalObj.modal('show');
modalObj.on('hidden.bs.modal', this.handleHideSampleModal);
}.bind(this));
},
handleHideSampleModal: function() {
$('#'+sampleModalId).remove();
},
render: function(){
return (
<div>
<a href="javascript:;" onClick={this.handleShowSampleModal}>show modal</a>
</div>
)
}
});
module.exports = SampleApp;
The main idea is:
Clone the modal element (ReactElement object).
Create a div element and insert it into document body.
Render the cloned modal element in the newly inserted div element.
When the render is finished, show modal. Also, attach an event listener, so that when modal is hidden, the newly inserted div element will be removed.
Reactstrap also has an implementation of Bootstrap Modals in React. This library targets Bootstrap version 4, whereas react-bootstrap targets version 3.X.
I got the following code working with bootstrap 5 and react hooks
const ref = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
if (ref.current) {
ref.myModal = new bootstrap.Modal(ref.current, { backdrop: true });
}
}, [ref]);
to show the modal i use this code inside my component
<button
className="btn btn-primary"
onClick={() => {
if (ref.myModal) {
ref.myModal.show();
}
}}
>
open modal
</button>
<div
className="modal fade"
tabIndex={-1}
aria-labelledby="uploadYoutubeModalLabel"
aria-hidden="true"
ref={ref}
>
<div className="modal-dialog">bla</div>
</div>
this binds myModel to the ref and you can call ref.myModal.show() to open the modal and ref.myModal.hide()
The quickest fix would be to explicitly use the jQuery $ from the global context (which has been extended with your $.modal() because you referenced that in your script tag when you did ):
window.$('#scheduleentry-modal').modal('show') // to show
window.$('#scheduleentry-modal').modal('hide') // to hide
so this is how you can about it on react
import React, { Component } from 'react';
export default Modal extends Component {
componentDidMount() {
window.$('#Modal').modal('show');
}
handleClose() {
window.$('#Modal').modal('hide');
}
render() {
<
div className = 'modal fade'
id = 'ModalCenter'
tabIndex = '-1'
role = 'dialog'
aria - labelledby = 'ModalCenterTitle'
data - backdrop = 'static'
aria - hidden = 'true' >
<
div className = 'modal-dialog modal-dialog-centered'
role = 'document' >
<
div className = 'modal-content' >
// ...your modal body
<
button
type = 'button'
className = 'btn btn-secondary'
onClick = {
this.handleClose
} >
Close <
/button> < /
div > <
/div> < /
div >
}
}
Just add href='#scheduleentry-modal' to the element you want to open the modal with
Or using jQuery: $('#scheduleentry-modal').modal('show');

Categories