Pedro Madureira
Pedro Madureira

Reputation: 131

Button click event inside v-alert component is causing to focus in the input field inside v-dialog

When I click a button inside the v-alert, it causes it to focus on the first input field inside the v-dialog.

I have searched about events propagation and I have tried to use all sorts of event modifiers such as .stop, .prevent, and .self, but nothing has worked.

I made this video to show an example.

The component file is this:

<template>
  <v-app>
    <button 
      @click="show_dialog = !show_dialog"
      class="button"
    >Show dialog</button>

    <button 
      @click="show_alert = !show_alert"
      class="button2"
    >Show alert</button>

    <v-dialog v-model='show_dialog' max-width="500px">
      <v-card>
        <v-card-title>Login</v-card-title>
        <v-card-text>
            <v-container fluid>
              <v-text-field
                label="first field"
                @focus="textFieldEvent($event)"
                @click="textFieldEvent($event)"
              ></v-text-field>
              <v-text-field
                label="second field"
                required
              ></v-text-field>
            </v-container>
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <button class="blue--text darken-1" text @click="show_dialog = !show_dialog">Cancel</button>
          <button type="submit">Login</button>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <v-alert
      :value="show_alert"
      type='info' 
      style="width: 50%;" 
      class="alert_message"
    >
      <button 
        @click="alertEvent"
        style="background-color: blue;"
      >Button</button>
    </v-alert>
  </v-app>
</template>

<script>
export default {
    name: "default",
  data(){
    return {
      show_dialog: true,
      show_alert: true,
    }
  },
  methods: {
    alertEvent(event){
      console.log(">>>>>>> Alert Event", event)
      event.preventDefault()
      event.stopPropagation()
      event.stopImmediatePropagation()
    },
    textFieldEvent(event) {
      console.log(">>>>>>> text Field Event:", event)
    },
  },
};
</script>

<style scoped>
.alert_message{
    position: fixed;
    left: 50%;
    top: 93%;
    transform: translate(-50%, -50%);
    z-index: 999;
}
.button {
  background-color: #4CAF50; /* Green */
  border: none;
  color: white;
  padding: 15px 32px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
}
.button2 {
  background-color: red;
  border: none;
  color: white;
  padding: 15px 32px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
}
</style>

Upvotes: 0

Views: 1073

Answers (1)

Kapcash
Kapcash

Reputation: 6909

That's because by default, v-dialog retains the focus when opened.
So whenever you try to focus a element that is not inside the dialog, it will catch this focus and autofocus the first focusable element in the dialog.

This is important for accessibility. Users using only keyboards only want to navigate within the dialog when it's opened, not in the whole application.

Solution:

If you really need this v-alert to be opened at the same time, the solution is just to add the :retain-focus="false" prop on the dialog.

<v-dialog :retain-focus="false"></v-dialog>

See working example on CodePen

Upvotes: 2

Related Questions