diff --git a/grade/report/singleview/classes/local/screen/grade.php b/grade/report/singleview/classes/local/screen/grade.php
index 25d51669ffc..cccef5ca812 100644
--- a/grade/report/singleview/classes/local/screen/grade.php
+++ b/grade/report/singleview/classes/local/screen/grade.php
@@ -158,6 +158,16 @@ class grade extends tablelike implements selectable_items, filterable_items {
return;
}
+ // If we change perpage on pagination we might end up with a page that doesn't exist.
+ if ($this->perpage) {
+ $numpages = intval($this->totalitemcount / $this->perpage) + 1;
+ if ($numpages <= $this->page) {
+ $this->page = 0;
+ }
+ } else {
+ $this->page = 0;
+ }
+
$params = [
'id' => $this->itemid,
'courseid' => $this->courseid
diff --git a/grade/report/singleview/classes/local/screen/screen.php b/grade/report/singleview/classes/local/screen/screen.php
index 1ef3ab51d50..47c16c839aa 100644
--- a/grade/report/singleview/classes/local/screen/screen.php
+++ b/grade/report/singleview/classes/local/screen/screen.php
@@ -85,11 +85,14 @@ abstract class screen {
*/
protected $items;
+ /** @var int Maximum number of students that can be shown on one page */
+ protected static $maxperpage = 5000;
+
/**
* List of allowed values for 'perpage' setting
* @var array $validperpage
*/
- protected static $validperpage = [20, 50, 100, 200, 400, 1000, 5000];
+ protected static $validperpage = [20, 100];
/**
* To store course data
@@ -124,17 +127,19 @@ abstract class screen {
$cache = \cache::make_from_params(\cache_store::MODE_SESSION, 'gradereport_singleview', 'perpage');
$perpage = optional_param('perpage', null, PARAM_INT);
- if (!in_array($perpage, self::$validperpage)) {
+ if (!in_array($perpage, self::$validperpage) && ($perpage !== 0)) {
// Get from cache.
$perpage = $cache->get(get_class($this));
} else {
// Save to cache.
$cache->set(get_class($this), $perpage);
}
- if ($perpage) {
+ if (isset($perpage) && $perpage) {
$this->perpage = $perpage;
} else {
- $this->perpage = 100;
+ // Get from cache.
+ $perpage = $cache->get(get_class($this));
+ $this->perpage = ($perpage === 0) ? $perpage : min(self::$validperpage);
}
$this->init(empty($itemid));
@@ -423,16 +428,37 @@ abstract class screen {
public function perpage_select(): string {
global $PAGE, $OUTPUT;
- $options = array_combine(self::$validperpage, self::$validperpage);
-
$url = new moodle_url($PAGE->url);
- $url->remove_params(['page', 'perpage']);
+ $numusers = count($this->items);
+ // Print per-page dropdown.
+ $pagingoptions = self::$validperpage;
+ if ($this->perpage) {
+ $pagingoptions[] = $this->perpage; // To make sure the current preference is within the options.
+ }
+ $pagingoptions = array_unique($pagingoptions);
+ sort($pagingoptions);
+ $pagingoptions = array_combine($pagingoptions, $pagingoptions);
+ if ($numusers > self::$maxperpage) {
+ $pagingoptions['0'] = self::$maxperpage;
+ } else {
+ $pagingoptions['0'] = get_string('all');
+ }
- $out = '';
- $select = new \single_select($url, 'perpage', $options, $this->perpage, null, 'perpagechanger');
- $select->label = get_string('itemsperpage', 'gradereport_singleview');
- $out .= $OUTPUT->render($select);
+ $perpagedata = [
+ 'baseurl' => $url->out(false),
+ 'options' => []
+ ];
+ foreach ($pagingoptions as $key => $name) {
+ $perpagedata['options'][] = [
+ 'name' => $name,
+ 'value' => $key,
+ 'selected' => $key == $this->perpage,
+ ];
+ }
- return $out;
+ // The number of students per page is always limited even if it is claimed to be unlimited.
+ $this->perpage = $this->perpage ?: self::$maxperpage;
+ $perpagedata['pagingbar'] = $this->pager();
+ return $OUTPUT->render_from_template('gradereport_singleview/perpage', $perpagedata);;
}
}
diff --git a/grade/report/singleview/classes/local/screen/tablelike.php b/grade/report/singleview/classes/local/screen/tablelike.php
index 4c408a78307..bd82fd7ae4f 100644
--- a/grade/report/singleview/classes/local/screen/tablelike.php
+++ b/grade/report/singleview/classes/local/screen/tablelike.php
@@ -194,6 +194,7 @@ abstract class tablelike extends screen implements be_readonly {
return $warnings;
}
$table = new html_table();
+ $table->id = 'singleview-grades';
$table->head = $this->headers();
@@ -219,17 +220,7 @@ abstract class tablelike extends screen implements be_readonly {
$data->table = $table;
$data->instance = $this;
- $buttonattr = ['class' => 'singleview_buttons submit'];
- $buttonhtml = implode(' ', $this->buttons($this->is_readonly()));
- $buttons = html_writer::tag('div', $buttonhtml, $buttonattr);
-
- $sessionvalidation = html_writer::empty_tag('input',
- ['type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()]);
-
- $html = html_writer::tag('form',
- html_writer::table($table) . $this->bulk_insert() . $buttons . $sessionvalidation,
- ['method' => 'POST']
- );
+ $html = html_writer::table($table);
return html_writer::div($html, 'reporttable');
}
diff --git a/grade/report/singleview/classes/local/screen/user.php b/grade/report/singleview/classes/local/screen/user.php
index 782e01f16fc..2cdbd92b2d2 100644
--- a/grade/report/singleview/classes/local/screen/user.php
+++ b/grade/report/singleview/classes/local/screen/user.php
@@ -121,6 +121,16 @@ class user extends tablelike implements selectable_items {
}
}
+ // If we change perpage on pagination we might end up with a page that doesn't exist.
+ if ($this->perpage) {
+ $numpages = intval(count($this->items) / $this->perpage) + 1;
+ if ($numpages <= $this->page) {
+ $this->page = 0;
+ }
+ } else {
+ $this->page = 0;
+ }
+
$this->requirespaging = count($this->items) > $this->perpage;
$this->setup_structure();
diff --git a/grade/report/singleview/index.php b/grade/report/singleview/index.php
index 4569e3cbf51..b8dfb2b2d70 100644
--- a/grade/report/singleview/index.php
+++ b/grade/report/singleview/index.php
@@ -36,7 +36,7 @@ $userid = optional_param('userid', null, PARAM_INT);
$itemid = optional_param('itemid', null, PARAM_INT);
$itemtype = optional_param('item', null, PARAM_TEXT);
$page = optional_param('page', 0, PARAM_INT);
-$perpage = optional_param('perpage', 100, PARAM_INT);
+$perpage = optional_param('perpage', null, PARAM_INT);
$edit = optional_param('edit', -1, PARAM_BOOL); // Sticky editing mode.
@@ -203,13 +203,13 @@ if ($data = data_submitted()) {
// Make sure we have proper final grades.
grade_regrade_final_grades_if_required($course);
-echo $report->output();
// Save the screen state in a session variable as last viewed state.
$SESSION->gradereport_singleview["itemtype-{$context->id}"] = $itemtype;
if ($itemid) {
$SESSION->gradereport_singleview["{$itemtype}item-{$context->id}"] = $itemid;
}
+$stickyfooter = '';
if (($itemtype !== 'select') && ($itemtype !== 'grade_select') &&($itemtype !== 'user_select')) {
$item = (isset($userid)) ? $userid : $itemid;
@@ -223,9 +223,21 @@ if (($itemtype !== 'select') && ($itemtype !== 'grade_select') &&($itemtype !==
$userreportrenderer = $PAGE->get_renderer('gradereport_singleview');
// Add previous/next user navigation.
- echo $userreportrenderer->report_navigation($gpr, $courseid, $context, $report, $groupid, $itemtype, $itemid);
+ $footercontent = $userreportrenderer->report_navigation($gpr, $courseid, $context, $report, $groupid, $itemtype, $itemid);
+
+ $buttonhtml = implode(' ', $report->screen->buttons($report->screen->is_readonly()));
+ $footercontent .= $report->screen->bulk_insert() . $buttonhtml;
+
+ $stickyfooter = new core\output\sticky_footer($footercontent);
+ $stickyfooter = $OUTPUT->render($stickyfooter);
+
}
+echo $OUTPUT->render_from_template('gradereport_singleview/report', [
+ 'table' => $report->output(),
+ 'stickyfooter' => $stickyfooter,
+ 'sesskey' => sesskey()
+]);
$event = \gradereport_singleview\event\grade_report_viewed::create(
[
'context' => $context,
diff --git a/grade/report/singleview/renderer.php b/grade/report/singleview/renderer.php
index c4fd5d7638d..9bf1f5afb44 100644
--- a/grade/report/singleview/renderer.php
+++ b/grade/report/singleview/renderer.php
@@ -152,7 +152,6 @@ class gradereport_singleview_renderer extends plugin_renderer_base {
if ($report->screen->supports_paging()) {
$navigationdata['perpageselect'] = $report->screen->perpage_select();
- $navigationdata['pager'] = $report->screen->pager();
}
if (isset($navigationdata)) {
diff --git a/grade/report/singleview/styles.css b/grade/report/singleview/styles.css
index 9d02f09f702..7623fd2e516 100644
--- a/grade/report/singleview/styles.css
+++ b/grade/report/singleview/styles.css
@@ -6,7 +6,6 @@
}
.path-grade-report-singleview div.groupselector,
-.path-grade-report-singleview div.reporttable form div.singleview_buttons,
.path-grade-report-singleview div.selectitems {
display: block;
text-align: right;
@@ -30,10 +29,6 @@
text-align: left;
}
-.path-grade-report-singleview .singleview_buttons {
- padding: 10px 0;
-}
-
.path-grade-report-singleview div.reporttable h2 {
text-align: left;
}
diff --git a/grade/report/singleview/templates/button.mustache b/grade/report/singleview/templates/button.mustache
index 5252ab5a4ca..12dc2d90f34 100644
--- a/grade/report/singleview/templates/button.mustache
+++ b/grade/report/singleview/templates/button.mustache
@@ -25,4 +25,4 @@
"value": "Save"
}
}}
-
+
diff --git a/grade/report/singleview/templates/perpage.mustache b/grade/report/singleview/templates/perpage.mustache
new file mode 100644
index 00000000000..d74cf73a45a
--- /dev/null
+++ b/grade/report/singleview/templates/perpage.mustache
@@ -0,0 +1,58 @@
+{{!
+ This file is part of Moodle - http://moodle.org/
+
+ Moodle is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Moodle is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Moodle. If not, see
| Name | User fullname | Grade | Actions |
|---|