Dismiss Modal

This public forum is for user-to-user discussions of PHPMaker. Note that this is not support forum.
Post Reply
sangnandar
User
Posts: 1031

Dismiss Modal

Post by sangnandar »

Scenario:
View Page as modal.

Standard behavior:
When user clicks outside modal, the modal will NOT dismissed.

How to change this behavior (i.e. when user clicks outside modal, the modal will dismissed) ?

My goal is to use View Page to display additional fields relating to the record, without add/edit/delete links in the modal. So the modal is functioned like a pop-up. Ideally, user want this kind of pop-up to be easily dismissed.
I know this can be achieved by using regular bootstrap modal, but I prefer to use View Page modal to have easy access to server events and jsrender.

If I'm not mistaken bootstrap modal has arguments for this in the call. The default is to dismiss modal when click event occurs anywhere outside the modal. I think PHPMaker's script make non-default call to modal. What is the script and how to make it call the default only for View Page modal? I surely need the standard-behavior for add/edit page to prevent accidental dismissed.

Thank you.


arbei
User
Posts: 9786

Post by arbei »

You can use your own modal dialog HTML markup by adding it to Page_Foot server event. (I believe PHPMaker purposely to use to avoid some mouse interaction issues with other widgets such as date/time picker.)


sangnandar
User
Posts: 1031

Post by sangnandar »

Yes, rendering my own modal dialog would be the last resort. This approach needs 2 separate codes; 1 using my own modal (for PC) and 1 using view-page (for mobile). Is it possible to fire view-page to my own modal?

I was thinking of a simpler approach like below, if possible:

// list-page startup script
if (<view-page link is clicked>) {
  $(document).on('shown.bs.modal', function(e) {
    // detach event handler that caused modal dismissal when user clicks outside modal
  });
  $(document).on('hidden.bs.modal', function(e) {
    // re-attach event handler
});
}

sangnandar
User
Posts: 1031

Post by sangnandar »

If I understand correctly, the handler for this event (I assume it's click event) is:

// DevTools event listener breakpoint
function bootstrapDelegationHandler(element, selector, fn) {
  return function handler(event) {
    const domElements = element.querySelectorAll(selector)

    for (let { target } = event; target && target !== this; target = target.parentNode) {
      for (const domElement of domElements) {
        if (domElement !== target) {
          continue
        }

        hydrateObj(event, { delegateTarget: target })

        if (handler.oneOff) {
          EventHandler.off(element, event.type, selector, fn)
        }

        return fn.apply(target, [event])
      }
    }
  }
}

I tried:

// list-page startup script
$(document).on('shown.bs.modal', function(e){
  // $(this).removeEventListener("click", bootstrapDelegationHandler); // not working
  // or
  // $(this).removeEventListener("click", handler); // not working
});

arbei
User
Posts: 9786

Post by arbei »

You may also simply use jQuery in Startup Script to change the data-bs-dismiss attribute.


sangnandar
User
Posts: 1031

Post by sangnandar »

Tried this but it has problem. The modal dismissed when click inside modal (not expected behavior)

// list-page startup script
$('#ew-modal-dialog')
  .attr({
    'data-bs-dismiss': 'modal',
    'data-bs-target': 'this'
  })
;

But it gave me idea to just trigger click on $('#btn-cancel'), excluding $('.modal-content').
I ended up using this:

$(document).on('shown.bs.modal', function(e){
  $(document).on('click', function handler(e){
    let el = $('.modal-content');
    if ($(e.target).closest(el).length > 0) { // clicked inside el
      $(document).off('click', handler); // detach
      return;
    } else { // clicked outside el
      $('#btn-cancel').click(); // trigger click
      $(document).off('click', handler); // detach
    }
  });
});

It's great now. Thanks.


Post Reply