mirror of
https://github.com/moodle/moodle.git
synced 2025-04-25 10:26:17 +02:00
MDL-63944 Question: Convert toggle all to generic module
This commit is contained in:
parent
b65bc972e6
commit
270fd3f5e4
lib/amd
question
amd
classes/bank
tests/behat
1
lib/amd/build/checkbox-toggleall.min.js
vendored
Normal file
1
lib/amd/build/checkbox-toggleall.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/pubsub"],function(a,b){var c=!1,d={checkboxToggled:"core/checkbox-toggleall:checkboxToggled"},e=function(a,b){return a.find('[data-action="toggle"][data-togglegroup="'+b+'"]')},f=function(a,b){return e(a,b).filter('[data-toggle="slave"]')},g=function(a,b){return e(a,b).filter('[data-toggle="master"]')},h=function(c){var e=c.data.root,g=a(c.target),h=g.data("togglegroup"),i=g.is(":checked"),k=f(e,h),l=k.filter(":checked");j(e,h,i),k.prop("checked",i),b.publish(d.checkboxToggled,{root:e,toggleGroupName:h,slaves:k,checkedSlaves:l,anyChecked:i})},i=function(c){var e=c.data.root,g=a(c.target),h=g.data("togglegroup"),i=f(e,h),k=i.filter(":checked"),l=i.length===k.length;j(e,h,l),b.publish(d.checkboxToggled,{root:e,toggleGroupName:h,slaves:i,checkedSlaves:k,anyChecked:!!k.length})},j=function(b,c,d){var e=g(b,c);e.prop("checked",d),e.each(function(c,e){e=a(e);var f,g=b.find('[for="'+e.attr("id")+'"]');g.length&&(f=d?e.data("toggle-deselectall"):e.data("toggle-selectall"),g.html()!==f&&g.html(f))})},k=function(){if(!c){c=!0;var b=a(document.body);b.on("change",'[data-action="toggle"][data-toggle="master"]',{root:b},h),b.on("change",'[data-action="toggle"][data-toggle="slave"]',{root:b},i)}};return{init:function(){k()},events:d}});
|
126
lib/amd/src/checkbox-toggleall.js
Normal file
126
lib/amd/src/checkbox-toggleall.js
Normal file
@ -0,0 +1,126 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* A module to help with toggle select/deselect all.
|
||||
*
|
||||
* @module core/checkbox-toggleall
|
||||
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['jquery', 'core/pubsub'], function($, PubSub) {
|
||||
|
||||
var registered = false;
|
||||
|
||||
var events = {
|
||||
checkboxToggled: 'core/checkbox-toggleall:checkboxToggled',
|
||||
};
|
||||
|
||||
var getAllCheckboxes = function(root, toggleGroup) {
|
||||
return root.find('[data-action="toggle"][data-togglegroup="' + toggleGroup + '"]');
|
||||
};
|
||||
|
||||
var getAllSlaveCheckboxes = function(root, toggleGroup) {
|
||||
return getAllCheckboxes(root, toggleGroup).filter('[data-toggle="slave"]');
|
||||
};
|
||||
|
||||
var getControlCheckboxes = function(root, toggleGroup) {
|
||||
return getAllCheckboxes(root, toggleGroup).filter('[data-toggle="master"]');
|
||||
};
|
||||
|
||||
var toggleSlavesFromMasters = function(e) {
|
||||
var root = e.data.root;
|
||||
var target = $(e.target);
|
||||
|
||||
var toggleGroupName = target.data('togglegroup');
|
||||
var targetState = target.is(':checked');
|
||||
|
||||
var slaves = getAllSlaveCheckboxes(root, toggleGroupName);
|
||||
var checkedSlaves = slaves.filter(':checked');
|
||||
|
||||
setMasterStates(root, toggleGroupName, targetState);
|
||||
|
||||
// Set the slave checkboxes from the masters.
|
||||
slaves.prop('checked', targetState);
|
||||
|
||||
PubSub.publish(events.checkboxToggled, {
|
||||
root: root,
|
||||
toggleGroupName: toggleGroupName,
|
||||
slaves: slaves,
|
||||
checkedSlaves: checkedSlaves,
|
||||
anyChecked: targetState,
|
||||
});
|
||||
};
|
||||
|
||||
var toggleMastersFromSlaves = function(e) {
|
||||
var root = e.data.root;
|
||||
var target = $(e.target);
|
||||
|
||||
var toggleGroupName = target.data('togglegroup');
|
||||
|
||||
var slaves = getAllSlaveCheckboxes(root, toggleGroupName);
|
||||
var checkedSlaves = slaves.filter(':checked');
|
||||
var targetState = (slaves.length === checkedSlaves.length);
|
||||
|
||||
setMasterStates(root, toggleGroupName, targetState);
|
||||
|
||||
PubSub.publish(events.checkboxToggled, {
|
||||
root: root,
|
||||
toggleGroupName: toggleGroupName,
|
||||
slaves: slaves,
|
||||
checkedSlaves: checkedSlaves,
|
||||
anyChecked: !!checkedSlaves.length,
|
||||
});
|
||||
};
|
||||
|
||||
var setMasterStates = function(root, toggleGroupName, targetState) {
|
||||
// Set the master checkboxes value and ARIA labels..
|
||||
var masters = getControlCheckboxes(root, toggleGroupName);
|
||||
masters.prop('checked', targetState);
|
||||
masters.each(function(i, masterCheckbox) {
|
||||
masterCheckbox = $(masterCheckbox);
|
||||
var masterLabel = root.find('[for="' + masterCheckbox.attr('id') + '"]');
|
||||
var targetString;
|
||||
if (masterLabel.length) {
|
||||
if (targetState) {
|
||||
targetString = masterCheckbox.data('toggle-deselectall');
|
||||
} else {
|
||||
targetString = masterCheckbox.data('toggle-selectall');
|
||||
}
|
||||
|
||||
if (masterLabel.html() !== targetString) {
|
||||
masterLabel.html(targetString);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var registerListeners = function() {
|
||||
if (!registered) {
|
||||
registered = true;
|
||||
|
||||
var root = $(document.body);
|
||||
root.on('change', '[data-action="toggle"][data-toggle="master"]', {root: root}, toggleSlavesFromMasters);
|
||||
root.on('change', '[data-action="toggle"][data-toggle="slave"]', {root: root}, toggleMastersFromSlaves);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
init: function() {
|
||||
registerListeners();
|
||||
},
|
||||
events: events,
|
||||
};
|
||||
});
|
2
question/amd/build/qbankmanager.min.js
vendored
2
question/amd/build/qbankmanager.min.js
vendored
@ -1 +1 @@
|
||||
define(["jquery","core/str","core/notification"],function(a,b,c){return{_strings:null,_buttons:null,init:function(){var d=a("#qbheadercheckbox");if(0!=d.length){var e=this;b.get_strings([{key:"selectall",component:"moodle"},{key:"deselectall",component:"moodle"}]).then(function(b){e._strings=b,d.attr({disabled:!1,checked:0!=e._getSizeChecked(),title:b[0]}),d.click(e,e._headerClick),e._buttons=a(".modulespecificbuttonscontainer input, .modulespecificbuttonscontainer select, .modulespecificbuttonscontainer link, .modulespecificbuttonscontainer link"),e._buttons.attr("disabled",0==e._getSizeChecked()),e._buttons.length>0&&a(".categoryquestionscontainer").delegate('td.checkbox input[type="checkbox"]',"change",e,e._questionClick)}).fail(c.exception)}},_headerClick:function(b){var c=b.data,d=a("#qbheadercheckbox"),e=d.is(":checked"),f=e?1:0;a("#categoryquestions tbody [type=checkbox]").prop("checked",e),c._buttons.attr("disabled",0===c._getSizeChecked()),d.attr("title",c._strings[f])},_questionClick:function(b){var c=b.data,d=a("#qbheadercheckbox"),e=c._getSizeChecked(),f=a("#categoryquestions tbody [type=checkbox]").length,g=0!=e&&e==f;d.prop("checked",g),c._buttons.attr("disabled",0===e)},_getSizeChecked:function(){return a('#categoryquestions td.checkbox input[type="checkbox"]:checked').length}}});
|
||||
define(["jquery","core/pubsub","core/checkbox-toggleall"],function(a,b,c){var d=function(){b.subscribe(c.events.checkboxToggled,e)},e=function(a){"qbank"===a.toggleGroupName&&f(a.anyChecked)},f=function(b){var c=a(".modulespecificbuttonscontainer").find("input, select, link");c.attr("disabled",!b)};return{init:function(){f(!1),d()}}});
|
113
question/amd/src/qbankmanager.js
Executable file → Normal file
113
question/amd/src/qbankmanager.js
Executable file → Normal file
@ -22,107 +22,34 @@
|
||||
* @copyright 2018 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['jquery', 'core/str', 'core/notification'], function($, str, notification) {
|
||||
define(['jquery', 'core/pubsub', 'core/checkbox-toggleall'], function($, PubSub, ToggleAll) {
|
||||
|
||||
var registerListeners = function() {
|
||||
PubSub.subscribe(ToggleAll.events.checkboxToggled, toggleButtonStates);
|
||||
};
|
||||
|
||||
var toggleButtonStates = function(data) {
|
||||
if ('qbank' !== data.toggleGroupName) {
|
||||
return;
|
||||
}
|
||||
|
||||
setButtonState(data.anyChecked);
|
||||
};
|
||||
|
||||
var setButtonState = function(state) {
|
||||
var buttons = $('.modulespecificbuttonscontainer').find('input, select, link');
|
||||
buttons.attr('disabled', !state);
|
||||
};
|
||||
|
||||
return {
|
||||
/**
|
||||
* A reference to the header checkbox.
|
||||
*
|
||||
* @property _strings
|
||||
* @type Node
|
||||
* @private
|
||||
*/
|
||||
_strings: null,
|
||||
|
||||
/**
|
||||
* A reference to the add to quiz button.
|
||||
*
|
||||
* @property _buttons
|
||||
* @type Node
|
||||
* @private
|
||||
*/
|
||||
_buttons: null,
|
||||
|
||||
/**
|
||||
* Set up the Question Bank Manager.
|
||||
*
|
||||
* @method init
|
||||
*/
|
||||
init: function() {
|
||||
// Find the header checkbox, and set the initial values.
|
||||
var header = $('#qbheadercheckbox');
|
||||
if (header.length == 0) {
|
||||
return;
|
||||
}
|
||||
var self = this;
|
||||
str.get_strings([
|
||||
{key: 'selectall', component: 'moodle'},
|
||||
{key: 'deselectall', component: 'moodle'},
|
||||
]).then(function(strings) {
|
||||
self._strings = strings;
|
||||
header.attr({
|
||||
disabled: false,
|
||||
checked: self._getSizeChecked() != 0,
|
||||
title: strings[0]
|
||||
});
|
||||
header.click(self, self._headerClick);
|
||||
|
||||
self._buttons = $(".modulespecificbuttonscontainer input, .modulespecificbuttonscontainer select," +
|
||||
" .modulespecificbuttonscontainer link, .modulespecificbuttonscontainer link");
|
||||
|
||||
self._buttons.attr('disabled', self._getSizeChecked() == 0);
|
||||
|
||||
if (self._buttons.length > 0) {
|
||||
$('.categoryquestionscontainer')
|
||||
.delegate('td.checkbox input[type="checkbox"]', 'change', self, self._questionClick);
|
||||
}
|
||||
return;
|
||||
}).fail(notification.exception);
|
||||
setButtonState(false);
|
||||
registerListeners();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle toggling of the header checkbox.
|
||||
*
|
||||
* @method _headerClick
|
||||
* @param {Event} event of element.
|
||||
* @private
|
||||
*/
|
||||
_headerClick: function(event) {
|
||||
var self = event.data;
|
||||
var header = $('#qbheadercheckbox');
|
||||
var isCheckedHeader = header.is(':checked');
|
||||
var indexStringTitle = isCheckedHeader ? 1 : 0;
|
||||
|
||||
$("#categoryquestions tbody [type=checkbox]").prop("checked", isCheckedHeader);
|
||||
self._buttons.attr('disabled', self._getSizeChecked() === 0);
|
||||
header.attr('title', self._strings[indexStringTitle]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle toggling of a question checkbox.
|
||||
*
|
||||
* @method _questionClick
|
||||
* @param {Event} event of element.
|
||||
* @private
|
||||
*/
|
||||
_questionClick: function(event) {
|
||||
var self = event.data;
|
||||
var header = $('#qbheadercheckbox');
|
||||
var areChecked = self._getSizeChecked();
|
||||
var lengthCheckbox = $("#categoryquestions tbody [type=checkbox]").length;
|
||||
var ischeckboxHeader = (areChecked != 0) && areChecked == lengthCheckbox;
|
||||
|
||||
header.prop('checked', ischeckboxHeader);
|
||||
self._buttons.attr('disabled', (areChecked === 0));
|
||||
},
|
||||
/**
|
||||
* Get size all row checked of table.
|
||||
* @method _getSizeChecked
|
||||
* @return {Number}
|
||||
* @private
|
||||
*/
|
||||
_getSizeChecked: function() {
|
||||
return $('#categoryquestions td.checkbox input[type="checkbox"]:checked').length;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -26,7 +26,9 @@ class checkbox_column extends column_base {
|
||||
protected $strselect;
|
||||
|
||||
public function init() {
|
||||
$this->strselect = get_string('select');
|
||||
global $PAGE;
|
||||
|
||||
$PAGE->requires->js_call_amd('core/checkbox-toggleall', 'init');
|
||||
}
|
||||
|
||||
public function get_name() {
|
||||
@ -34,22 +36,42 @@ class checkbox_column extends column_base {
|
||||
}
|
||||
|
||||
protected function get_title() {
|
||||
return '<input type="checkbox" disabled="disabled" id="qbheadercheckbox" name="qbheadercheckbox" />' .
|
||||
'<label class="accesshide" for="qbheadercheckbox">' . get_string('selectall', 'moodle') . '</label>';
|
||||
$input = \html_writer::empty_tag('input', [
|
||||
'id' => 'qbheadercheckbox',
|
||||
'title' => get_string('select'),
|
||||
'name' => 'qbheadercheckbox',
|
||||
'type' => 'checkbox',
|
||||
'value' => '1',
|
||||
'data-action' => 'toggle',
|
||||
'data-toggle' => 'master',
|
||||
'data-togglegroup' => 'qbank',
|
||||
'data-toggle-selectall' => get_string('selectall', 'moodle'),
|
||||
'data-toggle-deselectall' => get_string('deselectall', 'moodle'),
|
||||
]);
|
||||
|
||||
$label = \html_writer::tag('label', get_string('selectall', 'moodle'), [
|
||||
'class' => 'accesshide',
|
||||
'for' => 'qbheadercheckbox',
|
||||
]);
|
||||
|
||||
return $input . $label;
|
||||
}
|
||||
|
||||
protected function get_title_tip() {
|
||||
global $PAGE;
|
||||
$PAGE->requires->strings_for_js(array('selectall', 'deselectall'), 'moodle');
|
||||
$PAGE->requires->js_call_amd('core_question/qbankmanager', 'init');
|
||||
return get_string('selectquestionsforbulk', 'question');
|
||||
|
||||
}
|
||||
|
||||
protected function display_content($question, $rowclasses) {
|
||||
global $PAGE;
|
||||
echo '<input title="' . $this->strselect . '" type="checkbox" name="q' .
|
||||
$question->id . '" id="checkq' . $question->id . '" value="1"/>';
|
||||
echo \html_writer::empty_tag('input', [
|
||||
'title' => get_string('select'),
|
||||
'type' => 'checkbox',
|
||||
'name' => "q{$question->id}",
|
||||
'id' => "checkq{$question->id}",
|
||||
'value' => '1',
|
||||
'data-action' => 'toggle',
|
||||
'data-toggle' => 'slave',
|
||||
'data-togglegroup' => 'qbank',
|
||||
]);
|
||||
}
|
||||
|
||||
public function get_required_fields() {
|
||||
|
@ -773,10 +773,14 @@ class view {
|
||||
* @param array $addcontexts contexts where the user is allowed to add new questions.
|
||||
*/
|
||||
protected function display_bottom_controls($totalnumber, $recurse, $category, \context $catcontext, array $addcontexts) {
|
||||
global $PAGE;
|
||||
|
||||
$caneditall = has_capability('moodle/question:editall', $catcontext);
|
||||
$canuseall = has_capability('moodle/question:useall', $catcontext);
|
||||
$canmoveall = has_capability('moodle/question:moveall', $catcontext);
|
||||
|
||||
$PAGE->requires->js_call_amd('core_question/qbankmanager', 'init');
|
||||
|
||||
echo '<div class="modulespecificbuttonscontainer">';
|
||||
if ($caneditall || $canmoveall || $canuseall) {
|
||||
echo '<strong> '.get_string('withselected', 'question').':</strong><br />';
|
||||
|
@ -24,7 +24,7 @@ Feature: The questions in the question bank can be selected in various ways
|
||||
| Test questions | numerical | C question 3 name | teacher1 | Question 3 text |
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage
|
||||
And I navigate to "Questions" node in "Course administration > Question bank"
|
||||
And I navigate to "Questions" in current page administration
|
||||
|
||||
@javascript
|
||||
Scenario: The question text can be chosen all in the list of questions
|
||||
@ -33,7 +33,7 @@ Feature: The questions in the question bank can be selected in various ways
|
||||
Then the field "A question 1 name" matches value "1"
|
||||
And the field "B question 2 name" matches value "1"
|
||||
And the field "C question 3 name" matches value "1"
|
||||
When I click on "Select all" "checkbox"
|
||||
When I click on "Deselect all" "checkbox"
|
||||
Then the field "A question 1 name" matches value ""
|
||||
And the field "B question 2 name" matches value ""
|
||||
And the field "C question 3 name" matches value ""
|
||||
@ -45,7 +45,7 @@ Feature: The questions in the question bank can be selected in various ways
|
||||
Then the field "Select all" matches value ""
|
||||
When I click on "B question 2 name" "checkbox"
|
||||
And I click on "C question 3 name" "checkbox"
|
||||
Then the field "Select all" matches value "1"
|
||||
Then the field "Deselect all" matches value "1"
|
||||
|
||||
@javascript
|
||||
Scenario: The action button can be disabled when the question not be chosen in the list of questions
|
||||
|
Loading…
x
Reference in New Issue
Block a user