QTable footer with total count for each column visible



  • Re: qtable summary footer

    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 docs 😕

    What 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.

    Captura de Tela_Área de Seleção_20200309104623.png

    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!! 💕



  • @aislan

    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 this bottom-row I can follow the columns and each q-td get hidden together when toggling the visible cols (the respective q-td of the tbody and q-th for header?



  • @aislan

    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:

    c598deb1-e02e-473e-a750-bc2c023de77f-image.png

    And if you hide columns, works just as well:

    7f376bd3-cf6f-46df-9558-3d0a5ccb54be-image.png

    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


Log in to reply