Maramal
Maramal

Reputation: 3466

Create Bootstrap Modal from JavaScript

I am trying to include a JS CDN script to show a message on specific actions. To achieve that I am trying to make it work firstly on any browser.

This is what I am trying to do:

document.querySelector('.circle').addEventListener('click', function() {
  var m1 = $(makeModal('Somehting here')); // I would want to skip creating an HTML element with jQuery.
  document.body.insertAdjacentHTML('beforeend', m1);
  m1.modal('show');
}, false);

function makeModal(text) {
  return `<div id="myModal" class="modal fade" role="dialog" style="display: none">
  <div class="modal-dialog">

    <!-- Modal content-->
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">&times;</button>
        <h4 class="modal-title">Modal Header</h4>
      </div>
      <div class="modal-body">
        <p>${text}</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
      </div>
    </div>

  </div>
</div>`;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>An app</title>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
  <button class="circle">Click here</button>
<script src="https://code.jquery.com/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
  
</body>
</html>

This works, but the phrase [object Object] is appended to the button. Another thing, I guess everytime someone clicks on the button the node is created again and again.

Should I delete it after the modal appears? Well, how would you ahieve this stuff?

Upvotes: 1

Views: 9061

Answers (3)

Poul
Poul

Reputation: 31

You could do this way on JS:

function Modal(title, text, noBtnName='Close', yesBtnName='', yesBtnAction=()=>{}) {
    var wrap = _buildModal(title, text, noBtnName, yesBtnName, yesBtnAction)
    document.body.append(wrap)
    this.bsModal = bootstrap.Modal.getOrCreateInstance(wrap);
    this.show = function() {
        this.bsModal.show();
    }
}

function _buildModal(title, text, noBtnName, yesBtnName, yesBtnFunc) {
    var modal = document.createElement('div')
    modal.setAttribute('class', 'modal fade')
    modal.setAttribute('tabindex', '-1')
    modal.setAttribute('aria-labelledby', 'modalLabel')
    modal.setAttribute('aria-hidden', 'true')
    var modDialog = document.createElement('div')
    modDialog.setAttribute('class', 'modal-dialog')
    var modContent = document.createElement('div')
    modContent.setAttribute('class', 'modal-content')
    var header = _buildModalHeader(title)
    modContent.append(header)
    var body = document.createElement('div')
    body.setAttribute('class', 'modal-body')
    body.innerText = text
    modContent.append(body)
    var footer = _buildModalFooter(noBtnName, yesBtnName, yesBtnFunc)
    modContent.append(footer)
    modDialog.append(modContent)
    modal.append(modDialog)
    return modal
}

function _buildModalHeader(text) {
    var header = document.createElement('div');
    header.setAttribute('class', 'modal-header');
    header.setAttribute('style', 'border-bottom: none;');

    var title = document.createElement('h5');
    title.setAttribute('class', 'modal-title');
    title.setAttribute('id', 'modalLabel');
    title.innerText = text

    var closeBtn = document.createElement('button');
    closeBtn.setAttribute('class', 'btn-close');
    closeBtn.setAttribute('data-bs-dismiss', 'modal');
    closeBtn.setAttribute('aria-label', 'Close');

    header.append(title)
    header.append(closeBtn)
    return header
}

function _buildModalFooter(noBtnName, yesBtnName, yesBtnFunc) {
    var footer = document.createElement('div')
    footer.setAttribute('class', 'modal-footer')
    footer.setAttribute('style', 'border-top: none;')

    var noBtn = document.createElement('button')
    noBtn.setAttribute('type', 'button')
    noBtn.setAttribute('class', 'btn btn-secondary')
    noBtn.setAttribute('data-bs-dismiss', 'modal')
    noBtn.innerText = noBtnName
    footer.append(noBtn)

    if (yesBtnName && yesBtnFunc){
        var yesBtn = document.createElement('button')
        yesBtn.setAttribute('type', 'button')
        yesBtn.setAttribute('class', 'btn btn-primary')
        yesBtn.innerText = yesBtnName
        yesBtn.addEventListener('click', yesBtnFunc)
        footer.append(yesBtn)
    }
    return footer
}

Then example modal call would be:

(new Modal(
    'Warning',            // title
    'Ducks are crossing the road', // text
    'Close',              // noBtnName
    'Confirm',            // yesBtnName
    ()=>{alert('yeah')},  // yesBtnFunction
    )).show()

Works on Bootstrap 5, no jQuery required.

Upvotes: 1

Adeel
Adeel

Reputation: 2959

You just need to remove document.body.insertAdjacentHTML('beforeend', m1); to fix this issue because insertAdjacentHTML() is used to insert the node into the DOM tree and from your code what I can see is that you're trying to insert a node before end.

Please read Element.insertAdjacentHTML()

Answer to your second question, the close <button> has an attribute data-dismiss="modal" which is used to close the modal, so in simple words every time user click the close button will dismiss the modal completely.

Upvotes: 1

Enzo B.
Enzo B.

Reputation: 2371

this code cause the [object Object] :

document.body.insertAdjacentHTML('beforeend', m1);

And when i tried without this code, all works perfectly, why did you use it ?

If he is not usefull, you can just delete him.

Upvotes: 1

Related Questions