Escape key press not working with second modal window in vuejs

Viewed 713

I have a table with multiple rows, each row has a button, on clicking the button, a modal window opens contains form element.

After submitting the form, second window opens for confirmation and first window closes.

Below code is my sample work flow.

My problem is

On Escape key press, works when the first window was opened but not able to close the second window when it was opened.

<template>
    <div>
        <table>
            <tr>
                <td>
                    <button @click="openFormWindow">Open form</button>
                </td>
            </tr>
        </table>
        <modal v-on-escape="hideFirstModal" v-if="isFirstWindowOpen">
            <div>
                <form @submit="submitFormOne">
                    <input type="text">
                    <button type="submit"></button>
                </form>
            </div>
        </modal>
        <modal v-on-escape="hideSecondModal" v-if="isSecondWindowOpen">
            <p>confirmation window</p>
        </modal>
    </div>
</template>

<script>
export default {
    data () {
        return {
            isFirstWindowOpen: false,
            isSecondWindowOpen: false
        }
    }
    methods: {
        openFormWindow () {
            // form window opens 
            this.isFirstWindowOpen = true
        },
        hideFirstModal () {
            this.isFirstWindowOpen = false
        },
        hideSecondModal () {
            this.isSecondWindowOpen = false
        },
        submitFormOne () {
            // submit the details, let the first window close & open the second window.
            this.isFirstWindowOpen = false
            this.isSecondWindowOpen = true
        }
    }
}
</script>

vue directive on-escape

Vue.directive('on-escape', {
    bind (el, binding, vnode) {
        el.customEventKeydown = function (event) {
            // Check if click was outside the el and his childrens
            if (event.keyCode === 27) {
                vnode.context[binding.expression](event)
            }
        }
        document.body.addEventListener("keydown", el.customEventKeydown)
    },
    unbind (el) {
        document.body.removeEventListener("keydown", el.customEventKeydown)
    }
})
2 Answers

Use a key on each <modal> component to tell Vue not to reuse DOM nodes:

<modal v-on-escape="hideFirstModal" v-if="isFirstWindowOpen" key="modal1">
<modal v-on-escape="hideSecondModal" v-if="isSecondWindowOpen" key="modal2">

Vue was reusing the DOM for the first modal when it created the 2nd, so the second keydown event listener was never created.

When elements are added and removed from the DOM, Vue sometimes tries to help by reusing old DOM nodes to speed up rendering. Sometimes this can have unwanted side effects. The key essentially instructs it not to do this.

It looks like you are missing this.isSecondWindowOpen, it isn't being returned in your data function.

Related