jamesfranco
jamesfranco

Reputation: 520

Vuetify datatable search prop with autocomplete component

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?

Upvotes: 0

Views: 3089

Answers (1)

Andres Foronda
Andres Foronda

Reputation: 1409

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.

Upvotes: 2

Related Questions