MDL-87304 mod_data: Remove sticky footer in view/edit

* Move pagination at the bottom of the view
* Move edit save button at the bottom of the form
This commit is contained in:
Laurent David
2026-01-27 13:39:20 +01:00
parent b3cd83bd48
commit e6ce408bbc
9 changed files with 106 additions and 109 deletions
+31 -12
View File
@@ -33,12 +33,12 @@ class action_bar {
/** @var int $id The database module id. */
private $id;
/** @var int $cmid The database course module id. */
private $cmid;
/** @var moodle_url $currenturl The URL of the current page. */
private $currenturl;
/** @var \cm_info $cm the course module. */
private $cm;
/**
* The class constructor.
*
@@ -48,7 +48,7 @@ class action_bar {
public function __construct(int $id, moodle_url $pageurl) {
$this->id = $id;
[$course, $cm] = get_course_and_cm_from_instance($this->id, 'data');
$this->cmid = $cm->id;
$this->cm = $cm;
$this->currenturl = $pageurl;
}
@@ -111,7 +111,7 @@ class action_bar {
$triggerclasses = ['btn'];
$triggerclasses[] = $isprimarybutton ? 'btn-primary' : 'btn-secondary';
$fieldselect->set_menu_trigger(get_string('newfield', 'mod_data'), join(' ', $triggerclasses));
$fieldselectparams = ['id' => $this->cmid, 'mode' => 'new'];
$fieldselectparams = ['id' => $this->cm->id, 'mode' => 'new'];
foreach ($menufield as $fieldtype => $fieldname) {
$fieldselectparams['newtype'] = $fieldtype;
$fieldselect->add(new \action_menu_link(
@@ -135,10 +135,9 @@ class action_bar {
*/
public function get_view_action_bar(bool $hasentries, string $mode): string {
global $PAGE;
$viewlistlink = new moodle_url('/mod/data/view.php', ['d' => $this->id]);
$viewsinglelink = new moodle_url('/mod/data/view.php', ['d' => $this->id, 'mode' => 'single']);
$manager = manager::create_from_coursemodule($this->cm);
$menu = [
$viewlistlink->out(false) => get_string('listview', 'mod_data'),
$viewsinglelink->out(false) => get_string('singleview', 'mod_data'),
@@ -152,8 +151,28 @@ class action_bar {
$urlselect = new url_select($menu, $activeurl->out(false), null, 'viewactionselect');
$urlselect->set_label(get_string('viewnavigation', 'mod_data'), ['class' => 'visually-hidden']);
$cm = $manager->get_coursemodule();
$instance = $manager->get_instance();
$currentgroup = groups_get_activity_group($cm);
$groupmode = groups_get_activity_groupmode($cm);
$context = $manager->get_context();
if (data_user_can_add_entry($instance, $currentgroup, $groupmode, $context)) {
$backtourl = new moodle_url($this->currenturl);
$backtourl->param('mode', $mode);
$addentrylink = new moodle_url(
'/mod/data/edit.php',
['id' => $this->cm->id, 'backto' => $backtourl]
);
$addentrybutton = new \core\output\action_link(
$addentrylink,
get_string('add', 'mod_data'),
null,
['class' => 'btn btn-primary mx-1', 'role' => 'button']
);
}
$renderer = $PAGE->get_renderer('mod_data');
$viewactionbar = new view_action_bar($this->id, $urlselect, $hasentries, $mode);
$viewactionbar = new view_action_bar($this->id, $urlselect, $hasentries, $mode, $addentrybutton ?? null);
return $renderer->render_view_action_bar($viewactionbar);
}
@@ -233,7 +252,7 @@ class action_bar {
global $PAGE;
$renderer = $PAGE->get_renderer('mod_data');
$presetsactionbar = new presets_action_bar($this->cmid, $this->get_presets_actions_select(true));
$presetsactionbar = new presets_action_bar($this->cm->id, $this->get_presets_actions_select(true));
return $renderer->render_presets_action_bar($presetsactionbar);
}
@@ -302,20 +321,20 @@ class action_bar {
if ($hasimport) {
// Import.
$actionsselectparams = ['id' => $this->cmid];
$actionsselectparams = ['id' => $this->cm->id];
$actionsselect->add(new \action_menu_link(
new moodle_url('/mod/data/preset.php', $actionsselectparams),
null,
get_string('importpreset', 'mod_data'),
false,
['data-action' => 'importpresets', 'data-dataid' => $this->cmid]
['data-action' => 'importpresets', 'data-dataid' => $this->cm->id]
));
}
// If the database has no fields, export and save as preset options shouldn't be displayed.
if ($hasfields) {
// Export.
$actionsselectparams = ['id' => $this->cmid, 'action' => 'export'];
$actionsselectparams = ['id' => $this->cm->id, 'action' => 'export'];
$actionsselect->add(new \action_menu_link(
new moodle_url('/mod/data/preset.php', $actionsselectparams),
null,
@@ -16,6 +16,7 @@
namespace mod_data\output;
use core\output\action_link;
use data_portfolio_caller;
use mod_data\manager;
use moodle_url;
@@ -44,6 +45,9 @@ class view_action_bar implements templatable, renderable {
/** @var bool $mode The current view mode (list, view...). */
private $mode;
/** @var action_link|null $addentrylink The add entry link */
private ?action_link $addentrylink = null;
/**
* The class constructor.
*
@@ -51,12 +55,20 @@ class view_action_bar implements templatable, renderable {
* @param \url_select $urlselect The URL selector object.
* @param bool $hasentries Whether entries exist.
* @param string $mode The current view mode (list, view...).
* @param action_link|null $addentrylink The add entry link
*/
public function __construct(int $id, \url_select $urlselect, bool $hasentries, string $mode) {
public function __construct(
int $id,
\url_select $urlselect,
bool $hasentries,
string $mode,
?action_link $addentrylink = null
) {
$this->id = $id;
$this->urlselect = $urlselect;
$this->hasentries = $hasentries;
$this->mode = $mode;
$this->addentrylink = $addentrylink;
}
/**
@@ -142,7 +154,9 @@ class view_action_bar implements templatable, renderable {
if ($actionsselect) {
$data['actionsselect'] = $actionsselect->export_for_template($output);
}
if ($this->addentrylink) {
$data['addentrybutton'] = $this->addentrylink->export_for_template($output);
}
return $data;
}
}
+5 -37
View File
@@ -16,8 +16,8 @@
namespace mod_data\output;
use action_link;
use core\output\sticky_footer;
use core\output\renderable;
use core\output\templatable;
use html_writer;
use mod_data\manager;
use mod_data\template;
@@ -25,14 +25,13 @@ use moodle_url;
use renderer_base;
/**
* Renderable class for sticky footer in the view pages of the database activity.
* Renderable class for footer in the view pages of the database activity.
*
* @package mod_data
* @copyright 2022 Ferran Recio <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_footer extends sticky_footer {
class view_footer implements renderable, templatable {
/** @var int $totalcount the total records count. */
private $totalcount;
@@ -84,30 +83,12 @@ class view_footer extends sticky_footer {
* @return array data context for a mustache template
*/
public function export_for_template(renderer_base $output) {
$this->set_content(
$this->get_footer_output($output)
);
return parent::export_for_template($output);
}
/**
* Generate the pre-rendered footer content.
*
* @param \renderer_base $output The renderer to be used to render the action bar elements.
* @return string the rendered content
*/
public function get_footer_output(renderer_base $output): string {
$data = [];
$cm = $this->manager->get_coursemodule();
$instance = $this->manager->get_instance();
$currentgroup = groups_get_activity_group($cm);
$groupmode = groups_get_activity_groupmode($cm);
$context = $this->manager->get_context();
$canmanageentries = has_capability('mod/data:manageentries', $context);
$parser = $this->parser;
// Sticky footer content.
$data['pagination'] = $output->paging_bar(
$this->totalcount,
$this->currentpage,
@@ -138,19 +119,6 @@ class view_footer extends sticky_footer {
'data-toggle' => 'action',
]);
}
if (data_user_can_add_entry($instance, $currentgroup, $groupmode, $context)) {
$addentrylink = new moodle_url(
'/mod/data/edit.php',
['id' => $cm->id, 'backto' => $this->baseurl]
);
$addentrybutton = new action_link(
$addentrylink,
get_string('add', 'mod_data'),
null,
['class' => 'btn btn-primary mx-1', 'role' => 'button']
);
$data['addentrybutton'] = $addentrybutton->export_for_template($output);
}
return $output->render_from_template('mod_data/view_footer', $data);
return $data;
}
}
+22 -16
View File
@@ -198,29 +198,35 @@ if (empty($redirectbackto)) {
$redirectbackto = new \moodle_url('/mod/data/view.php', ['id' => $cm->id]);
}
$actionbuttons = html_writer::link(
$redirectbackto,
get_string('cancel'),
['class' => 'btn btn-secondary mx-1', 'role' => 'button']
);
$actionbuttons = '';
if (
!$rid && (
(!$data->maxentries) ||
has_capability('mod/data:manageentries', $context) ||
(data_numentries($data) < ($data->maxentries - 1))
)
) {
$actionbuttons .= html_writer::empty_tag('input', [
'type' => 'submit',
'name' => 'saveandadd',
'value' => get_string('saveandadd', 'data'),
'class' => 'btn btn-primary mx-1',
]);
}
$actionbuttons .= html_writer::empty_tag('input', [
'type' => 'submit',
'name' => 'saveandview',
'value' => get_string('save'),
'class' => 'btn btn-primary mx-1'
'class' => 'btn btn-primary mx-1',
]);
if (!$rid && ((!$data->maxentries) ||
has_capability('mod/data:manageentries', $context) ||
(data_numentries($data) < ($data->maxentries - 1)))) {
$actionbuttons .= html_writer::empty_tag('input', [
'type' => 'submit', 'name' => 'saveandadd',
'value' => get_string('saveandadd', 'data'), 'class' => 'btn btn-primary mx-1'
]);
}
$actionbuttons .= html_writer::link(
$redirectbackto,
get_string('cancel'),
['class' => 'btn btn-secondary mx-1', 'role' => 'button']
);
$stickyfooter = new core\output\sticky_footer($actionbuttons);
echo $OUTPUT->render($stickyfooter);
echo html_writer::div($actionbuttons, 'mt-2');
echo $OUTPUT->box_end();
echo '</div></form>';
-4
View File
@@ -201,7 +201,3 @@
border-color: var(--bs-primary);
color: var(--bs-primary);
}
#page-mod-data-preset .table {
margin-bottom: 10rem;
}
@@ -14,7 +14,7 @@
{{!
@template mod_data/fields_footer
The mod_data fields sticky footer content.
The mod_data fields footer content.
Example context (json):
{
@@ -22,6 +22,18 @@
Example context (json):
{
"addentrybutton": {
"disabled": false,
"url": "#",
"id": "test-id",
"classes": "btn btn-link",
"attributes": [
{
"name": "title",
"value": "Add entry"
}
]
},
"urlselect": {
"id": "url_select_test",
"action": "https://example.com/post",
@@ -81,28 +93,28 @@
}
}
}}
<div class="container-fluid tertiary-navigation d-flex">
<div class="row ms-auto">
<div class="container-fluid tertiary-navigation px-0">
<div class="row justify-content-between">
<div class="col">
{{#addentrybutton}}
<div class="navitem mb-0">
{{>core/single_button}}
</div>
{{/addentrybutton}}
<div class="d-flex">
{{#urlselect}}
<div class="navitem">
{{>core/url_select}}
</div>
{{/urlselect}}
</div>
</div>
<div class="col">
{{#urlselect}}
<div class="navitem mb-0">
{{>core/url_select}}
</div>
{{/urlselect}}
</div>
<div class="col">
<div class="col d-flex justify-content-end">
{{#actionsselect}}
<div class='navitem mb-0 entriesactions'>
{{>core/action_menu}}
</div>
{{/actionsselect}}
{{#addentrybutton}}
<div class="navitem">
{{>core/action_link}}
</div>
{{/addentrybutton}}
</div>
</div>
</div>
+2 -20
View File
@@ -14,26 +14,13 @@
{{!
@template mod_data/view_footer
The mod_data sticky footer content.
The mod_data footer content.
Example context (json):
{
"selectall": "<button>Select all</button>",
"deleteselected": "<button>Cancel selection</button>",
"pagination": "1, 2, 3...",
"addentrybutton": {
"disabled": false,
"url": "#",
"id": "test-id",
"classes": "btn btn-link",
"attributes": [
{
"name": "title",
"value": "Add entry"
}
],
"text": "Add"
}
"pagination": "1, 2, 3..."
}
}}
{{#selectall}}
@@ -45,8 +32,3 @@
<div class="navitem submit mx-auto">
{{{pagination}}}
</div>
{{#addentrybutton}}
<div class="navitem">
{{> core/action_link}}
</div>
{{/addentrybutton}}
+2 -2
View File
@@ -521,7 +521,7 @@ if ($showactivity) {
echo $OUTPUT->box_end();
}
$stickyfooter = new mod_data\output\view_footer(
$viewfooter = new mod_data\output\view_footer(
$manager,
$totalcount,
$page,
@@ -529,7 +529,7 @@ if ($showactivity) {
$baseurl,
$parser
);
echo $OUTPUT->render($stickyfooter);
echo $OUTPUT->render($viewfooter);
echo html_writer::end_tag('form');
}