1

I am using a Vuetify data table with header and item slots. Now i have a button which by default should be hidden but i only want to show it when a row is selected or when all of them are selected. I assumed i should be able to use the selected data property but that seems to stay empty if i select one row. So not sure how i can hide/show the button.

This is a working pen.

This is the code:-

new Vue({
  el: "#app",
  data: () => ({
    pagination: {
      sortBy: "name"
    },
    selected: [],
    headers: [{
        text: "Dessert (100g serving)",
        align: "left",
        value: "name"
      },
      {
        text: "Calories",
        value: "calories"
      },
      {
        text: "Fat (g)",
        value: "fat"
      }
    ],
    desserts: [{
        name: "Frozen Yogurt",
        calories: 159,
        fat: 6.0
      },
      {
        name: "Ice cream sandwich",
        calories: 237,
        fat: 9.0
      }
    ]
  }),

  methods: {
    toggleAll() {
      if (this.selected.length) this.selected = [];
      else this.selected = this.desserts.slice();
    },
    changeSort(column) {
      if (this.pagination.sortBy === column) {
        this.pagination.descending = !this.pagination.descending;
      } else {
        this.pagination.sortBy = column;
        this.pagination.descending = false;
      }
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet" />

<div id="app">
  <v-app id="inspire">
    <v-data-table v-model="selected" :headers="headers" :items="desserts" :pagination.sync="pagination" select-all item-key="name" class="elevation-1">
      <template v-slot:headers="props">
        <tr>
          <th>
            <v-checkbox :input-value="props.all" :indeterminate="props.indeterminate" primary hide-details @click.stop="toggleAll"></v-checkbox>
          </th>
          <th v-for="header in props.headers" :key="header.text" @click="changeSort(header.value)">
            <v-icon small>arrow_upward</v-icon>
            {{ header.text }}
          </th>
        </tr>
      </template>
      <template v-slot:items="props">
        <tr :active="props.selected" @click="props.selected = !props.selected">
          <td>
            <v-checkbox :input-value="props.selected" primary hide-details></v-checkbox>
          </td>
          <td class="text-xs-center">{{ props.item.name }}</td>
          <td class="text-xs-center">{{ props.item.calories }}</td>
          <td class="text-xs-center">{{ props.item.fat }}</td>
        </tr>
      </template>
    </v-data-table>
    <v-container>
      <v-layout>
        <v-flex xs6 class="mt-5">
          <v-btn>Hide by default but show on selected</v-btn>
        </v-flex>
      </v-layout>
    </v-container>
  </v-app>
</div>

Any help will be appreciated. Thank you.

2
  • use vue computed Commented Apr 26, 2020 at 3:22
  • @JoshLin what will i be computing and based on what? Commented Apr 26, 2020 at 3:25

1 Answer 1

1

you can use selected.length.

here is a computed you can add

  computed: {
    showBtn() {
      return this.selected.length > 0
    }
  },

then use showBtn in your template

<v-btn v-if="showBtn">Hide by default but show on selected</v-btn>

You can also just use it inline, but I prefer using computed, because they cache the value, and make the template more readable

new Vue({
  el: "#app",
  data: () => ({
    pagination: {
      sortBy: "name"
    },
    selected: [],
    headers: [
      {
        text: "Dessert (100g serving)",
        align: "left",
        value: "name"
      },
      { text: "Calories", value: "calories" },
      { text: "Fat (g)", value: "fat" }
    ],
    desserts: [
      {
        name: "Frozen Yogurt",
        calories: 159,
        fat: 6.0
      },
      {
        name: "Ice cream sandwich",
        calories: 237,
        fat: 9.0
      }
    ]
  }),
  
  computed: {
    showBtn() {
      return this.selected.length > 0
    }
  },

  methods: {
    toggleAll() {
      if (this.selected.length) this.selected = [];
      else this.selected = this.desserts.slice();
    },
    changeSort(column) {
      if (this.pagination.sortBy === column) {
        this.pagination.descending = !this.pagination.descending;
      } else {
        this.pagination.sortBy = column;
        this.pagination.descending = false;
      }
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>



<div id="app">
  <v-app id="inspire">
    <v-data-table v-model="selected" :headers="headers" :items="desserts" :pagination.sync="pagination" select-all item-key="name" class="elevation-1">
      <template v-slot:headers="props">
        <tr>
          <th>
            <v-checkbox :input-value="props.all" :indeterminate="props.indeterminate" primary hide-details @click.stop="toggleAll"></v-checkbox>
          </th>
          <th v-for="header in props.headers" :key="header.text" :class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']" @click="changeSort(header.value)">
            <v-icon small>arrow_upward</v-icon>
            {{ header.text }}
          </th>
        </tr>
      </template>
      <template v-slot:items="props">
        <tr :active="props.selected" @click="props.selected = !props.selected">
          <td>
            <v-checkbox :input-value="props.selected" primary hide-details></v-checkbox>
          </td>
          <td class="text-xs-center">{{ props.item.name }}</td>
          <td class="text-xs-center">{{ props.item.calories }}</td>
          <td class="text-xs-center">{{ props.item.fat }}</td>
        </tr>
      </template>
    </v-data-table>
    <v-container>
    <v-container>
      <v-layout>
        <v-flex xs6 class="mt-5">
          <v-btn v-if="showBtn">Hide by default but show on selected</v-btn>
        </v-flex>
      </v-layout>
    </v-container>
  </v-app>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.