Vuetify data table in single-select mode, selecting one row selects all others
Asked Answered
J

5

8

I am trying to select one row in the table and emit the selected item.

Selecting one selects all but only the first encountered object is saved to the model (as selected variable).

Do you have any ideas, what i'm doing wrong?

enter image description here

<template>
  <v-data-table
    :headers="headers"
    :items="items"
    :search="search"
    :loading="loading"
    v-model="selected"
    single-select
    show-select
    :options="{itemsPerPage:5}"
    @item-selected="itemSelected"
  >
    <template v-slot:top>
      <v-toolbar flat>
        <v-text-field
          v-model="search"
          append-icon="mdi-magnify"
          label="Search"
          single-line
          hide-details
        ></v-text-field>
      </v-toolbar>
    </template>

    <template v-slot:item.name="{ item }">{{ item.name }}</template>
  </v-data-table>
</template>

<script>
export default {
  name: "variable-selector",
  props: ["variables", "map", "index"],
  data() {
    return {
      search: "",
      selected: {},
      loading: false,
      items: [],
      headers: [{ text: "Variable name", value: "name", sortable: true }]
    };
  },
  methods: {
    itemSelected(selection) {
      if (selection.value) {
        this.$emit("selected", selection.item); // it always emits var_2 object
      } else {
        this.$emit("selected", null);
      }
    },

    updateItemsList(variables) {
      this.items = Array.from(variables);
    }
  },

  mounted() {
    this.updateItemsList(this.variables);
  },

  watch: {
    variables(newValue) {
      this.loading = true;
      this.updateItemsList(newValue);
      this.loading = false;
    }
  }
};
</script>
Jaine answered 29/5, 2020 at 11:16 Comment(1)
Please create an answer instead of editing the solution announcement into the question. Or just accept the best one by using the tick mark next to it.Respire
J
4

Each object should be unique key value if u face error , you want manually tell each object is unique

just add

item-key="table_header_index"//or name 

eg:

<v-data-table
    :headers="headers"
    :items="items"
    show-select
    item-key="table_header_index"  <-------------------add this line
>

</v-data-table>
Jordain answered 14/12, 2020 at 9:9 Comment(0)
C
1

I had this issue and the realized my item-key="value" did not match any of the values in my header. Select one of your header values and it should work.

Commodore answered 10/11, 2020 at 7:40 Comment(0)
E
0

From the example in the docs I can see the following:

1.) selected should be an array, not an object

Selected holds all selected values. single-select property just determines if the length can be bigger than 1.

2.) if you use v-model you should not use @item-selected="itemSelected"

v-model is already 2 way binding. but you trigger an additional event and override the model (which should be an array) with an object or null

Solution

Make selected an array and remove @item-selected="itemSelected".

<template>
  <v-data-table
    :headers="headers"
    :items="items"
    :search="search"
    :loading="loading"
    v-model="selected"
    single-select
    show-select
    :options="{itemsPerPage:5}"
  >
    <template v-slot:top>
      <v-toolbar flat>
        <v-text-field
          v-model="search"
          append-icon="mdi-magnify"
          label="Search"
          single-line
          hide-details
        ></v-text-field>
      </v-toolbar>
    </template>

    <template v-slot:item.name="{ item }">{{ item.name }}</template>
  </v-data-table>
</template>

<script>
export default {
  name: "variable-selector",
  props: ["variables", "map", "index"],
  data() {
    return {
      search: "",
      selected: [],
      loading: false,
      items: [],
      headers: [{ text: "Variable name", value: "name", sortable: true }]
    };
  },
  methods: {
    updateItemsList(variables) {
      this.items = Array.from(variables);
    }
  },

  mounted() {
    this.updateItemsList(this.variables);
  },

  watch: {
    variables(newValue) {
      this.loading = true;
      this.updateItemsList(newValue);
      this.loading = false;
    }
  }
};
</script>
Easley answered 29/5, 2020 at 11:55 Comment(1)
I forgot about this thread ... The solution to the problem is to add the parameters selectable-key =" name " and item-key =" name " to v-data-table and default to` "id" `. My items do not have such a field and it was necessary to indicate what the check was about.Predict
B
0

your data from back should have primary key. if it does it your table understand it; and if your data doesn't have primary key should write item-key for table.

good luck

Brigittebriley answered 12/5, 2021 at 10:55 Comment(0)
A
0

Quick update in November 2023, I had exactly this issue with a Vue3/vuetify app and the above solutions didn't solve it. I needed to use item-value="my-key" rather than item-key.

<v-data-table :headers="headers" :items="things" :search="search"
            show-select item-value="SortKey" v-model="selected"
            :footer-props="{ 'items-per-page-options': [10, 25, 50, 100] }"
            :sort-by="['Name']">

and then in the setup script, I was creating:

headers: [
        { title: 'Some Field', value: 'SortKey' }
      ]
Arletha answered 21/11, 2023 at 11:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.