1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Ui;
6:
7: use Atk4\Ui\Js\Jquery;
8: use Atk4\Ui\Js\JsExpressionable;
9:
10: /**
11: * Paginate content using scroll event in JS.
12: */
13: class JsPaginator extends JsCallback
14: {
15: /** @var View|null The View that trigger scrolling event. */
16: public $view;
17:
18: /**
19: * The JS scroll plugin options
20: * - appendTo: the HTML selector where new content should be appendTo.
21: * Ex: For a table, the selector would be 'tbody'.
22: * - padding: Bottom padding need prior to perform a page request.
23: * Page request will be ask when container is scroll down and reach padding value.
24: * - initialPage: The initial page load.
25: * The next page request will be initialPage + 1.
26: * - hasFixTableHeader: boolean Should we use fixed table header.
27: * - tableContainerHeight: int Fixed height of table container in pixels.
28: * - tableHeaderColor: int|string HTML color for header.
29: *
30: * @var array
31: */
32: public $options = [];
33:
34: #[\Override]
35: protected function init(): void
36: {
37: parent::init();
38:
39: if (!$this->view) {
40: $this->view = $this->getOwner();
41: }
42:
43: $this->view->js(true)->atkScroll([
44: 'url' => $this->getJsUrl(),
45: 'urlOptions' => $this->args,
46: 'options' => $this->options,
47: ]);
48: }
49:
50: /**
51: * Set JsPaginator in idle mode.
52: *
53: * @return Jquery
54: */
55: public function jsIdle(): JsExpressionable
56: {
57: return $this->view->js(true)->atkScroll('idle');
58: }
59:
60: /**
61: * Get current page number.
62: */
63: public function getPage(): int
64: {
65: return (int) ($this->getApp()->tryGetRequestQueryParam('page') ?? 0);
66: }
67:
68: /**
69: * Callback when container has been scroll to bottom.
70: *
71: * @param \Closure(int): (JsExpressionable|View|string|void) $fx
72: */
73: public function onScroll(\Closure $fx): void
74: {
75: $page = $this->getPage();
76: $this->set(static function () use ($fx, $page) {
77: return $fx($page);
78: });
79: }
80: }
81: