'nextjs and bootstrap5 modal
Hello I would like to use bootstrap 5 without react-bootstrap and reactstrap when I create my modal I end up with this error:
TypeError: undefined is not an object (evaluating 'this._element.classList')
Do you have any idea because all the examples I am viewing are still with reactstrap or react-bootstrap, do you have any idea how to do this, thanks for your help.
import Document, { Html, Head, Main, NextScript } from "next/document";
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
<div id="modal-root"></div>
</body>
</Html>
);
}
}
export default MyDocument;
My modal
import { useState, useEffect } from "react";
import ReactDom from "react-dom";
const Modal = ({ show, onClose, children, title, targetModal }) => {
const [isBrowser, setIsBrowser] = useState(false);
useEffect(() => setIsBrowser(true));
const handleCloseModal = (e) => {
e.preventDefault();
let myModalEl = document.getElementById(targetModal);
console.log(myModalEl);
onClose();
};
const modalContent = show ? (
<div
className="modal fade py-3"
tabIndex="-1"
role="dialog"
id={targetModal}
>
<div className="modal-dialog" role="document">
<div className="modal-content border-0 rounded-6 shadow-blue-sm">
<div className="modal-header p-4 pb-4 border-bottom-0">
<h4 className="fw-bold mb-0 hstack text-secondary">
{title && (
<span>
<i className="ri-user-search-line me-2"></i> {title}
</span>
)}
</h4>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
onClick={handleCloseModal}
aria-label="Close"
></button>
</div>
<div className="modal-body p-4 pt-0">{children}</div>
</div>
</div>
</div>
) : null;
if (isBrowser) {
return ReactDom.createPortal(
modalContent,
document.getElementById("modal-root")
);
} else {
return null;
}
};
export default Modal;
My Page
import { useState } from "react";
import Layouts from "@/components/Layouts";
import Modal from "@/components/Modal";
const EditEventsPage = () => {
const [showModal, setShowModal] = useState(false);
return (
<Layouts title="Edit event.">
<button
type="submit"
className="btn btn-secondary mt-4 hstack"
data-bs-toggle="modal"
data-bs-target="#uploadImage"
onClick={() => setShowModal(true)}
>
<i className="ri-image-line "></i> Ajouter image{" "}
</button>
<Modal
show={showModal}
onClose={() => setShowModal(false)}
targetModal="uploadImage"
></Modal>
</Layouts>
);
};
export default EditEventsPage;
Thansk for your helps.
Solution 1:[1]
I have not been able to achieve this using your method.
However, this works for me, and you could expand on the example.
in your _app.js file add this line of code, you should wrap it in the useEffect function as so
useEffect(() => {
typeof document !== undefined
? require("bootstrap/dist/js/bootstrap")
: null;
},[]);
This will make bootstrap available across your project. So where ever you want to trigger your modal.
just do this instead
<button type="button" data-bs-toggle="modal" data-bs-target="#myModal">Launch modal</button>
Your Bootstrap modal
<div
className="modal modal-alert bg-secondary py-5"
tabIndex="-1"
role="dialog"
id="myModal"
>
<div className="modal-dialog modal-dialog-centered" role="document">
<div className="modal-content rounded-4 shadow">
<div className="modal-body p-4 text-center">
<h5 className="mb-0">Enable this setting?</h5>
<p className="mb-0">
You can always change your mind in your account settings.
</p>
</div>
<div className="modal-footer flex-nowrap p-0">
<button
type="button"
className="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0 border-right"
>
<strong>Yes, enable</strong>
</button>
<button
type="button"
className="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0"
data-bs-dismiss="modal"
>
No thanks
</button>
</div>
</div>
</div>
</div>
Hope this helps.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Freesoul |