0
votes

I'm trying to configure a drop down filter for each column in my vuetify data table. It seems the vuetify autocomplete component has the functionality I want but I'm not sure how to get the values from the autocomplete component to filter the data table. Here's what I have:

<template>
  <v-card>
    <v-card-title>
      {{gridTitle}}
      <v-spacer></v-spacer>
    </v-card-title>
    <v-data-table
      v-model="selected"
      :headers="headers"
      :items="dataSource"
      class="elevation-1"
      :search="search"
      :loading="isloading"
      item-key="id"
      show-select
      multi-sort
      dense
    >

    <template v-slot:header.id="{ header }" >
    <v-autocomplete
        v-model="search"
        :items="dataSource"
        item-text="id"
        :label="header.value"
        v-bind="selected"
        dense
        multiple
        chips
        small-chips
        filled
      >
      </v-autocomplete>
    </template>
      <v-progress-linear
        slot="progress"
        color="blue"
        indeterminate
      ></v-progress-linear>

      <v-alert
        slot="no-results"
        :value="true"
        color="error"
        icon="warning"
      >Your search for "{{ search }}" found no results.</v-alert>
    </v-data-table>
  </v-card>
</template>

<script>
export default {
  name: "ConfirmationsGrid",
  data() {
    return {
      isloading: true,
      search: "",
      selected: [],
    };
  },
  props: {
    dataSource: {
      type: Array[Object],
      default: new Array(),
    },
    headers: Array[String], 
    gridTitle: String,
  },
  mounted() {
    this.isloading = false;
  },
  methods: {
    onSelectMethod: function (value) {
      this.$emit("select_method", value);

    },
  },
};
</script>

At the moment I'm testing with the one header. slot but I plan on extending to all headers. This renders the autocomplete as the column header and also shows the correct values in the drop down but selecting them doesn't filter the table. I only get the following error:

[Vue warn]: Invalid prop: type check failed for prop "search". Expected String with value "2579034", got Array

Any ideas on how I can convert the autocomplete data into a string?

1
Can you post the script part? But I suspected the multiple prop on the autocomplete component to be the cause of "array" being the bound value.Yom T.
Edited to add scriptjamesfranco
I'd like to keep the multiple functionality. Is there anyway to change how autocomplete binds the value?jamesfranco
What exactly do you need to be the v-data-table filter, is it the matching or "selected" item from the search (since multiple gives you array results), or what's being typed in the text field?Yom T.
@YomS. The autocompletes are populated with the current values from the data set. So for example the autocomplete on the ID column will have a list of all the unique ID's in the data set. Selecting them will filter the data table to only those rows with the selected IDs.jamesfranco

1 Answers

2
votes

You are adding the prop multiple to the v-autocomplete tag with v-model search, so it returns an Array, i.e.:

["search option1", "searchOption2"]

But the v-autocomplete tag with v-model selected is using the search prop as String, so that's te reason of the error.

The default behavior of the search prop for v-autocomplete tag is to match the string passed to it with each value in its options.

To test it, remove the multiple prop in the search v-autocomplete tag, and you can see that it works.

Now, in order to work with multiple word search, you can have a computed property as items for the first v-autocomplete:

...    
computed: {
  itemsForSelected() {
    if (this.search.length) {
      return this.dataSource.filter(item => this.search.includes(item))
    }
    return this.dataSource
  }
}
...

<template>
  <v-card>
    <v-card-title>
      {{gridTitle}}
      <v-spacer></v-spacer>
    </v-card-title>
    <v-data-table
      v-model="selected"
      :headers="headers"
      :items="itemsForSelected"
      class="elevation-1"
      :loading="isloading"
      item-key="id"
      show-select
      multi-sort
      dense
    >

    <template v-slot:header.id="{ header }" >
    <v-autocomplete
        v-model="search"
        :items="dataSource"
        item-text="id"
        :label="header.value"
        v-bind="selected"
        dense
        multiple
        chips
        small-chips
        filled
      >
      </v-autocomplete>
    </template>
      <v-progress-linear
        slot="progress"
        color="blue"
        indeterminate
      ></v-progress-linear>

      <v-alert
        slot="no-results"
        :value="true"
        color="error"
        icon="warning"
      >Your search for "{{ search }}" found no results.</v-alert>
    </v-data-table>
  </v-card>
</template>

Now you can remove the search prop from the first v-autocomplete, this solution is not useful if you want to have the search by substrings ("hol" matching "alcohol"), it just filter the items from the source that are not selected in the search filter. A better solution could be includes a regex to match more options.