Categories
Vuetify

Vuetify — Table Checkbox and Filtering

Spread the love

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Simple Checkbox

We can add a checkbox inside our table.

We can add the v-simple-checkbox component to add the checkbox.

For example, we can write:

<template>
  <div>
    <v-data-table :headers="headers" :items="desserts" class="elevation-1">
      <template v-slot:item.glutenfree="{ item }">
        <v-simple-checkbox v-model="item.glutenfree" disabled></v-simple-checkbox>
      </template>
    </v-data-table>
  </div>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    desserts: [
      {
        name: "Frozen Yogurt",
        calories: 159,
        fat: 6.0,
        glutenfree: true,
      },
      {
        name: "Ice cream sandwich",
        calories: 237,
        fat: 9.0,
        glutenfree: false,
      },
      {
        name: "Eclair",
        calories: 262,
        fat: 16.0,
        glutenfree: false,
      },
    ],
    headers: [
      {
        text: "Dessert (100g serving)",
        align: "start",
        sortable: false,
        value: "name",
      },
      { text: "Calories", value: "calories" },
      { text: "Fat (g)", value: "fat" },
      { text: "Gluten-Free", value: "glutenfree" },
    ],
  }),
};
</script>

to add a table with the v-data-table component.

The v-slot:item.glutenfree slot lets us add a checkbox to set the value of the glutenfree property of an entry.

Expandable Rows

The show-expand prop lets us render an expand icon on each row.

To add it, we can write:

<template>
  <v-data-table
    :headers="headers"
    :items="desserts"
    :expanded.sync="expanded"
    item-key="name"
    show-expand
    class="elevation-1"
  >
    <template v-slot:top>
      <v-toolbar flat>
        <v-toolbar-title>Expandable Table</v-toolbar-title>
      </v-toolbar>
    </template>
    <template v-slot:expanded-item="{ headers, item }">
      <td :colspan="headers.length">More info about {{ item.name }}</td>
    </template>
  </v-data-table>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    expanded: [],
    desserts: [
      {
        name: "Frozen Yogurt",
        calories: 159,
        fat: 6.0,
        glutenfree: true,
      },
      {
        name: "Ice cream sandwich",
        calories: 237,
        fat: 9.0,
        glutenfree: false,
      },
      {
        name: "Eclair",
        calories: 262,
        fat: 16.0,
        glutenfree: false,
      },
    ],
    headers: [
      {
        text: "Dessert (100g serving)",
        align: "start",
        sortable: false,
        value: "name",
      },
      { text: "Calories", value: "calories" },
      { text: "Fat (g)", value: "fat" },
      { text: "Gluten-Free", value: "glutenfree" },
    ],
  }),
};
</script>

We populate the expanded-item slot with our own items.

The expanded state to let us get and set which rows are expanded.

It’s used as the value of the expanded.sync prop so it can get and set the values.

Custom Filtering

We can add filtering to our table.

For instance, we can write:

<template>
  <div>
    <v-data-table
      :headers="headers"
      :items="desserts"
      item-key="name"
      class="elevation-1"
      :search="search"
      :custom-filter="filterOnlyCapsText"
    >
      <template v-slot:top>
        <v-text-field v-model="search" label="Search (UPPER CASE ONLY)" class="mx-4"></v-text-field>
      </template>
      <template v-slot:body.append>
        <tr>
          <td></td>
          <td>
            <v-text-field v-model="calories" type="number" label="Less than"></v-text-field>
          </td>
          <td colspan="4"></td>
        </tr>
      </template>
    </v-data-table>
  </div>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      search: "",
      calories: "",
      desserts: [
        {
          name: "Frozen Yogurt",
          calories: 159,
          fat: 6.0,
        },
        {
          name: "Ice cream sandwich",
          calories: 237,
          fat: 9.0,
        },
        {
          name: "Eclair",
          calories: 262,
          fat: 16.0,
        },
      ],
    };
  },
  computed: {
    headers() {
      return [
        {
          text: "Dessert (100g serving)",
          align: "start",
          sortable: false,
          value: "name",
        },
        {
          text: "Calories",
          value: "calories",
          filter: (value) => {
            return !this.calories || value < parseInt(this.calories);
          },
        },
        { text: "Fat (g)", value: "fat" },
      ];
    },
  },
  methods: {
    filterOnlyCapsText(value, search, item) {
      return (
        value != null &&
        search != null &&
        typeof value === "string" &&
        value.toString().toLocaleUpperCase().indexOf(search) !== -1
      );
    },
  },
};
</script>

We have the filterOnlyCapsText method to let users search with upper case text.

Also, we have the header computed property so that we can filter the values properly when this.calories changes according to what we typed in.

Conclusion

We can add our own filtering logic to Vuetify tables.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *