Search code examples
vue.jspaginationvuetify.jsgrid-layout

Vuetify v-data-iterator's prop rows-per-page-items determines items per page, not rows


We are using Vuetify's v-data-iterator to control pagination on a grid layout. We are setting the iterator's rows-per-page-items to [8, 16, 24, 36]. But this doesn't exactly determine the number of rows per page, but items per page. That is, because it's a grid layout, there may be several items per row. So if we set it to 8, we get this:

enter image description here

This depends on screen size, of course, but that's exactly the issue. The number of ACTUAL rows depends on how many items can fit in a row. What's worse is that if the user selects 8 for the "rows" per page, and only 3 items can fit in a row, there will be only 2 items in the last row with a gap at the third column. This is deceptive because it looks like there are no more items after the 8th item (this has actually deceived some people into thinking the item they are looking for doesn't actually exist). They need to look at the footer to see that there are more items on the next page.

What we are wondering is if there is a way to configure the v-data-iterator to limit the number of actual rows instead of the number of items. This would mean, for example if you had 2 rows per page, there could be 8 items on the page (on wide screens) or 6 items on the page (on smaller screens), but at least there would be no gap after the last item on the page (or if there is a gap, it would only be because it is ACTUALLY the last item).

Thanks very much.


Solution

  • It appears Vuetify did away with rows-per-page-items in 2.x, perhaps for this reason.

    Controlling rows per page with responsive item rows is a little math challenge🤓 with the number of items, desired rows per page and Vuetify's 5 responsive breakpoints. Using computed values, determine the number of pages (for pagination), items per row (based on how many cols you want on each breakpoint), and finally use this to calculate the items per page (ipp)...

    computed: {
      numberOfPages () {
        return Math.ceil(this.beers.length / this.ipp)
      },
      itemsPerRow () {
        switch (this.$vuetify.breakpoint.name) {
          case 'xs': return 1
          case 'sm': return 2
          case 'md': return 3
          case 'lg': return 4
          case 'xl': return 6
        }
      },
      ipp () {
         return Math.ceil(this.rowsPerPage * this.itemsPerRow)
      }
    },
    

    And since Vuetify is based on a 12 column grid, determining the cols prop is simply...

     <v-row>
        <v-col
            v-for="(item,idx) in props.items"
            :key="item.name"
            :cols="(12/itemsPerRow)">
         ....
        </v-col>
     </v-row>
    

    Demo: https://codeply.com/p/bFrSEsnq4L