HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
How to implement a Pager
I have a custom plugin that creates a custom content. I already have pages that implements add, edit, delete and view( single record only) functionalities . Now I want to implement another page that will show all records with a pager. Can someone point me into a tutorial or documentation on how to do this properly.
There is no tutorial on that and the pager is quite complex, thow you do not need to do much to get it going. After you have set up a working pager, I recommend taking a closer look at the class.pagermodule.php to find out more about its possibilities.
The best way to get going is to look at a page where you can find a pager, e.g. one of the discussions lists (recent discussions, bookmarked, mine etc.) You can find that code in /applications/vanilla/controllers/class.discussionscontroller.php
Let's look at the mine() method, which is quite short, but I stripped out what is not necessary to get a working example:
The main element in there is the following block:
The pager module needs to be configured with those information: where does the current page starts (offset), how much elements does it show (limit), how much elements are there in total (countDiscussions) and where should the previous and next page links should point to.
But look at method code step by step:
In your plugin this will most probably be
The $args array will contain everything that comes after yourforum.com/plugin/foo/...
Therefore, if your url scheme for e.g. the third page should be /plugin/foo/p3, you should have the following code for getting the page for building the pager:
$page = $args ?? 'p1';
If your url scheme is /plugin/foo/bar/baz/p3, the required code would be
$page = $args ?? 'p1';
This line does a lot! You should look up the function
offsetLimitin functions.general.php. What's happening here is that the variables $offset and $limit are filled based on the $page variable and the config value for Vanilla.Discussions.PerPage. I would encoure to make your view configurable in the same way.
And if it makes sense, you can directly use a Vanilla PerPage setting as default!
The following lines in the snippet are split because that way a plugin author can influence the look and feel of the pager of the mine() method.
You can condense it to this line
By the way: in most cases when you look at Vanilla code and see
$this, you will have to replace that with
$sender(if you stick to Vanillas conventions)
Frankly spoken, I'm not sure if you need this block:
ANd you have to decide by yourself if that makes sense for you:
In your view, a simple PagerModule::write() should be sufficient.
the code works, I replaced $page = $args ?? 'p1' with $page = $_GET["Page"] ?? 'p1'.
What Is best way to hide the next button at the end of the last record when pager reach the last page?
I found out that I need to set the options of PagerModule::write() in the view to make the url route work properly and the show the pager buttons with numbers
['Wrapper' => '<span class="PagerNub"> </span><div %1$s>%2$s</div>', 'RecordCount' => $this->data('count'), 'CurrentRecords' => $this->data('count')];
$PagerOptions['Url'] = $this->data('_PagerUrl');}
What is the best way to add dropdown filter with this?
Instead of having [previous] 1...7 [next] you want to have [__3__|\/]? Then the pager module isn't suitable. The good thing is that you now already know what you need!
This is the base info needed to build a pager, no matter what html you choose.
Vanilla has a Form class which can help you build dropdowns. It should look similar to this:
You would need to add some js that will catch click events on the GO! button (or directly track changing the dropdown) and reload the current page with the appropriate page. I would try to change the forms action attribute accordingly whenever the dropdown changes.