MDL-80386 core_question: Add "show all" button to filters.
This adds the "Show All" button to the question bank filters to allow users to select all questions easily. It also adds new behat tests to test the functionality.
This commit is contained in:
@@ -36,7 +36,8 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"showallbutton": false
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -52,7 +53,10 @@
|
||||
<button type="button" class="btn btn-link text-reset" data-filteraction="add">
|
||||
{{#pix}}t/add{{/pix}}<span class="pl-3">{{#str}}addcondition{{/str}}</span>
|
||||
</button>
|
||||
<button data-filteraction="reset" type="button" class="btn btn-secondary ml-auto mr-2">{{#str}}clearfilters{{/str}}</button>
|
||||
{{#showallbutton}}
|
||||
<button data-filteraction="showall" data-perpage="{{ perpage }}" data-status="0" type="button" class="btn btn-light ml-auto mr-2">{{#str}}showall{{/str}}</button>
|
||||
{{/showallbutton}}
|
||||
<button data-filteraction="reset" type="button" class="btn btn-secondary {{^showallbutton}}ml-auto{{/showallbutton}} mr-2">{{#str}}clearfilters{{/str}}</button>
|
||||
<button data-filteraction="apply" type="button" class="btn btn-primary">{{#str}}applyfilters{{/str}}</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -83,10 +83,10 @@ class custom_view extends \core_question\local\bank\view {
|
||||
}
|
||||
|
||||
$this->init_columns($this->wanted_columns(), $this->heading_column());
|
||||
$this->pagesize = self::DEFAULT_PAGE_SIZE;
|
||||
parent::__construct($contexts, $pageurl, $course, $cm, $params, $extraparams);
|
||||
[$this->quiz, ] = get_module_from_cmid($cm->id);
|
||||
$this->set_quiz_has_attempts(quiz_has_attempts($this->quiz->id));
|
||||
$this->pagesize = self::DEFAULT_PAGE_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -26,6 +26,8 @@ import Notification from 'core/notification';
|
||||
import Selectors from 'core/datafilter/selectors';
|
||||
import Templates from 'core/templates';
|
||||
import Fragment from 'core/fragment';
|
||||
import {getString} from 'core/str';
|
||||
import {addIconToContainerRemoveOnCompletion} from 'core/loadingicon';
|
||||
|
||||
/**
|
||||
* Initialise the question bank filter on the element with the given id.
|
||||
@@ -42,7 +44,7 @@ import Fragment from 'core/fragment';
|
||||
* @param {Object} pagevars JSON-encoded parameters from passed from the view, including filters and jointype.
|
||||
* @param {Object} extraparams JSON-encoded additional parameters specific to this view class, used for re-rendering the view.
|
||||
*/
|
||||
export const init = (
|
||||
export const init = async(
|
||||
filterRegionId,
|
||||
defaultcourseid,
|
||||
defaultcategoryid,
|
||||
@@ -66,10 +68,19 @@ export const init = (
|
||||
MENU_ACTIONS: '.menu-action',
|
||||
EDIT_SWITCH: '.editmode-switch-form input[name=setmode]',
|
||||
EDIT_SWITCH_URL: '.editmode-switch-form input[name=pageurl]',
|
||||
SHOW_ALL_LINK: '[data-filteraction="showall"]',
|
||||
};
|
||||
|
||||
const filterSet = document.querySelector(`#${filterRegionId}`);
|
||||
|
||||
const [
|
||||
showAllText,
|
||||
showPerPageText,
|
||||
] = await Promise.all([
|
||||
getString('showall', 'core', ''),
|
||||
getString('showperpage', 'core', extraparams.defaultqperpage),
|
||||
]);
|
||||
|
||||
const viewData = {
|
||||
extraparams: JSON.stringify(extraparams),
|
||||
cmid,
|
||||
@@ -115,10 +126,15 @@ export const init = (
|
||||
// Load questions for first page.
|
||||
viewData.filter = JSON.stringify(filterdata);
|
||||
viewData.sortdata = JSON.stringify(sortData);
|
||||
|
||||
const questionscontainer = document.querySelector(SELECTORS.QUESTION_CONTAINER_ID);
|
||||
// Clear the contents of the element, then append the loading icon.
|
||||
questionscontainer.innerHTML = '';
|
||||
addIconToContainerRemoveOnCompletion(questionscontainer, pendingPromise);
|
||||
|
||||
Fragment.loadFragment(component, callback, contextId, viewData)
|
||||
// Render questions for first page and pagination.
|
||||
.then((questionhtml, jsfooter) => {
|
||||
const questionscontainer = document.querySelector(SELECTORS.QUESTION_CONTAINER_ID);
|
||||
if (questionhtml === undefined) {
|
||||
questionhtml = '';
|
||||
}
|
||||
@@ -180,10 +196,11 @@ export const init = (
|
||||
};
|
||||
|
||||
// Add listeners for the sorting, paging and clear actions.
|
||||
document.addEventListener('click', e => {
|
||||
document.querySelector('.questionbankwindow').addEventListener('click', e => {
|
||||
const sortableLink = e.target.closest(SELECTORS.SORT_LINK);
|
||||
const paginationLink = e.target.closest(SELECTORS.PAGINATION_LINK);
|
||||
const clearLink = e.target.closest(Selectors.filterset.actions.resetFilters);
|
||||
const showallLink = e.target.closest(SELECTORS.SHOW_ALL_LINK);
|
||||
if (sortableLink) {
|
||||
e.preventDefault();
|
||||
const oldSort = sortData;
|
||||
@@ -209,6 +226,23 @@ export const init = (
|
||||
if (clearLink) {
|
||||
cleanUrlParams();
|
||||
}
|
||||
if (showallLink) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
// Toggle between showing all and going back to the original qperpage.
|
||||
if (Number(showallLink.dataset.status) === 0) {
|
||||
viewData.qperpage = extraparams.maxqperpage;
|
||||
showallLink.dataset.status = 1;
|
||||
showallLink.innerText = showPerPageText;
|
||||
} else {
|
||||
viewData.qperpage = extraparams.defaultqperpage;
|
||||
showallLink.dataset.status = 0;
|
||||
showallLink.innerText = showAllText;
|
||||
}
|
||||
viewData.qpage = 0;
|
||||
coreFilter.updateTableFromFilter();
|
||||
}
|
||||
});
|
||||
|
||||
// Run apply filter at page load.
|
||||
|
||||
@@ -235,6 +235,10 @@ class view {
|
||||
$this->cm = $cm;
|
||||
$this->extraparams = $extraparams;
|
||||
|
||||
// Add the default qperpage to extra params array so we can switch back and forth between it and "all".
|
||||
$this->extraparams['defaultqperpage'] = $this->pagesize;
|
||||
$this->extraparams['maxqperpage'] = MAXIMUM_QUESTIONS_PER_PAGE;
|
||||
|
||||
// Default filter condition.
|
||||
if (!isset($params['filter']) && isset($params['cat'])) {
|
||||
$params['filter'] = [];
|
||||
@@ -811,15 +815,18 @@ class view {
|
||||
*/
|
||||
protected function load_page_questions(): \moodle_recordset {
|
||||
global $DB;
|
||||
|
||||
// Load the questions based on the page we are on.
|
||||
$questions = $DB->get_recordset_sql($this->loadsql, $this->sqlparams,
|
||||
(int)$this->pagevars['qpage'] * (int)$this->pagevars['qperpage'], $this->pagevars['qperpage']);
|
||||
(int)$this->pagevars['qpage'] * (int)$this->pagevars['qperpage'], (int)$this->pagevars['qperpage']);
|
||||
|
||||
if (!$questions->valid()) {
|
||||
$questions->close();
|
||||
// No questions on this page. Reset to the nearest page that contains questions.
|
||||
$this->pagevars['qpage'] = max(0,
|
||||
ceil($this->totalcount / $this->pagevars['qperpage']) - 1);
|
||||
ceil($this->totalcount / (int)$this->pagevars['qperpage']) - 1);
|
||||
$questions = $DB->get_recordset_sql($this->loadsql, $this->sqlparams,
|
||||
$this->pagevars['qpage'] * (int) $this->pagevars['qperpage'], $this->pagevars['qperpage']);
|
||||
(int)$this->pagevars['qpage'] * (int)$this->pagevars['qperpage'], (int)$this->pagevars['qperpage']);
|
||||
}
|
||||
return $questions;
|
||||
}
|
||||
@@ -1155,6 +1162,7 @@ class view {
|
||||
// We probably do not want to raise it to unlimited, so randomly picking 5 minutes.
|
||||
// Note: We do not call this in the loop because quiz ob_ captures this function (see raise() PHP doc).
|
||||
\core_php_time_limit::raise(300);
|
||||
raise_memory_limit(MEMORY_EXTRA);
|
||||
|
||||
[$categoryid, $contextid] = category_condition::validate_category_param($this->pagevars['cat']);
|
||||
$catcontext = \context::instance_by_id($contextid);
|
||||
|
||||
@@ -137,6 +137,7 @@ class question_bank_filter_ui extends datafilter {
|
||||
'cmid' => $this->cmid ?? 0,
|
||||
'pagevars' => json_encode($this->pagevars),
|
||||
'extraparams' => json_encode($this->extraparams),
|
||||
'showallbutton' => true,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
@core @core_question @qbank_filter @javascript
|
||||
Feature: A teacher can show all of the questions on the question bank and override pagination
|
||||
In order to see all the questions in the question bank
|
||||
As a teacher
|
||||
I must be able to toggle between show all and show paginated
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | format |
|
||||
| Course 1 | C1 | topics |
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber |
|
||||
| quiz | Test quiz | C1 | quiz1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And the following "question categories" exist:
|
||||
| contextlevel | reference | questioncategory | name |
|
||||
| Course | C1 | Top | Test Category |
|
||||
Given 201 "questions" exist with the following data:
|
||||
| questioncategory | Test Category |
|
||||
| qtype | truefalse |
|
||||
| name | Question #[count] |
|
||||
| questiontext | True or false? |
|
||||
|
||||
Scenario: Use "Show All" button on the question bank when there are no questions
|
||||
Given I am on the "Course 1" "core_question > course question bank" page logged in as "teacher1"
|
||||
When I apply question bank filter "Category" with value "Default for C1"
|
||||
Then I should not see "Question #"
|
||||
And I click on "Show all" "button"
|
||||
Then I should not see "Question #"
|
||||
And I click on "Show 100 per page" "button"
|
||||
Then I should not see "Question #"
|
||||
|
||||
Scenario: Question bank shows paginated questions by default
|
||||
Given I am on the "Course 1" "core_question > course question bank" page logged in as "teacher1"
|
||||
When I apply question bank filter "Category" with value "Top for Course 1"
|
||||
Then I should see "100" occurrences of "Question #" in the "div#questionscontainer" "css_element"
|
||||
And I should see "1" in the ".pagination" "css_element"
|
||||
And I should see "2" in the ".pagination" "css_element"
|
||||
And I should see "3" in the ".pagination" "css_element"
|
||||
|
||||
Scenario: Toggle "Show all" shows all questions
|
||||
Given I am on the "Course 1" "core_question > course question bank" page logged in as "teacher1"
|
||||
When I apply question bank filter "Category" with value "Top for Course 1"
|
||||
And I click on "Show all" "button"
|
||||
Then I should see "201" occurrences of "Question #" in the "div#questionscontainer" "css_element"
|
||||
And ".pagination" "css_element" should not exist
|
||||
And I should see "Show 100 per page"
|
||||
|
||||
Scenario: Toggle "Show all" back to paginated shows paginated questions
|
||||
Given I am on the "Course 1" "core_question > course question bank" page logged in as "teacher1"
|
||||
When I apply question bank filter "Category" with value "Top for Course 1"
|
||||
And I click on "Show all" "button"
|
||||
And I click on "Show 100 per page" "button"
|
||||
Then I should see "100" occurrences of "Question #" in the "div#questionscontainer" "css_element"
|
||||
And I should see "1" in the ".pagination" "css_element"
|
||||
And I should see "2" in the ".pagination" "css_element"
|
||||
And I should see "3" in the ".pagination" "css_element"
|
||||
And I should see "Show all"
|
||||
|
||||
Scenario: Show all questions on the question bank when adding questions to a quiz
|
||||
Given I am on the "Test quiz" "mod_quiz > Edit" page logged in as "teacher1"
|
||||
When I open the "last" add to quiz menu
|
||||
And I follow "from question bank"
|
||||
And I apply question bank filter "Category" with value "Top for Course 1"
|
||||
Then I should see "20" occurrences of "Question #" in the "div#questionscontainer" "css_element"
|
||||
When I click on "Show all" "button"
|
||||
Then I should see "201" occurrences of "Question #" in the "div#questionscontainer" "css_element"
|
||||
When I click on "Select all" "checkbox"
|
||||
And I click on "Add selected questions to the quiz" "button"
|
||||
Then I should see "Questions: 201"
|
||||
Reference in New Issue
Block a user