Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuetify How to open and close dialogs within a data table

We've build an application for a staffing company where Admin can view Users in a Vuetify data table. In that table, we want to show User Notes, but they are sometimes long and don't fit well into a table cell. We would like to simply click a button and open the Notes in a dialog.

The problem is that if we have 200 users, and we click the button to open "dialogNotes", every user dialog opens. How can we adjust our code so that only the dialog for that user opens?

<template slot="items" slot-scope="props">
                <td>
                <v-checkbox
                  primary
                  hide-details
                  v-model="props.selected"
                ></v-checkbox>
              </td>
                <td>{{props.item.status}}</td>
                <td>
          <img v-if="props.item.photoUrl" :src="props.item.photoUrl" class="user-img">
          <img v-if="!props.item.photoUrl" src="/static/avatar.png" class="user-img">
        </td>
                <td>
                <router-link v-if="props.item.name" v-bind:to="'/staff/' + props.item.id">{{ props.item.name }}</router-link>
        <router-link v-if="!props.item.name" v-bind:to="'/staff/' + props.item.id">{{ props.item.id }}</router-link>
                </td>
                <td>
                <v-btn icon color="primary" small @click.stop="dialogNote = true"><v-icon small>open_in_new</v-icon></v-btn>
                    <v-dialog v-model="dialogNote" scrollable lazy max-width="500" :key="props.item.id">
                    <v-card>
                      <v-card-title>
                        <span>{{ props.item.name }} Note</span>
                      </v-card-title>
                      <v-card-text>
                        {{props.item.note}}
                      </v-card-text>
                      <v-card-actions>
                        <v-btn color="primary" flat @click.stop="dialogNote=false">Close</v-btn>
                      </v-card-actions>
                    </v-card>
                  </v-dialog>
                </td>
                <td>{{props.item.greek}}</td>
                <td>
                <span v-if="props.item.tipsUrl">Yes</span>
              </td>
                <td>{{props.item.waiver}}</td>
                <td>{{props.item.media}}</td>
              <td>{{ props.item.howHear }}</td>
            </template>

data:

dialogNote: false,
like image 377
Greg Fielding Avatar asked Mar 30 '18 19:03

Greg Fielding


People also ask

How to close dialog when Esc key is pressed with vuetify?

To close dialog when ESC key is pressed with Vuetify and Vue.js, we can add a keydown event listener to the dialog. ← → How to access props in mounted function with Vue.js?

What is V-dialog component?

Just a simple example of a form in a dialog. The v-dialog component makes it easy to create a customized loading experience for your application. Dialogs can be nested: you can open one dialog from another.

How to tell if a dialog is open or not?

Turn dialogNote into an object and use the dialogNote [props.item.id] to tell if that item is open or not. And change the open/close buttons. Show activity on this post. In my opinion it is a better and cleaner way to use vuetify for data-table and dialog.

How to stop event propagation when dialog is open?

If dialog is active and not using the persistent prop, the esc key will deactivate it. When used, will activate the component when clicked (or hover for specific components). This manually stops the event propagation. Without this slot, if you open the component through its model, you will need to manually stop the event propagation


1 Answers

Turn dialogNote into an object and use the dialogNote[props.item.id] to tell if that item is open or not.

Declare it, in data, like:

dialogNote: {},

And use it like:

 <v-dialog v-model="dialogNote[props.item.id]" scrollable lazy max-width="500" :key="props.item.id">

And change the open/close buttons.

  • Open:

    • From

      @click.stop="dialogNote = true"
      
    • To:

      @click.stop="$set(dialogNote, props.item.id, true)"
      
  • Close:

    • From

      @click.stop="dialogNote = false"
      
    • To:

      @click.stop="$set(dialogNote, props.item.id, false)"
      

Your template:

<template slot="items" slot-scope="props">
<td>
  <v-checkbox primary hide-details v-model="props.selected"></v-checkbox>
</td>
<td>{{props.item.status}}</td>
<td>
  <img v-if="props.item.photoUrl" :src="props.item.photoUrl" class="user-img">
  <img v-if="!props.item.photoUrl" src="/static/avatar.png" class="user-img">
</td>
<td>
  <router-link v-if="props.item.name" v-bind:to="'/staff/' + props.item.id">{{ props.item.name }}</router-link>
  <router-link v-if="!props.item.name" v-bind:to="'/staff/' + props.item.id">{{ props.item.id }}</router-link>
</td>
<td>
  <v-btn icon color="primary" small @click.stop="$set(dialogNote, props.item.id, true)">
    <v-icon small>open_in_new</v-icon>
  </v-btn>
  <v-dialog v-model="dialogNote[props.item.id]" scrollable lazy max-width="500" :key="props.item.id">
    <v-card>
      <v-card-title>
        <span>{{ props.item.name }} Note</span>
      </v-card-title>
      <v-card-text>
        {{props.item.note}}
      </v-card-text>
      <v-card-actions>
        <v-btn color="primary" flat @click.stop="$set(dialogNote, props.item.id, false)">Close</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</td>
<td>{{props.item.greek}}</td>
<td>
  <span v-if="props.item.tipsUrl">Yes</span>
</td>
<td>{{props.item.waiver}}</td>
<td>{{props.item.media}}</td>
<td>{{ props.item.howHear }}</td>
</template>
like image 96
acdcjunior Avatar answered Sep 21 '22 10:09

acdcjunior