Reputation: 341
Error while trying to show bootstrap 5 modal using javascript.
const handleClick = (e) => {
e.preventDefault();
const modalElement = document.getElementById('editUserModal');
const modal = Modal.getOrCreateInstance(modalElement);
modal.show();
};
This is the code for modal
const EditModal = () => {
return (
<>
<div
className="modal fade "
id="editUserModal"
aria-hidden="true"
tabIndex="-1"
>
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalToggleLabel">
Modal 1
</h5>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body">
Show a second modal and hide this one with the button below.
</div>
<div className="modal-footer">
<button
className="btn btn-primary"
data-bs-target="#exampleModalToggle2"
data-bs-toggle="modal"
data-bs-dismiss="modal"
>
Open second modal
</button>
</div>
</div>
</div>
</div>
</>
);
};
export default EditModal;
Uncaught TypeError: Cannot read properties of undefined (reading 'backdrop')
at Modal._initializeBackDrop (modal.js:158:39)
at new Modal (modal.js:69:27)
at Modal.getOrCreateInstance (base-component.js:65:41)
at HTMLAnchorElement.<anonymous> (modal.js:364:22)
at HTMLDocument.handler (event-handler.js:118:19)
I don't want to rely on the react-bootstrap library for this. There was another similar question for the same problem, but it doesn't have a fix either.
Edit: I am attaching the parent components that holds EditModal
import ProfileCard from '../../components/profileCard/ProfileCard';
import EditModal from '../../components/editModal/EditModal';
import { Modal } from 'bootstrap';
const Home = () => {
const handleClick = (e) => {
e.preventDefault();
const modalElement = document.getElementById('editUserModal');
const modal = Modal.getOrCreateInstance(modalElement);
modal.show();
};
return (
<>
<a
className="btn btn-primary"
data-bs-toggle="modal"
onClick={handleClick}
role="button"
>
Open first modal
</a>
<div className="container">
<div className="row mt-5">
<div className="col-md-3"></div>
</div>
</div>
<EditModal />
</>
);
};
export default Home;
Upvotes: 13
Views: 37574
Reputation: 28
Try the following to explicitly set the backdrop:
const handleClick = (e) => {
e.preventDefault();
const modalElement = document.getElementById('editUserModal');
const modal = new Modal(modalElement, {
backdrop: false,
keyboard: true,
focus: true
});
modal.show();
};
Upvotes: 1
Reputation: 477
in this part of your code
<a
className="btn btn-primary"
data-bs-toggle="modal"
onClick={handleClick}
role="button"
>
you added data-bs-toggle
and also you have this in your handleClick
const modal = Modal.getOrCreateInstance(modalElement);
modal.show();
Both of these can not work together
if you delete data-bs-toggle="modal"
from your 'a' tag, then the problem will be resolved.
because already you have modal action in your handleClick
function
Upvotes: 3
Reputation: 11
The below solved my case.
Rather than initialize the modal upon mounting, I initialize it on demand. https://github.com/orgs/twbs/discussions/37304
Upvotes: 1
Reputation: 91
If you have, like I do, two different buttons to toggle the modal :
I was facing this same error until I changed the data-bs-toggle
attribute on one of these two buttons. They apparently need to be different.
data-bs-target
has the same value on two buttons.
Upvotes: 1
Reputation: 1558
since you are showing/hiding modals via a click handler try to remove data-bs-toggle="modal"
.
Upvotes: 8
Reputation: 327
If you conditionally render the modal, just remove the condition, it worked for me. The code snippet with problem, suppose setIsModalOpen becomes true after some button click
function Details(){
const [isModalOpen, setIsModalOpen] = useState(false)
return(
isModalOpen ? <div
className="modal fade"> //Contents </div>: null
)}
The problem resolved when I removed the isModalOpen condition
function Details(){
const [isModalOpen, setIsModalOpen] = useState(false)
return(
<div
className="modal fade"> //Contents </div>
)}
The reason could be that all libraries for modal may not be loaded properly
Upvotes: 1
Reputation: 352
I am encountering the same exact error as is depicted in this post.
The button that opens the modal is on the first line.
The modal begins on the line after the the close table element.
import React, {Component, Fragment} from 'react';
import { variables } from './Variables.js';
export class Department extends Component {
constructor(props) {
super(props);
this.state = {
departments: [],
modalTitle: "",
DepartmentName: "",
DepartmentId: 0
}
}
componentDidMount(){
this.refreshList();
}
refreshList(){
fetch(variables.API_URL + 'department')
.then( response => response.json())
.then( data => {
this.setState({departments:data})
})
}
changeDepartmentName = (e) =>{
this.setState({DepartmentName:e.target.value})
}
//clicks
addClick() {
this.setState({
modalTitle: "Add Department",
departmentId: 0,
DepartmentName: ""
})
console.log()
}
editClick(dep) {
this.setState({
modalTitle: "Edit Department",
departmentId: dep.departmentId,
DepartmentName: dep.DepartmentName
})
}
render(){
const {
departments,
modalTitle,
DepartmentId,
DepartmentName
} = this.state
return (
<Fragment>
<button type="button" className="btn btn-primary m-2 float-end" data-bs-backdrop="static" data-bs-toggle="modal" data-bs-target="exampleModal" onClick={() => this.addClick()}>Add Department</button>
<table className='table table-striped'>
<thead>
<tr>
<th>
DepartmentId
</th>
<th>
DepartmentName
</th>
<th>
Options
</th>
</tr>
</thead>
<tbody>
{departments.map(department =>
<tr key={department.DepartmentId}>
<td>{department.DepartmentId}</td>
<td>{department.DepartmentName}</td>
<td>
<button type="button" className='btn btn-light mr-1'
data-bs-toggle="modal"
data-bs-target="exampleModal"
onClick={() => this.editClick(department)}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-pencil" viewBox="0 0 16 16">
<path fillRule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" /></svg>
</button>
<button type="button" className='btn btn-light mr-1'>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-trash" viewBox="0 0 16 16">
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
</svg>
</button>
</td>
</tr>)}
</tbody>
</table>
<div className="modal fade" id="exampleModal" tabIndex="-1" aria-hidden="true" data-bs-backdrop="static">
<div className="modal-dialog modal-lg modal-dialog-centered" data-bs-backdrop="static">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">{modalTitle}</h5>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div className="modal-body">
<div className="input-group mb-3">
<span className="input-group-text">Department Name</span>
<input type="text" className="form-control" value={DepartmentName} onChange={this.changeDepartmentName}></input>
</div>
{DepartmentId == 0 ? <button type="button" className="btn btn-primary float-start">Create</button> : null}
{DepartmentId != 0 ? <button type="button" className="btn btn-primary float-start">Update</button> : null}
</div>
</div>
</div>
</div>
</Fragment>
)
}
}
Upvotes: 1
Reputation: 91
Try the new experimental "data-bs-config" attribute:
<div className="modal-dialog modal-dialog-centered" data-bs-config={backdrop:true}>
I think there is a "small" bug in Bootstrap-5.2 and an exception arises if it is not used/defined (I think it should be optional)
Regards
Upvotes: 1
Reputation: 947
Make sure all libraries are loaded before setup your modal. This is my solution :
document.addEventListener("DOMContentLoaded", function(event) {
//your modal setup
});
Upvotes: 2