Search code examples
javascripthtmltwitter-bootstrapbulma

Close child modal while keeping parent open only on close button click


So I'm running into some issues and I can't figure out how to close a child modal and keep the parent modal open, so I wanted to ask the community to see if I can get some assistance.

So here is what I'm attempting to do:

  • I open click on the 'Launch parent modal', I want the parent modal to show (This works great).
  • When I launch the child modal from inside the parent, I see the child modal (This works great).
  • I want to be able to click on the close button inside the child modal and go back to the parent modal since it's still is-active, otherwise if they click anywhere in the shaded are it will close all the modals as it currently is doing.

So to sum it up, I just want the child modal to close so that I can see the parent modal only if the click on the close button.

document.addEventListener('DOMContentLoaded', function() {
  const rootEl = document.documentElement;
  const $modals = document.querySelectorAll('.modal');
  const $modalButtons = document.querySelectorAll('.modal-button');
  const $modalCloses = document.querySelectorAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button');

  if ($modalButtons.length > 0) {
    $modalButtons.forEach(function ($el) {
      $el.addEventListener('click', function () {
        var target = $el.dataset.target;
        openModal(target);
      });
    });
  }

  if ($modalCloses.length > 0) {
    $modalCloses.forEach(function ($el) {
      $el.addEventListener('click', function () {
        closeModals();
      });
    });
  }

  function openModal(target) {
    var $target = document.getElementById(target);
    rootEl.classList.add('is-clipped');
    $target.classList.add('is-active');
  }

  function closeModals() {
    rootEl.classList.remove('is-clipped');
    $modals.forEach(function ($el) {
      $el.classList.remove('is-active');
    });
  }

  document.addEventListener('keydown', function (event) {
    var e = event || window.event;

    if (e.keyCode === 27) {
      closeModals();
      closeDropdowns();
    }
  })
});
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css" rel="stylesheet"/>
<button class="button is-primary is-large modal-button" data-target="modal-ter" aria-haspopup="true">Launch parent modal</button>

<div id="modal-ter" class="modal">
  <div class="modal-background"></div>
  <div class="modal-card">
    <header class="modal-card-head">
      <p class="modal-card-title">Modal title</p>
      <button class="delete" aria-label="close"></button>
    </header>
    <section class="modal-card-body">
    
    <p>
      This is the parent modal (Scroll down and click the child modal button).
    </p>
      
      <button class="button is-primary is-large modal-button" data-target="modal-ter2" aria-haspopup="true">Launch child modal</button>
      
    </section>
    <footer class="modal-card-foot">
      <button class="button is-success">Save changes</button>
      <button class="button">Cancel</button>
    </footer>
  </div>
</div>

<div id="modal-ter2" class="modal">
  <div class="modal-background"></div>
  <div class="modal-card">
    <header class="modal-card-head">
      <p class="modal-card-title">Modal title</p>
      <button class="delete" aria-label="close"></button>
    </header>
    <section class="modal-card-body">
      
      <p>
        This is the child modal
      </p>
      
    </section>
    <footer class="modal-card-foot">
      <button class="button is-success">Save changes</button>
      <button class="button">Cancel</button>
    </footer>
  </div>
</div>


Solution

  • I think you should bind different events for success and cancel butttons, cause they have different logics.

    document.addEventListener('DOMContentLoaded', function() {
      const rootEl = document.documentElement;
      const $modals = document.querySelectorAll('.modal');
      const $modalButtons = document.querySelectorAll('.modal-button');
      const $modalCloses = document.querySelectorAll('.modal-background, .modal-close, .modal-card-head .delete');
    
      if ($modalButtons.length > 0) {
        $modalButtons.forEach(function ($el) {
          $el.addEventListener('click', function () {
            var target = $el.dataset.target;
            openModal(target);
          });
        });
      }
    
      if ($modalCloses.length > 0) {
        $modalCloses.forEach(function ($el) {
          $el.addEventListener('click', function () {
            closeModals();
          });
        });
      }
    
      function openModal(target) {
        var $target = document.getElementById(target);
        rootEl.classList.add('is-clipped');
        $target.classList.add('is-active');
      }
    
      function closeModals() {
        rootEl.classList.remove('is-clipped');
        $modals.forEach(function ($el) {
          $el.classList.remove('is-active');
        });
      }
      
      $modals.forEach(function ($el) {
        $el.addEventListener('click', function(event) {
        if (event.target.classList.contains('cancel')) {
            $el.classList.remove('is-active');
          }
        })
      });
    
      document.addEventListener('keydown', function (event) {
        var e = event || window.event;
    
        if (e.keyCode === 27) {
          closeModals();
          closeDropdowns();
        }
      })
    });
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css" rel="stylesheet"/>
    <button class="button is-primary is-large modal-button" data-target="modal-ter" aria-haspopup="true">Launch parent modal</button>
    
    <div id="modal-ter" class="modal">
      <div class="modal-background"></div>
      <div class="modal-card">
        <header class="modal-card-head">
          <p class="modal-card-title">Modal title</p>
          <button class="delete" aria-label="close"></button>
        </header>
        <section class="modal-card-body">
        
        <p>
          This is the parent modal (Scroll down and click the child modal button).
        </p>
          
          <button class="button is-primary is-large modal-button" data-target="modal-ter2" aria-haspopup="true">Launch child modal</button>
          
        </section>
        <footer class="modal-card-foot">
          <button class="button is-success">Save changes</button>
          <button class="button cancel">Cancel</button>
        </footer>
      </div>
    </div>
    
    <div id="modal-ter2" class="modal">
      <div class="modal-background"></div>
      <div class="modal-card">
        <header class="modal-card-head">
          <p class="modal-card-title">Modal title</p>
          <button class="delete" aria-label="close"></button>
        </header>
        <section class="modal-card-body">
          
          <p>
            This is the child modal
          </p>
          
        </section>
        <footer class="modal-card-foot">
          <button class="button is-success">Save changes</button>
          <button class="button cancel">Cancel</button>
        </footer>
      </div>
    </div>