Greg Fielding
Greg Fielding

Reputation: 557

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,

Upvotes: 9

Views: 21583

Answers (2)

Roland
Roland

Reputation: 27819

In my opinion it is a better and cleaner way to use vuetify for data-table and dialog.

Also in the examples below the dialog will open for each user when you want to edit them.

Vuetify offers Data Table CRUD Actions and you can edit,delete and add new item.For more look here

Upvotes: 0

acdcjunior
acdcjunior

Reputation: 135862

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>

Upvotes: 9

Related Questions