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

Time:03-29

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"
      
    >Show dialog</button>

    <button 
      @click="show_alert = !show_alert"
      
    >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  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%;" 
      
    >
      <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>

CodePudding user response:

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

  • Related