QTable footer with total count for each column visible
-
As this topic above, I’m looking for this feature as well. The QTable doesn’t have a
footer
by default?
I wasn’t expecting that a component like the table shouldn’t have a basic feature like that. We have so many options, but this doesn’t exist in the docsWhat kind of footer I’m trying to do is like in this design below, just only a footer row that have for each columns a total count. This total count should appear and disappear with the column itself, of course.
Would be great if we have this footer sticky as well.
Anyone knows how to accomplish that ? In advance, many thanks for this awesome framework!!
-
I think you could easily achieve this with the bottom-row slot:
<template v-slot:bottom-row> <q-tr> <q-td colspan="100%"> Bottom row </q-td> </q-tr> </template>
There’s an example on the docs page
From what I could understand it doesn’t work if virtual-scroll is set, but for your use case that’s probably not very relevant.
If you are worried about filtering out columns, I think by writing a method that reads a table visibleColumns property, and having some property on the config stating if the column should be added or not, I should be rather easy.I’ll try and get an example running actually, it’s a fairly common requirement.
-
@cmanique if this work with local pagination, it’s fine.
But with thisbottom-row
I can follow the columns and eachq-td
get hidden together when toggling the visible cols (the respectiveq-td
of the tbody andq-th
for header? -
So, I gave it a shot with the most naive approach possible.
Assuming you have data of visibility of columns and column configuration (notice I added a sums boolean to check if you are doing that for a given column):
data () { return { visibleColumns: ['calories', 'desc', 'fat', 'carbs', 'protein', 'sodium', 'calcium', 'iron'], columns: [ { name: 'desc', required: true, label: 'Dessert (100g serving)', align: 'left', field: row => row.name, format: val => `${val}`, sortable: true }, { name: 'calories', align: 'center', label: 'Calories', field: 'calories', sortable: true }, { name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true }, { name: 'carbs', label: 'Carbs (g)', field: 'carbs', sums: true }, { name: 'protein', label: 'Protein (g)', field: 'protein' }, { name: 'sodium', label: 'Sodium (mg)', field: 'sodium', sums: true }, { name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, { name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) } ],
Then you can write a computed in the likes of:
bottomColumns: function () { var retVal = [] for (let i = 0; i < this.columns.length; i++) { var isVisible = false for (let j = 0; j < this.visibleColumns.length; j++) { if (this.visibleColumns[j] === this.columns[i].name) { isVisible = true break } } if (isVisible) { if (this.columns[i].sums) { // need to calculate sum, wonder how retVal.push({ name: this.columns[i].name, text: ' the sum of ' + this.columns[i].name }) } else { retVal.push({ name: this.columns[i].name, text: '' }) } } } return retVal }
And use it in the bottom-row in the following way:
<template v-slot:bottom-row> <q-tr> <q-td v-bind:key="column.name" v-for="column in bottomColumns"> {{ column.text }} </q-td> </q-tr> </template>
Which outputs something like this:
And if you hide columns, works just as well:
How you will calculate the sums, and if they are based on the current page or total, beats me.
I think it’s a reasonable hack, dunno about performance and I’m sure it can be vastly improved.HTH