Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

dcranmer's avatar

Modal opens first time, but not second time

I've got a modal component (using Vue 2.6.x) that opens and displays perfectly the first time I click the button to open it.

But if I close it (and the component gets destroyed), and then try to open it again, the component mounts and gets its props just as it should. But it is not visible. Looking at the html in DevTools, it says "null" where the modal content is supposed to be inserted just below the <body> element. The console shows no errors.

HTML (abbreviated) when modal opens the first time:

<body class="county-index auth" style="">

<div id="modal-container" class="modal-backdrop">
<dialog aria-modal="true" aria-describedby="modal-desc" tabindex="-1" class="dialog modal-dialog">
<div role="document">
<div class="widb-row widb-county-modal-header">
<h2 id="county-heading-modal">Waukesha County</h2>
<p id="modal-desc">Some key facts about Waukesha County connections to UW–Madison</p> <p>2184
                  Current Undergraduate Students
                </p> <p>1966
                  Medical Professionals with degrees from UW
                </p> <p>16325
                  Alumni
                </p></div> <p><a href="/counties/67">More Waukesha
              County connections to UW–Madison</a></p>
<button type="button">
                Return to Map
              </button>
              <button type="button" aria-label="Close">
              </button>
        </div>
    </dialog>
</div>
[...]

HTML when modal is closed and then opened a second time:

<body class="county-index auth" style="">
null
<header class="uw-header" aria-hidden="true" inert="true"><a class="uw-show-on-focus" href="#main" id="uw-skip-link">Skip to main content</a>
  <div class="uw-global-bar">
    <a class="uw-global-name-link" href="http://www.wisc.edu" aria-label="University of Wisconsin Madison home page">U<span>niversity <span class="uw-of">of</span> </span>W<span>isconsin</span>–Madison</a>
    <ul class="login-meta top-right links">
[...]

Some additional context: opening and closing the modal is done with v-if, and an additional 'v-show in the modem component based on a prop. Opening the modal does some DOM manipulation so that the modal becomes the first element after <body>, and everything else is assigned inert=true using the inert-polyfill. But this works perfectly the first time, and upon close, the DOM is returned to its original state. Everything appears to be the same, but something must be different.

I just can't figure out why the modal won't appear the second time, and why "null" is inserted into the html.

0 likes
6 replies
LaryAI's avatar
Level 58

It's difficult to provide a solution without seeing the code, but one possible issue could be that the modal component is not being properly destroyed and re-created when it is closed and opened again. This could be due to a variety of factors, such as incorrect usage of v-if or not properly resetting the component's state when it is closed.

One possible solution could be to use a key attribute on the modal component to force it to be destroyed and re-created each time it is opened. For example:

<modal :key="modalKey" v-if="showModal" ... />

Then, in the component's methods, you can update the modalKey value each time the modal is opened:

export default {
  data() {
    return {
      modalKey: 0,
      ...
    };
  },
  methods: {
    openModal() {
      this.showModal = true;
      this.modalKey += 1;
      ...
    },
    closeModal() {
      this.showModal = false;
      ...
    },
    ...
  },
  ...
};

This should ensure that the modal component is properly destroyed and re-created each time it is opened, which may resolve the issue of it not appearing the second time.

dcx's avatar
dcx
Best Answer
Level 1

As a hint, remember v-if won't add something to the dome if false but v-show will always add it and only show if truthy...it's hard to give more without the full code but i suspect you're using a v-if somewhere when a v-show might be more appropriate - i don't see any js actions when you close the modal either...on click of the close button you should be updating some state to dictate whether modal is open or closed maybe a ref..

dcranmer's avatar

@dcx I'm not sure why, but switching to v-show did the trick. I'm not sure why it wasn't working with v-if. There are methods run inside the modal component on both open and close to handle the dom manipulation I mentioned. Now that I am using v-show, this needs to be done a bit differently. Once the modal is inserted as the first element after <body>, that doesn't need to be repeated each time. But I still need to apply/remove aria-hidden=true and inert-true to the other elements each time the modal is opened and closed. Using v-show in this case seems much more efficient, too, because I expect users to be opening and closing the modal several times as they navigate through a map of state counties. It's silly to try and add/remove the modal to the DOM each time. Thanks for the push to rethink how I'm doing this!

1 like
dcx's avatar

@pweil No problem, glad it helped and it's now working :)

dcx's avatar

@pweil PS the reason is in my original comment... v-show is always in the dom but hidden - however v-if is not in the dom unless condition is truthy

dcranmer's avatar

@dcx Yes, I'm aware of this. The thing is, the condition was truthy, and "something" was being inserted into the DOM. Except that it wasn't the modal component's content; it was "null". If the condition were false, nothing at all would have happened. I'll probably figure it before long, probably in the middle of the night. So it's no biggie, and everything is working as intended now. Thanks again.

Please or to participate in this conversation.