RowsPerPage option disappears if using pagination.sync in QTable



  • Re: QDataTable help

    I am having issues with the pagination scheme. If I try to override my q-table’s rowsPerPage option to say 7, then I see that the tables now display 7 as the initial amount. As an example, suppose that I have 12 items for that table and I only display 7. The user then has the option to change the rows per page to [3, 5, 7, 10, 15, 20, 25, 50, All] as a default . However, if they were to choose between 15-50 as their rowsPerPage, then the option to choose a different rowsPerPage disappears.

    I am using windows/chrome. I am implementing the initial pagination’s rowPerPage option by doing :pagination.sync="pagination" and in data data () { pagination: {rowsPerPage: 7}}.



  • use a model for your q-table’s :rows-per-page-options="rowsOptions" and change the array of that model according to your condition. in this sense giving it an empty array will hide it.

    from docs: https://quasar-framework.org/components/datatable.html
    rows-per-page-options type:Array description:Array of Numbers representing options for user to select how many rows per page should be shown. Example: ‘[3, 5, 7, 0]’. Notice value 0 means “All” and empty array hides the selection.

    watch: {
      'pagination' () {
        if (this.pagination.rowsPerPage === 0 || (this.pagination.rowsPerPage > 15 && this.pagination.rowsPerPage < 50)) {
          this.rowsOptions = []
        }
      }
    }
    


  • @metalsadman I tried your solution. I did :rows-per-page-options="rowsOptions". In data, I now have

    data () {
        return {
          rowsOptions: [3, 5, 7, 10, 15, 25, 50, 0],
          pagination: {
            rowsPerPage: 7,
            page: 1
          }
    }
    

    I implemented the watch but instead of giving it a blank array, because I don’t want it to be empty, I go ahead and re-establish this.rowsOptions to what I want it to be.

    watch: {
        'pagination' () {
          console.log(this.pagination.rowsPerPage)
          if (this.pagination.rowsPerPage === 0 || (this.pagination.rowsPerPage >= 15 && this.pagination.rowsPerPage < 50)) {
            this.rowsOptions = [3, 5, 7, 10, 15, 25, 50, 0]
          }
        }
      }
    

    However, the Rows per page still disappears on the UI if the user selects a Rows per page greater than the amount of items.



  • I also notice that on https://v0-15.quasar-framework.org/components/datatable.html#Controlling-pagination-custom-controls-amp-watching-for-page-navigation the example is basically what I have. They setup :pagination.sync="paginationControl" and paginationControl: { rowsPerPage: 3, page: 1 }. The rest of the example is just fancy stuff but the fact that the Rows per page doesn’t disappear on the UI is what I am lacking.



  • you need to put an else to set it back to default. example:

    data () { 
      ...
      defaultOpts: [3, 5, 7, 10, 15, 25, 50, 0],
      rowsOptions: [3, 5, 7, 10, 15, 25, 50, 0]
     ...
     },
    watch: {
        'pagination' () {
          console.log(this.pagination.rowsPerPage)
          if (this.pagination.rowsPerPage === 0 || (this.pagination.rowsPerPage >= 15 && this.pagination.rowsPerPage < 50)) {
             this.rowsOptions = []
          } else {       
             this.rowsOptions = this.defaultOpts
          }
        }
      }
    


  • @metalsadman The table control is still disappearing 😞



  • @metalsadman I got it. It was a dumb mistake. I have a condition :hide-bottom="items.length < pagination.rowsPerPage" Where the intention was to hide the table controls but this is obviously bad code. Thanks for your help!



  • However, while I have you here @metalsadman… This component is being spawned multiple. Imagine 5 different tables that all use this same component. If a user selects a different Rows per page on one of the tables, how can I reflect that across all tables?



  • you’ll need vuex for that to store the state of your pagination object and share it across your component.
    https://quasar-framework.org/guide/app-vuex-store.html
    https://vuex.vuejs.org/



  • @metalsadman I am a noob with vuex. I created a store with the property pagination in the structure we require. From my component, I am calling mapState from my file/variable. It sets my pagination how I want but I am not able to change it. I understand that I am supposed to use a mapMutation to change the store value but what is the event that handles the changing of the Rows per page selection?



  • no event in q-table that exposes that, just do same like the example i gave you, use watch hook on your vuex key.



  • @metalsadman I’m sorry but I can’t get it.

    In my store, store.js I have

    export default {
      state: {
        pagination: {
          rowsPerPage: 7,
          page: 1
        }
      }
    

    And from my table I have

    import { mapState } from 'vuex'
    export default {
      computed: {
        ...mapState('store', [
          'pagination'
        ])
    }
    

    I’m not sure how to implement the watch functionality like in your example if we are no longer using a v-model.



  • :pagination.sync="pagination" :rows-per-page-options="rowsOptions", also add the rowOptions in your state and add actions or mutations so you can change its values, then same as the example:

        'pagination' () {
          console.log(this.pagination.rowsPerPage)
          if (this.pagination.rowsPerPage === 0 || (this.pagination.rowsPerPage >= 15 && this.pagination.rowsPerPage < 50)) {
             this.setRowOptionAction([])
          } else {       
             this.setRowOptionAction(this.defaultOpts)
          }
        }
      }
    


  • Because pagination is an object, and depending on how you set it’s properies, you may have to write your watch a different way.
    if you use this.$set(this.pagination, 'rowsPerPage', value) then you’re good. Otherwise, you need to write your watch like this:
    https://vuejs.org/v2/api/#watch

    pagination: {
        handler: function (value) {
            console.log(this.pagination.rowsPerPage)
            if (this.pagination.rowsPerPage === 0 || (this.pagination.rowsPerPage >= 15 && this.pagination.rowsPerPage < 50)) {
               this.setRowOptionAction([])
            } else {       
               this.setRowOptionAction(this.defaultOpts)
            }
        },
        deep: true
    }