Setting the Page of a Paginated DataTable Programmatically?

UI Components for Vue
Post Reply
adlaws
Posts: 9
Joined: 04 Feb 2021, 10:51

16 Feb 2021, 07:46

Howdy,

Is there any way to programmatically set the page of a paginated datatable?

My use case for this is as follows:

I have a paginated `DataTable` with a single select model and a list-like presentation of the same data items. If an item is selected in one, it is also selected in the other.

When an item selected in the list, I would like to ensure that the corresponding page of the `DataTable` is also displayed so the item can be seen there too.

So far I have looked for...
  • a method to call on the `DataTable` component to change the page (e.g., `this.$refs.theDataTable.changePage(2);`
  • an exposure of the `Paginator` used by the `DataTable` so that I could call its `changePage(...)` method (e.g., `this.$refs.theDataTable.paginator.changePage(2);`
  • a property to manipulate (like I could with `selection.sync`) to control the page (e.g. `<DataTable :value="myValues" :paginator="true" :page.sync="page">`)
...but I haven't had any joy with any of these approaches - none of them are available.

Currently the only way forward that I can see is to use the `Paginator` with a "basic" `DataTable` and manage the pagination of the items manually. This is not "terrible", but given the integration of the `Paginator` and the `DataTable` is as simple as using the `:paginator="true"` property, it feels like I must be missing a simpler approach.

Is there something I'm missing, or does anyone have any suggestions on a workaround other than the one I have outlined?

Thanks!

Andrew

adlaws
Posts: 9
Joined: 04 Feb 2021, 10:51

16 Feb 2021, 08:45

In reply to my own question, I have the following workaround which is probably the neatest solution for my situation for the time being.

That said, it's a bit brittle in that it relies on knowing the component tag for the paginator - it would be nice to be able to access the paginator in a more "official" way.

So, basically, I declare the `DataTable` like this:

Code: Select all

<DataTable
    ref="theTable"
    :value="waypoints"
    :paginator="true"
/>
...then I set things up like this, with the `mounted()` hook inspecting the `$children` of the `DataTable` component to find the paginator component... :twisted:

Code: Select all

export default {
    data()
    {
        return {
            paginator:null,
        };
    },
    mounted()
    {
        const theTable = this.$refs.theTable;
        // run through `DataTable` Vue component children, get the first one with the component tag 'DTPaginator`
        this.paginator = theTable.$children.filter((c) => c.$options._componentTag === 'DTPaginator')[0]; // evil, but it works
    }
}
From then on, I can change the page of the paginated `DataTable` by calling `this.paginator.changePage(2);`, or whatever page I want to go to.

So that works - use it at your own risk if you want. Like I said, it's brittle - if the paginator component's `DTPaginator` component tag ever changes, this approach will stop working for no obvious reason, and it may be difficult to track down exactly what went wrong for someone who is not aware of this somewhat hacky approach. :?

What I would prefer to do this is something along the lines of one of the following alternatives:

Code: Select all

<!-- EXAMPLE ONLY, NOT REAL CODE-->
<DataTable
    ref="theTable"
    :value="waypoints"
    :paginator="true"
    :page.sync="currentPage"
/>
...so that setting the value of `currentPage` changes the page, and changing the page with the paginator component updates the value of `currentPage`.

Less nice, but similar to my existing approach, would be the ability to get hold of the `Paginator` component instance in some "official" way, like...

Code: Select all

<!-- EXAMPLE ONLY, NOT REAL CODE-->
<DataTable
    ref="theTable"
    :value="waypoints"
    :paginator="true"
/>

<script>
export default {
    data()
    {
        return {
            paginator:null,
        };
    },
    mounted()
    {
        const theTable = this.$refs.theTable;
        this.paginator = theTable.paginator;
    }
}
</script>
Anyway, here's hoping someone in the PrimeVue team likes the idea and provides a mechanism for this. :)

As a side note, I also came across the documentation for the `first` property of `DataTable`; it looks like it will do what I am trying to do, but it does something quite different - it simply sets the first item displayed (in the entire table), meaning that items before it are missing from the table entirely(!). I'm not actually sure I see the use case for this property, but I have no doubt there is a good reason for it. See https://www.primefaces.org/primevue/sho ... /datatable for more details on this.

Cheers!

Andrew

Post Reply

Return to “PrimeVue”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 1 guest