Alan Dsilva
Alan Dsilva

Reputation: 341

Uncaught TypeError: Cannot read properties of undefined (reading 'backdrop') while using bootstrap 5 modal in react

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;

This is the errorerror

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

Answers (9)

Link477
Link477

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

alireza alizade
alireza alizade

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

zukio
zukio

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

La&#239;ta
La&#239;ta

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

Abdu4
Abdu4

Reputation: 1558

since you are showing/hiding modals via a click handler try to remove data-bs-toggle="modal".

Upvotes: 8

Ghias Ali
Ghias Ali

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

Stephen Smith
Stephen Smith

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

floss.dev
floss.dev

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

wahmal
wahmal

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

Related Questions