1

I am using Aurelia with bootstrap to show the modal to ask for confirmation to clear form details. I have created plunker link for this. How can I hide the bootstrap modal without using JQuery that bootstrap provides to trigger an event to close the modal? I tried below to hide the modal, which works. But breaks the modal when you want to show it again.

document.getElementById("confirmationRequired").style.display = 'none';

When I try to click on clear btn, I get below error.

enter image description here

Ray
  • 1,095
  • 3
  • 18
  • 43
  • 2
    Aurelia also has a plugin for modals, [aurelia-dialog](http://aurelia.io/docs/plugins/dialog/). While it doesn't answer your question, it might provide you with an alternative that doesn't require bootstrap or jquery. – Jesse Apr 30 '18 at 13:16
  • I see. Thanks Jesse. I will give it a try. – Ray Apr 30 '18 at 13:17
  • Jesse, thank you for your suggestion. I was able to get `aurelia dialog` working in my project. :) – Ray May 01 '18 at 11:55

1 Answers1

4

I understand (and share) your preference to try and avoid JQuery where possible, but when you're working with a JQuery component that ship has kind of sailed already.. :-)

To answer your question (and demonstrate why it's hard to avoid JQuery when working with JQuery), here are 2 ways to hide it with "plain JS":

1. Copy the code from bootstrap's Modal.hide():

As you can see it does quite a few more things than just applying the hide style. Which is why that doesn't work.

if (event) {
  event.preventDefault()
}

if (this._isTransitioning || !this._isShown) {
  return
}

const hideEvent = $.Event(Event.HIDE)

$(this._element).trigger(hideEvent)

if (!this._isShown || hideEvent.isDefaultPrevented()) {
  return
}

this._isShown = false
const transition = $(this._element).hasClass(ClassName.FADE)

if (transition) {
  this._isTransitioning = true
}

this._setEscapeEvent()
this._setResizeEvent()

$(document).off(Event.FOCUSIN)

$(this._element).removeClass(ClassName.SHOW)

$(this._element).off(Event.CLICK_DISMISS)
$(this._dialog).off(Event.MOUSEDOWN_DISMISS)


if (transition) {
  const transitionDuration  = Util.getTransitionDurationFromElement(this._element)

  $(this._element)
    .one(Util.TRANSITION_END, (event) => this._hideModal(event))
    .emulateTransitionEnd(transitionDuration)
} else {
  this._hideModal()
}

I have tried similar things before and typically ended up tossing out an evening of work (figuring out and tying together all the dependencies) after concluding that I should just let the library handle it.

That's not to say it's a total waste of time. Doing this helps you better understand how these libraries work under the hood, and ultimately saves time in the long run because the API will have fewer surprises for you.

2. Manually invoke Modal.hide()

This involves finding the correct jQuery object on an element, getting the object instance you need and then invoking the appropriate method on it. A quick-n-dirty way to do this:

const el = document.getElementById("confirmationRequired");
const modal = Object.getOwnPropertyNames(el)
    .filter(n => n.startsWith("jQuery"))
    .map(n => e[n]["bs.modal"])
    .find(j => j !== undefined);

modal.hide();

Or..

I'd just use jQuery to do the same thing but with less code and more reliably.

As jesse already pointed out, aurelia-dialog is the way to go if you want to avoid JQuery. There is a learning curve involved but it's a very neat library once you get the hang of it.

One might argue: why not just hand-roll your own modal logic using only the CSS from bootstrap to style the dialog? A modal is nothing but two simple parts:

  • A fixed screen-filling element with a shade and positive z-index that makes the rest of the app unclickable while the modal is active. Simply show/hide it with CSS.

  • A plain form element, fixed and centered, with a higher z-index than the screen-filler. You could make this a custom element and to keep it really simple, let it communicate via the EventAggregator so you don't need to do any sorcery with tightly coupled bindings.

Add a few event handlers like esc and clicking outside the modal as alternatives to close it, and you're golden.

Fred Kleuver
  • 7,797
  • 2
  • 27
  • 38
  • 2
    Fred, as always, thank you so much for your great contribution to this community. :) I got the `dialog` working and like it how simple it is. You are right, the ship has already sailed. haha. But adding aurelia to existing bootstrap project is hard to get away for now. But for new projects, trying to avoid as much as jquery as possible. But sometime you can't control it because the third party component might heavily rely on jquery. – Ray May 01 '18 at 11:59
  • I copy-pasted your solution #2 and it bloody worked! Thanks so much! I have no idea how it worked but thanks a bunch! – Jamie Oct 29 '19 at 15:36