javascripthtmljquerytwitter-bootstrapbootstrap-modal

Bootstrap Modal error: "Uncaught TypeError: Illegal invocation"


I'm trying to dinamically render the content of this Bootstrap modal, but I keep getting this error of invocation. I'm starting to suspect that Bootstrap can't render a modalBody that has template literals (${}) in it's modal-body - if that's the case, I'm open to suggestions on how to circunvent this. Below, I have tried to isolate the problem as best as possible:

<!DOCTYPE html>

<head>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
    <script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
</head>

<body>
    <button class="btn btn-primary" type="button" data-bs-toggle="modal" data-bs-target="#manageUser" data-bs-action="POST">Manage User</button>

    <div class="modal fade" id="manageUser" tabindex="-1" aria-labelledby="manageUserLabel" aria-hidden="true"></div>
</body>

<script src="./index.js"></script>

</html>
const manageUserModal = $('#manageUser');
manageUserModal.on('show.bs.modal', event => {
    const triggerType = $(event.relatedTarget).data('bs-action');
    $('#manage-user input').val('');
    let userData = {
        id: 0,
        value: 0,
        coverage: 0
    };
    manageUserModal.html(`
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h1 class="modal-title" id="manageUserLabel">${triggerType === 'POST' ? 'Register New User' : 'Edit User Data'}</h1>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <form>
                    <div class="modal-body">
                        <input type="hidden" id="manage-method" value="${triggerType}">
                        <input type="hidden" id="manage-id" ${triggerType === 'UPDATE' ? `name="id" value="${userData?.id}"` : ''}>
                                <div class="form-floating mb-3">
                                    <input type="text" class="${triggerType === 'POST' ? 'form-control' : 'form-control-plaintext'}"currency" id="manage-value" name="value" required ${triggerType === 'UPDATE' ? `value="${userData?.value}" readonly` : ''}>
                                    <label for="manage-value">Value (*)</label>
                                </div>

                                <div class="form-floating mb-3">
                                    <input type="text" class="${triggerType === 'POST' ? 'form-control' : 'form-control-plaintext'}" id="manage-coverage" name="coverage" required ${triggerType === 'UPDATE' ? `value="${userData?.coverage}" readonly` : ''}>
                                    <label for="manage-coverage">Coverage (*)</label>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="dismissModalAndCancelEdit">Fechar</button>
                        <button type="${triggerType === 'POST' ? 'submit' : 'button'}" class="btn btn-primary" id="toggleModeAndSubmitUser">${triggerType === 'POST' ? 'Register' : 'Edit'}</button>
                    </div>
                </form>
            </div>
        </div>
    `);
});

For anyone familiarized with Bootstrap's source code, here are more details of the error:

findOne(selector, element = document.documentElement) {
    return Element.prototype.querySelector.call(element, selector)
  },
    const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)
    if (modalBody) {
      modalBody.scrollTop = 0
    }
    this._backdrop.show(() => this._showElement(relatedTarget))
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
  return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue
}
    this._emulateAnimation(() => {
      execute(callback)
    })

Solution

  • I'm starting to suspect that Bootstrap can't render a modalBody that has template literals (${}) in it's modal-body"_

    No, that's not it. The problem is that your modal is completely empty, the moment it gets invoked. You need at least <div class="modal-content"></div> in there to begin with.