Piotr Płaczek
Piotr Płaczek

Reputation: 610

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

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>

Upvotes: 8

Views: 6624

Answers (5)

shearn89
shearn89

Reputation: 897

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' }
      ]

Upvotes: 0

AMIN
AMIN

Reputation: 31

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

Upvotes: 0

Balaji
Balaji

Reputation: 11007

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>

Upvotes: 4

Josh
Josh

Reputation: 2508

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.

Upvotes: 1

oshell
oshell

Reputation: 9123

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>

Upvotes: 0

Related Questions