MDL-68288 core_table: support pagination bar for dynamic tables
authorSimey Lameze <simey@moodle.com>
Mon, 6 Apr 2020 03:14:40 +0000 (11:14 +0800)
committerSimey Lameze <simey@moodle.com>
Wed, 8 Apr 2020 23:06:35 +0000 (07:06 +0800)
13 files changed:
lib/outputcomponents.php
lib/table/amd/build/dynamic.min.js
lib/table/amd/build/dynamic.min.js.map
lib/table/amd/build/local/dynamic/repository.min.js
lib/table/amd/build/local/dynamic/repository.min.js.map
lib/table/amd/build/local/dynamic/selectors.min.js
lib/table/amd/build/local/dynamic/selectors.min.js.map
lib/table/amd/src/dynamic.js
lib/table/amd/src/local/dynamic/repository.js
lib/table/amd/src/local/dynamic/selectors.js
lib/table/classes/external/dynamic/fetch.php
lib/tablelib.php
lib/templates/paging_bar.mustache

index fa9a76f..f33fda9 100644 (file)
@@ -3085,6 +3085,7 @@ class paging_bar implements renderable, templatable {
         $data->label = get_string('page');
         $data->pages = [];
         $data->haspages = $this->totalcount > $this->perpage;
+        $data->pagesize = $this->perpage;
 
         if (!$data->haspages) {
             return $data;
index 2a30ca5..26453f9 100644 (file)
Binary files a/lib/table/amd/build/dynamic.min.js and b/lib/table/amd/build/dynamic.min.js differ
index a6d77b2..15c863a 100644 (file)
Binary files a/lib/table/amd/build/dynamic.min.js.map and b/lib/table/amd/build/dynamic.min.js.map differ
index 849507d..439fe85 100644 (file)
Binary files a/lib/table/amd/build/local/dynamic/repository.min.js and b/lib/table/amd/build/local/dynamic/repository.min.js differ
index 88acdf0..4806057 100644 (file)
Binary files a/lib/table/amd/build/local/dynamic/repository.min.js.map and b/lib/table/amd/build/local/dynamic/repository.min.js.map differ
index 7e047e0..f4dc44a 100644 (file)
Binary files a/lib/table/amd/build/local/dynamic/selectors.min.js and b/lib/table/amd/build/local/dynamic/selectors.min.js differ
index 525cf30..73059fc 100644 (file)
Binary files a/lib/table/amd/build/local/dynamic/selectors.min.js.map and b/lib/table/amd/build/local/dynamic/selectors.min.js.map differ
index 4cddc4d..5f11a38 100644 (file)
@@ -75,6 +75,8 @@ export const refreshTableContent = tableRoot => {
             filters: filterset.filters,
             firstinitial: tableRoot.dataset.tableFirstInitial,
             lastinitial: tableRoot.dataset.tableLastInitial,
+            pageNumber: tableRoot.dataset.tablePageNumber,
+            pageSize: tableRoot.dataset.tablePageSize,
         }
     )
     .then(data => {
@@ -92,6 +94,8 @@ export const updateTable = (tableRoot, {
     filters = null,
     firstInitial = null,
     lastInitial = null,
+    pageNumber = null,
+    pageSize = null,
 } = {}, refreshContent = true) => {
     checkTableIsDynamic(tableRoot);
 
@@ -110,6 +114,14 @@ export const updateTable = (tableRoot, {
         tableRoot.dataset.tableLastInitial = lastInitial;
     }
 
+    if (pageNumber !== null) {
+        tableRoot.dataset.tablePageNumber = pageNumber;
+    }
+
+    if (pageSize !== null) {
+        tableRoot.dataset.tablePageSize = pageSize;
+    }
+
     // Update filters.
     if (filters) {
         tableRoot.dataset.tableFilters = JSON.stringify(filters);
@@ -146,6 +158,28 @@ export const setFilters = (tableRoot, filters, refreshContent = true) =>
 export const setSortOrder = (tableRoot, sortBy, sortOrder, refreshContent = true) =>
     updateTable(tableRoot, {sortBy, sortOrder}, refreshContent);
 
+/**
+ * Set the page number.
+ *
+ * @param {HTMLElement} tableRoot
+ * @param {String} pageNumber
+ * @param {Bool} refreshContent
+ * @returns {Promise}
+ */
+export const setPageNumber = (tableRoot, pageNumber, refreshContent = true) =>
+    updateTable(tableRoot, {pageNumber}, refreshContent);
+
+/**
+ * Set the page size.
+ *
+ * @param {HTMLElement} tableRoot
+ * @param {Number} pageSize
+ * @param {Bool} refreshContent
+ * @returns {Promise}
+ */
+export const setPageSize = (tableRoot, pageSize, refreshContent = true) =>
+    updateTable(tableRoot, {pageSize, pageNumber: 0}, refreshContent);
+
 /**
  * Update the first initial to show.
  *
@@ -205,5 +239,12 @@ export const init = () => {
 
             setLastInitial(tableRoot, lastInitialLink.dataset.initial);
         }
+
+        const pageItem = e.target.closest(Selectors.paginationBar.links.pageItem);
+        if (pageItem) {
+            e.preventDefault();
+
+            setPageNumber(tableRoot, pageItem.dataset.pageNumber);
+        }
     });
 };
index 6743775..5ef99c4 100644 (file)
@@ -33,6 +33,8 @@ import {call as fetchMany} from 'core/ajax';
  * @param {Object} filters The filters to apply when searching
  * @param {String} firstinitial The first name initial to filter on
  * @param {String} lastinitial The last name initial to filter on
+ * @param {String} pageNumber The page number
+ * @param {Number} pageSize The page size
  * @param {Number} params parameters to request table
  * @return {Promise} Resolved with requested table view
  */
@@ -43,6 +45,8 @@ export const fetch = (handler, uniqueid, {
         filters = {},
         firstinitial = null,
         lastinitial = null,
+        pageNumber = null,
+        pageSize = null,
     } = {}
 ) => {
     return fetchMany([{
@@ -56,6 +60,8 @@ export const fetch = (handler, uniqueid, {
             filters,
             firstinitial,
             lastinitial,
+            pagenumber: pageNumber,
+            pagesize: pageSize,
         },
     }])[0];
 };
index 6803571..118f328 100644 (file)
@@ -36,4 +36,9 @@ export default {
             lastInitial: '.lastinitial [data-initial]',
         },
     },
+    paginationBar: {
+        links: {
+            pageItem: '.pagination [data-page-number]'
+        }
+    },
 };
index b029ff5..194822f 100644 (file)
@@ -98,6 +98,18 @@ class fetch extends external_api {
                 VALUE_REQUIRED,
                 null
             ),
+            'pagenumber' => new external_value(
+                PARAM_INT,
+                'The page number',
+                VALUE_REQUIRED,
+                null
+            ),
+            'pagesize' => new external_value(
+                PARAM_INT,
+                'The number of records per page',
+                VALUE_REQUIRED,
+                null
+            ),
         ]);
     }
 
@@ -112,6 +124,9 @@ class fetch extends external_api {
      * @param string $jointype The join type.
      * @param string $firstinitial The first name initial to filter on
      * @param string $lastinitial The last name initial to filter on
+     * @param int $pagenumber The page number.
+     * @param int $pagesize The number of records.
+     * @param string $jointype The join type.
      *
      * @return array
      */
@@ -123,7 +138,9 @@ class fetch extends external_api {
         ?array $filters = null,
         ?string $jointype = null,
         ?string $firstinitial = null,
-        ?string $lastinitial = null
+        ?string $lastinitial = null,
+        ?int $pagenumber = null,
+        ?int $pagesize = null
     ) {
 
         global $PAGE;
@@ -141,6 +158,8 @@ class fetch extends external_api {
             'jointype' => $jointype,
             'firstinitial' => $firstinitial,
             'lastinitial' => $lastinitial,
+            'pagenumber' => $pagenumber,
+            'pagesize' => $pagesize,
         ] = self::validate_parameters(self::execute_parameters(), [
             'handler' => $handler,
             'uniqueid' => $uniqueid,
@@ -150,6 +169,8 @@ class fetch extends external_api {
             'jointype' => $jointype,
             'firstinitial' => $firstinitial,
             'lastinitial' => $lastinitial,
+            'pagenumber' => $pagenumber,
+            'pagesize' => $pagesize,
         ]);
 
         $filterset = new \core_user\table\participants_filterset();
@@ -173,13 +194,20 @@ class fetch extends external_api {
             $instance->set_last_initial($lastinitial);
         }
 
-        $context = $instance->get_context();
+        if ($pagenumber !== null) {
+            $instance->set_page_number($pagenumber);
+        }
 
+        if ($pagesize === null) {
+            $pagesize = 20;
+        }
+
+        $context = $instance->get_context();
         self::validate_context($context);
         $PAGE->set_url($instance->get_base_url());
 
         ob_start();
-        $instance->out(20, true);
+        $instance->out($pagesize, true);
         $participanttablehtml = ob_get_contents();
         ob_end_clean();
 
index 0203543..3f79a59 100644 (file)
@@ -549,7 +549,10 @@ class flexible_table {
             $this->baseurl = $PAGE->url;
         }
 
-        $this->currpage = optional_param($this->request[TABLE_VAR_PAGE], 0, PARAM_INT);
+        if ($this->currpage == null) {
+            $this->currpage = optional_param($this->request[TABLE_VAR_PAGE], 0, PARAM_INT);
+        }
+
         $this->setup = true;
 
         // Always introduce the "flexible" class for the table if not specified
@@ -1406,6 +1409,15 @@ class flexible_table {
         $this->ilast = $initial;
     }
 
+    /**
+     * Set the page number.
+     *
+     * @param int $pagenumber The page number.
+     */
+    public function set_page_number(int $pagenumber): void {
+        $this->currpage = $pagenumber - 1;
+    }
+
     /**
      * Generate the HTML for the sort icon. This is a helper method used by {@link sort_link()}.
      * @param bool $isprimary whether an icon is needed (it is only needed for the primary sort column.)
@@ -1505,6 +1517,8 @@ class flexible_table {
                 'data-table-sort-order' => $sortdata['sortorder'],
                 'data-table-first-initial' => $this->prefs['i_first'],
                 'data-table-last-initial' => $this->prefs['i_last'],
+                'data-table-page-number' => $this->currpage + 1,
+                'data-table-page-size' => $this->pagesize,
             ]);
         }
 
@@ -1810,6 +1824,7 @@ class table_sql extends flexible_table {
             $this->define_columns(array_keys((array)$onerow));
             $this->define_headers(array_keys((array)$onerow));
         }
+        $this->pagesize = $pagesize;
         $this->setup();
         $this->query_db($pagesize, $useinitialsbar);
         $this->build_table();
index 735b5cf..56a793c 100644 (file)
@@ -1,8 +1,8 @@
 {{#haspages}}
     <nav aria-label="{{label}}" class="pagination pagination-centered justify-content-center">
-        <ul class="mt-1 pagination ">
+        <ul class="mt-1 pagination " data-page-size="{{pagesize}}">
             {{#previous}}
-                <li class="page-item">
+                <li class="page-item" data-page-number="{{page}}">
                     <a href="{{url}}" class="page-link" aria-label="Previous">
                         <span aria-hidden="true">&laquo;</span>
                         <span class="sr-only">{{#str}}previous{{/str}}</span>
                 </li>
             {{/previous}}
             {{#first}}
-                <li class="page-item">
+                <li class="page-item" data-page-number="{{page}}">
                     <a href="{{url}}" class="page-link">{{page}}</a>
                 </li>
-                <li class="page-item disabled">
+                <li class="page-item disabled" data-page-number="{{page}}">
                     <span class="page-link">&hellip;</a>
                 </li>
             {{/first}}
             {{#pages}}
-                <li class="page-item {{#active}}active{{/active}}">
+                <li class="page-item {{#active}}active{{/active}}" data-page-number="{{page}}">
                     <a href="{{#url}}{{.}}{{/url}}{{^url}}#{{/url}}" class="page-link">
                         {{page}}
                         {{#active}}
                 </li>
             {{/pages}}
             {{#last}}
-                <li class="page-item disabled">
+                <li class="page-item disabled" data-page-number="{{page}}">
                     <span class="page-link">&hellip;</a>
                 </li>
-                <li class="page-item">
+                <li class="page-item" data-page-number="{{page}}">
                     <a href="{{url}}" class="page-link">{{page}}</a>
                 </li>
             {{/last}}
             {{#next}}
-                <li class="page-item">
+                <li class="page-item" data-page-number="{{page}}">
                     <a href="{{url}}" class="page-link" aria-label="Next">
                         <span aria-hidden="true">&raquo;</span>
                         <span class="sr-only">{{#str}}next{{/str}}</span>