2

I am trying to add a popup-modal to a table in vuetify vue.js but it always ends up getting the value of the first item.

The problem arises on the 4th <td> where I am trying to implement a pop-up modal.

It keeps getting the first element of the list only. I feel like it is a very easy fix.. it is the 4th <td> just to save you time.

Vue Template:

<script>
        var model =  @Html.Raw(Json.Encode(Model))
</script>



<div id="app">
    <v-app id="inspire">
        <v-card>
            <v-card-title>
                <v-card-actions>
                    <v-spacer></v-spacer>
                    <v-btn flat color="purple" href="/Home">Home</v-btn>
                    <v-btn flat color="purple">Inventory</v-btn>
                </v-card-actions>

                <v-spacer></v-spacer>

            </v-card-title>

        </v-card>


        <v-container grid-list-md text-xs-center>
            <v-layout>
                <v-flex xs8>

                    <v-card>

                        <v-card-title>
                            Un Added Lab Equipment
                            <v-spacer></v-spacer>
                            <v-text-field v-model="search"
                                          append-icon="search"
                                          label="Search"
                                          single-line
                                          hide-details></v-text-field>
                        </v-card-title>
                        <v-data-table :headers="Headers"
                                      :items="items"
                                      :search="search"
                                      item-key="equipment"
                                      hide-actions
                                      expand
                                      class="elevation-1">
                            <template slot="items" scope="props">
                                <td class="text-xs">{{ props.item.equipment }}</td>
                                <td class="text-xs">{{ props.item.location }}</td>
                                <td class="text-xs">{{ props.item.qty }}  </td>
                                <td>
                                    @*<a v-bind:href="props.item.pictureUrl">
                                        <i class="fa fa-info-circle fa-2x" style="color: rgb(159, 212, 172);"></i></a>*@
                                    <v-dialog v-model="dialog" lazy absolute>
                                        <i class="fa fa-info-circle fa-2x" style="color: rgb(159, 212, 172);" slot="activator"></i>
                                        <v-card>
                                            <v-card-title class="justify-center">
                                                <p class="headline">More Info  for '{{ props.item.equipment }}'</p>
                                            </v-card-title>
                                            <v-card-text>
                                                @*<v-img src="{{props.item.pictureUrl}}"
                                                    aspect-ratio="2.75"></v-img>*@ {{props.item.location}}
                                            </v-card-text>
                                            <v-card-actions>
                                                <v-spacer></v-spacer>
                                                <v-btn class="blue--text darken-1" flat="flat" v-on:click.native="dialog = false">No</v-btn>
                                                <v-btn class="blue--text darken-1" flat="flat" v-on:click.native="deleteRow(props.item)">Yes</v-btn>
                                            </v-card-actions>
                                        </v-card>
                                    </v-dialog>

                                </td>
                                <td class="text-xs">
                                    <button v-on:click="decrement(props.item.id)" :disabled="disabled == props.item.id ? true : false">
                                        <v-icon color="pink">remove</v-icon>
                                    </button>
                                    <button v-on:click="increment(props.item.id)" id="incrementButton" :disabled="disabled == props.item.id + '2' ? true : false">
                                        <v-icon color="green">add</v-icon>
                                    </button>
                                </td>


                            </template>
                        </v-data-table>
                    </v-card>
                </v-flex>

            </v-layout>
            <br />




        </v-container>


</div>

***Vue App:***
new Vue({
el: '#app',
data() {
    return {
        disabled: "",
        searchAdded: '',
        message: 'omae wa moo shindeiruu',
        dialog: false,
        notifications: false,
        sound: true,
        test: true,
        widgets: false,
        search: '',
        Headers: [
            { text: 'Equipment', value: 'equipment' },
            { text: 'Location', value: 'location' },
            { text: 'Qty', value: 'qty' },
            { text: 'MoreInfo', value: 'pictureUrl',  sortable: false, disabled: true },
            { text: 'Add or Remove', value: 'addo', sortable: false, disabled: true }
        ],
        HeadersAdded: [
            { text: 'Equipment', value: 'itemName' },
            { text: 'Location', value: 'location' },
            { text: 'Qty', value: 'quantity' },
            { text: 'Add or Remove', value: 'addo', sortable: false, disabled: true }
        ],
        items: [{ equipment: "beaker", location: 'Room 3535 drawer 21', qty: 21, id: '07f37f', pictureUrl: 'https://www.bhphotovideo.com/images/images2500x2500/Photographers_Formulary_09_0095_Glass_Beaker_600ml_231378.jpg' },
            { equipment: "ruler", location: 'Room 3535 drawer 10', qty: 7, id: '08f312', pictureUrl: 'https://images-na.ssl-images-amazon.com/images/I/41qUVuXt2AL.jpg' },
            { equipment: "flask", location: 'Room 2121 drawer 22', qty: 6, id: '09f37d', pictureUrl: 'https://images-na.ssl-images-amazon.com/images/I/316GJIEdJxL._SY445_.jpg' },
            { equipment: "vernier-caliber", location: 'Room 4125 drawer 21', qty: 12, id: '07g3hf', pictureUrl: 'https://static.grainger.com/rp/s/is/image/Grainger/2ZUF3_AS01?$mdmain$' }
                ],
        itemsAdded: []
    }

}

})

14
  • Where is model coming from? That is not an accepted Vue property. Commented May 26, 2019 at 17:57
  • im using vuetify to load the table and model. I hope this is what you are asking about? Commented May 26, 2019 at 18:09
  • I am referring to the model property. This does not exist in Vue. new Vue({ el: "#app", model: model, Furthermore, you reference this model prop within your Vue object - where is this data coming from? What is model? Can you supply the code for it? Commented May 26, 2019 at 18:22
  • oohhh I am using razor mvc for asp.net so I am passing in a model and having it JSON encoded so I can manipulate it using vue.js This is what I am doing <script> var model = @Html.Raw(Json.Encode(Model)) </script> Commented May 26, 2019 at 18:56
  • And thats working? Do you have a sample of the JSON data that I can use to test with? Commented May 26, 2019 at 19:44

1 Answer 1

1

I was able to get this to work by changing the v-model for the v-dialog on each item..

Code Snippet is below, and I have created a CodePen Mirror here as well.

It now sets the dialog open/close property for each specific item in the items list:

<v-dialog v-model="dialog[props.item.equipment]"...

The activator slot now looks like this:

[email protected]="$set(dialog, props.item.equipment, true)" slot="activator"...

..and the "close button" for the v-dialog had to also be modified to:

[email protected]="$set(dialog, props.item.equipment, false)"...

This means I also had to change dialog in your data() props to be an object:

data() {
  return {
    ...
    dialog: {},
    ...
  }
}

CODE SNIPPET:

new Vue({
  el: "#app",
  data() {
    return {
      disabled: "",
      searchAdded: "",
      message: "omae wa moo shindeiruu",
      dialog: {},
      notifications: false,
      sound: true,
      test: true,
      widgets: false,
      search: "",
      Headers: [
        { text: "Equipment", value: "equipment" },
        { text: "Location", value: "location" },
        { text: "Qty", value: "qty" },
        {
          text: "MoreInfo",
          value: "pictureUrl",
          sortable: false,
          disabled: false
        },
        {
          text: "Add or Remove",
          value: "addo",
          sortable: false,
          disabled: true
        }
      ],
      HeadersAdded: [
        { text: "Equipment", value: "itemName" },
        { text: "Location", value: "location" },
        { text: "Qty", value: "quantity" },
        {
          text: "Add or Remove",
          value: "addo",
          sortable: false,
          disabled: true
        }
      ],
      items: [
        {
          equipment: "beaker",
          location: "Room 3535 drawer 21",
          qty: 21,
          id: "07f37f",
          pictureUrl:"https://www.bhphotovideo.com/images/images2500x2500/Photographers_Formulary_09_0095_Glass_Beaker_600ml_231378.jpg"
        },
        {
          equipment: "ruler",
          location: "Room 3535 drawer 10",
          qty: 7,
          id: "08f312",
          pictureUrl: "https://images-na.ssl-images-amazon.com/images/I/41qUVuXt2AL.jpg"
        },
        {
          equipment: "flask",
          location: "Room 2121 drawer 22",
          qty: 6,
          id: "09f37d",
          pictureUrl: "https://images-na.ssl-images-amazon.com/images/I/316GJIEdJxL._SY445_.jpg"
        },
        {
          equipment: "vernier-caliber",
          location: "Room 4125 drawer 21",
          qty: 12,
          id: "07g3hf",
          pictureUrl: "https://static.grainger.com/rp/s/is/image/Grainger/2ZUF3_AS01?$mdmain$"
        }
      ],
      itemsAdded: []
    };
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.14/vuetify.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet"/>
<link href="https://static.fontawesome.com/css/fontawesome-app.css" rel="stylesheet"/>
<link href="https://pro.fontawesome.com/releases/v5.2.0/css/all.css" rel="stylesheet"/>


<div id="app">
    <v-app id="inspire">
        <v-card>
            <v-card-title>
                Un Added Lab Equipment
                <v-spacer></v-spacer>
                <v-text-field v-model="search" append-icon="search" label="Search" single-line hide-details>
                </v-text-field>
            </v-card-title>
            <v-data-table :headers="Headers" :items="items" :search="search" item-key="equipment" hide-actions expand
                class="elevation-1">
                <template slot="items" scope="props">
                    <td class="text-xs">{{ props.item.equipment }}</td>
                    <td class="text-xs">{{ props.item.location }}</td>
                    <td class="text-xs">{{ props.item.qty }}</td>
                    <td>
                        <v-dialog v-model="dialog[props.item.equipment]" lazy absolute>
                            <v-btn flat icon color="blue lighten-2"
                                @click.stop="$set(dialog, props.item.equipment, true)" slot="activator">
                                <v-icon>info</v-icon>
                            </v-btn>
                            <v-card>
                                <v-card-title>
                                    <div class="headline">More Info for '{{ props.item.equipment }}'</div>
                                </v-card-title>
                                <v-card-text>
                                    <v-img :src="props.item.pictureUrl" aspect-ratio="2.75"></v-img>
                                    {{props.item.location}}
                                </v-card-text>
                                <v-card-actions>
                                    <v-spacer></v-spacer>
                                    <v-btn class="blue--text darken-1" flat="flat"
                                        @click.stop="$set(dialog, props.item.equipment, false)">No</v-btn>
                                    <v-btn class="blue--text darken-1" flat="flat"
                                        @click.native="deleteRow(props.item)">Yes</v-btn>
                                </v-card-actions>
                            </v-card>
                        </v-dialog>
                    </td>
                    <td class="text-xs">
                        <button v-on:click="decrement(props.item.id)"
                            :disabled="disabled == props.item.id ? true : false">
                            <v-icon color="pink">remove</v-icon>
                        </button>
                        <button v-on:click="increment(props.item.id)" id="incrementButton"
                            :disabled="disabled == props.item.id + '2' ? true : false">
                            <v-icon color="green">add</v-icon>
                        </button>
                    </td>
                </template>
            </v-data-table>
        </v-card>
    </v-app>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.