MDL-78885 comboboxsearch: Points from review
This commit is contained in:
committed by
Shamim Rezaie
parent
2ac9dc9108
commit
68bf0f5b77
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -40,6 +40,7 @@ export default class GradeItemSearch extends search_combobox {
|
||||
};
|
||||
const component = document.querySelector(this.componentSelector());
|
||||
this.courseID = component.querySelector(this.selectors.courseid).dataset.courseid;
|
||||
this.instance = this.component.querySelector(this.selectors.instance).dataset.instance;
|
||||
|
||||
const searchValueElement = this.component.querySelector(`#${this.searchInput.dataset.inputElement}`);
|
||||
searchValueElement.addEventListener('change', () => {
|
||||
@@ -102,6 +103,7 @@ export default class GradeItemSearch extends search_combobox {
|
||||
*/
|
||||
async renderDropdown() {
|
||||
const {html, js} = await renderForPromise('core/local/comboboxsearch/resultset', {
|
||||
instance: this.instance,
|
||||
results: this.getMatchedResults(),
|
||||
hasresults: this.getMatchedResults().length > 0,
|
||||
searchterm: this.getSearchTerm(),
|
||||
@@ -233,6 +235,7 @@ export default class GradeItemSearch extends search_combobox {
|
||||
|
||||
/**
|
||||
* Build up the view all link that is dedicated to a particular result.
|
||||
* We will call this function when a user interacts with the combobox to redirect them to show their results in the page.
|
||||
*
|
||||
* @param {Number} gradeID The ID of the grade item selected.
|
||||
*/
|
||||
|
||||
@@ -65,6 +65,7 @@ class core_grades_renderer extends plugin_renderer_base {
|
||||
$sbody = $this->render_from_template('core_group/comboboxsearch/searchbody', [
|
||||
'courseid' => $course->id,
|
||||
'currentvalue' => optional_param('groupsearchvalue', '', PARAM_NOTAGS),
|
||||
'instance' => rand(),
|
||||
]);
|
||||
|
||||
$label = $groupmode == VISIBLEGROUPS ? get_string('selectgroupsvisible') : get_string('selectgroupsseparate');
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"version":3,"file":"group.min.js","sources":["../src/group.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for groups within the grader report.\n *\n * @module gradereport_grader/group\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport GroupSearch from 'core_group/comboboxsearch/group';\nimport Url from 'core/url';\n\nexport default class Group extends GroupSearch {\n\n courseID;\n\n constructor() {\n super();\n\n // Define our standard lookups.\n this.selectors = {...this.selectors,\n courseid: '[data-region=\"courseid\"]',\n };\n const component = document.querySelector(this.componentSelector());\n this.courseID = component.querySelector(this.selectors.courseid).dataset.courseid;\n }\n\n static init() {\n return new Group();\n }\n\n /**\n * Build up the view all link that is dedicated to a particular result.\n *\n * @param {Number} groupID The ID of the group selected.\n * @returns {string|*}\n */\n selectOneLink(groupID) {\n return Url.relativeUrl('/grade/report/grader/index.php', {\n id: this.courseID,\n groupsearchvalue: this.getSearchTerm(),\n group: groupID,\n }, false);\n }\n}\n"],"names":["Group","GroupSearch","constructor","selectors","this","courseid","component","document","querySelector","componentSelector","courseID","dataset","selectOneLink","groupID","Url","relativeUrl","id","groupsearchvalue","getSearchTerm","group"],"mappings":"2WAyBqBA,cAAcC,eAI/BC,6LAISC,UAAY,IAAIC,KAAKD,UACtBE,SAAU,kCAERC,UAAYC,SAASC,cAAcJ,KAAKK,0BACzCC,SAAWJ,UAAUE,cAAcJ,KAAKD,UAAUE,UAAUM,QAAQN,8BAIlE,IAAIL,MASfY,cAAcC,gBACHC,aAAIC,YAAY,iCAAkC,CACrDC,GAAIZ,KAAKM,SACTO,iBAAkBb,KAAKc,gBACvBC,MAAON,UACR"}
|
||||
{"version":3,"file":"group.min.js","sources":["../src/group.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for groups within the grader report.\n *\n * @module gradereport_grader/group\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport GroupSearch from 'core_group/comboboxsearch/group';\nimport Url from 'core/url';\n\nexport default class Group extends GroupSearch {\n\n courseID;\n\n constructor() {\n super();\n\n // Define our standard lookups.\n this.selectors = {...this.selectors,\n courseid: '[data-region=\"courseid\"]',\n };\n const component = document.querySelector(this.componentSelector());\n this.courseID = component.querySelector(this.selectors.courseid).dataset.courseid;\n }\n\n static init() {\n return new Group();\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} groupID The ID of the group selected.\n * @returns {string|*}\n */\n selectOneLink(groupID) {\n return Url.relativeUrl('/grade/report/grader/index.php', {\n id: this.courseID,\n groupsearchvalue: this.getSearchTerm(),\n group: groupID,\n }, false);\n }\n}\n"],"names":["Group","GroupSearch","constructor","selectors","this","courseid","component","document","querySelector","componentSelector","courseID","dataset","selectOneLink","groupID","Url","relativeUrl","id","groupsearchvalue","getSearchTerm","group"],"mappings":"2WAyBqBA,cAAcC,eAI/BC,6LAISC,UAAY,IAAIC,KAAKD,UACtBE,SAAU,kCAERC,UAAYC,SAASC,cAAcJ,KAAKK,0BACzCC,SAAWJ,UAAUE,cAAcJ,KAAKD,UAAUE,UAAUM,QAAQN,8BAIlE,IAAIL,MASfY,cAAcC,gBACHC,aAAIC,YAAY,iCAAkC,CACrDC,GAAIZ,KAAKM,SACTO,iBAAkBb,KAAKc,gBACvBC,MAAON,UACR"}
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"user.min.js","sources":["../src/user.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for learners within the grader report.\n *\n * @module gradereport_grader/user\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport Url from 'core/url';\nimport * as Repository from 'gradereport_grader/local/user/repository';\n\n// Define our standard lookups.\nconst selectors = {\n component: '.user-search',\n courseid: '[data-region=\"courseid\"]',\n};\nconst component = document.querySelector(selectors.component);\nconst courseID = component.querySelector(selectors.courseid).dataset.courseid;\n\nexport default class User extends UserSearch {\n\n constructor() {\n super();\n }\n\n static init() {\n return new User();\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n return Repository.userFetch(courseID).then((r) => r.users);\n }\n\n /**\n * Build up the view all link.\n *\n * @returns {string|*}\n */\n selectAllResultsLink() {\n return Url.relativeUrl('/grade/report/grader/index.php', {\n id: courseID,\n gpr_search: this.getSearchTerm()\n }, false);\n }\n\n /**\n * Build up the view all link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n return Url.relativeUrl('/grade/report/grader/index.php', {\n id: courseID,\n gpr_search: this.getSearchTerm(),\n gpr_userid: userID,\n }, false);\n }\n}\n"],"names":["selectors","courseID","document","querySelector","dataset","courseid","User","UserSearch","constructor","fetchDataset","Repository","userFetch","then","r","users","selectAllResultsLink","Url","relativeUrl","id","gpr_search","this","getSearchTerm","selectOneLink","userID","gpr_userid"],"mappings":";;;;;;;q0BA2BMA,oBACS,eADTA,mBAEQ,2BAGRC,SADYC,SAASC,cAAcH,qBACdG,cAAcH,oBAAoBI,QAAQC,eAEhDC,aAAaC,cAE9BC,2CAKW,IAAIF,KAQfG,sBACWC,WAAWC,UAAUV,UAAUW,MAAMC,GAAMA,EAAEC,QAQxDC,8BACWC,aAAIC,YAAY,iCAAkC,CACrDC,GAAIjB,SACJkB,WAAYC,KAAKC,kBAClB,GASPC,cAAcC,eACHP,aAAIC,YAAY,iCAAkC,CACrDC,GAAIjB,SACJkB,WAAYC,KAAKC,gBACjBG,WAAYD,SACb"}
|
||||
{"version":3,"file":"user.min.js","sources":["../src/user.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for learners within the grader report.\n *\n * @module gradereport_grader/user\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport Url from 'core/url';\nimport * as Repository from 'gradereport_grader/local/user/repository';\n\n// Define our standard lookups.\nconst selectors = {\n component: '.user-search',\n courseid: '[data-region=\"courseid\"]',\n};\nconst component = document.querySelector(selectors.component);\nconst courseID = component.querySelector(selectors.courseid).dataset.courseid;\n\nexport default class User extends UserSearch {\n\n constructor() {\n super();\n }\n\n static init() {\n return new User();\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n return Repository.userFetch(courseID).then((r) => r.users);\n }\n\n /**\n * Build up the view all link.\n *\n * @returns {string|*}\n */\n selectAllResultsLink() {\n return Url.relativeUrl('/grade/report/grader/index.php', {\n id: courseID,\n gpr_search: this.getSearchTerm()\n }, false);\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n return Url.relativeUrl('/grade/report/grader/index.php', {\n id: courseID,\n gpr_search: this.getSearchTerm(),\n gpr_userid: userID,\n }, false);\n }\n}\n"],"names":["selectors","courseID","document","querySelector","dataset","courseid","User","UserSearch","constructor","fetchDataset","Repository","userFetch","then","r","users","selectAllResultsLink","Url","relativeUrl","id","gpr_search","this","getSearchTerm","selectOneLink","userID","gpr_userid"],"mappings":";;;;;;;q0BA2BMA,oBACS,eADTA,mBAEQ,2BAGRC,SADYC,SAASC,cAAcH,qBACdG,cAAcH,oBAAoBI,QAAQC,eAEhDC,aAAaC,cAE9BC,2CAKW,IAAIF,KAQfG,sBACWC,WAAWC,UAAUV,UAAUW,MAAMC,GAAMA,EAAEC,QAQxDC,8BACWC,aAAIC,YAAY,iCAAkC,CACrDC,GAAIjB,SACJkB,WAAYC,KAAKC,kBAClB,GASPC,cAAcC,eACHP,aAAIC,YAAY,iCAAkC,CACrDC,GAAIjB,SACJkB,WAAYC,KAAKC,gBACjBG,WAAYD,SACb"}
|
||||
@@ -478,6 +478,7 @@ export default class ColumnSearch extends search_combobox {
|
||||
// Update the collapsed button pill.
|
||||
this.countUpdate();
|
||||
const {html, js} = await renderForPromise('gradereport_grader/collapse/collapsebody', {
|
||||
'instance': this.instance,
|
||||
'results': this.getMatchedResults(),
|
||||
'userid': this.userID,
|
||||
});
|
||||
@@ -500,6 +501,7 @@ export default class ColumnSearch extends search_combobox {
|
||||
*/
|
||||
async renderDropdown() {
|
||||
const {html, js} = await renderForPromise('gradereport_grader/collapse/collapseresults', {
|
||||
instance: this.instance,
|
||||
'results': this.getMatchedResults(),
|
||||
'searchTerm': this.getSearchTerm(),
|
||||
});
|
||||
|
||||
@@ -43,7 +43,7 @@ export default class Group extends GroupSearch {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up the view all link that is dedicated to a particular result.
|
||||
* Build up the link that is dedicated to a particular result.
|
||||
*
|
||||
* @param {Number} groupID The ID of the group selected.
|
||||
* @returns {string|*}
|
||||
|
||||
@@ -64,7 +64,7 @@ export default class User extends UserSearch {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up the view all link that is dedicated to a particular result.
|
||||
* Build up the link that is dedicated to a particular result.
|
||||
*
|
||||
* @param {Number} userID The ID of the user selected.
|
||||
* @returns {string|*}
|
||||
|
||||
@@ -116,6 +116,7 @@ class action_bar extends \core_grades\output\action_bar {
|
||||
$searchinput = $OUTPUT->render_from_template('core_user/comboboxsearch/user_selector', [
|
||||
'currentvalue' => $this->usersearch,
|
||||
'courseid' => $courseid,
|
||||
'instance' => rand(),
|
||||
'resetlink' => $resetlink->out(false),
|
||||
'group' => 0,
|
||||
'name' => 'usersearch',
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"instance": 25,
|
||||
"results": [
|
||||
{
|
||||
"name": "42",
|
||||
@@ -43,7 +44,7 @@
|
||||
<form class="columnsdropdownform flex-column h-100">
|
||||
<fieldset>
|
||||
<legend class="sr-only">{{#str}} aria:dropdowncolumns, gradereport_grader {{/str}}</legend>
|
||||
<ul id="collapse-listbox" class="searchresultitemscontainer overflow-auto py-2 px-1 list-group mx-0 text-truncate" data-region="search-result-items-container">
|
||||
<ul id="collapse-{{instance}}-listbox" class="searchresultitemscontainer overflow-auto py-2 px-1 list-group mx-0 text-truncate" data-region="search-result-items-container">
|
||||
{{>gradereport_grader/collapse/collapseresults}}
|
||||
</ul>
|
||||
</fieldset>
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"group.min.js","sources":["../src/group.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for groups within the singleview report.\n *\n * @module gradereport_singleview/group\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport GroupSearch from 'core_group/comboboxsearch/group';\nimport Url from 'core/url';\n\nexport default class Group extends GroupSearch {\n\n courseID;\n\n item = null;\n\n /**\n * Construct the class.\n *\n * @param {string} item The page type we are currently on.\n */\n constructor(item) {\n super();\n this.item = item;\n\n // Define our standard lookups.\n this.selectors = {...this.selectors,\n courseid: '[data-region=\"courseid\"]',\n };\n const component = document.querySelector(this.componentSelector());\n this.courseID = component.querySelector(this.selectors.courseid).dataset.courseid;\n }\n\n /**\n * Allow the class to be invoked via PHP.\n *\n * @param {string} item The page type we are currently on.\n * @returns {Group}\n */\n static init(item) {\n return new Group(item);\n }\n\n /**\n * Build up the view all link that is dedicated to a particular result.\n *\n * @param {Number} groupID The ID of the group selected.\n * @returns {string|*}\n */\n selectOneLink(groupID) {\n return Url.relativeUrl('/grade/report/singleview/index.php', {\n id: this.courseID,\n groupsearchvalue: this.getSearchTerm(),\n group: groupID,\n item: this.item\n }, false);\n }\n}\n"],"names":["Group","GroupSearch","constructor","item","selectors","this","courseid","component","document","querySelector","componentSelector","courseID","dataset","selectOneLink","groupID","Url","relativeUrl","id","groupsearchvalue","getSearchTerm","group"],"mappings":"mhBAyBqBA,cAAcC,eAW/BC,YAAYC,kFAPL,WASEA,KAAOA,UAGPC,UAAY,IAAIC,KAAKD,UACtBE,SAAU,kCAERC,UAAYC,SAASC,cAAcJ,KAAKK,0BACzCC,SAAWJ,UAAUE,cAAcJ,KAAKD,UAAUE,UAAUM,QAAQN,qBASjEH,aACD,IAAIH,MAAMG,MASrBU,cAAcC,gBACHC,aAAIC,YAAY,qCAAsC,CACzDC,GAAIZ,KAAKM,SACTO,iBAAkBb,KAAKc,gBACvBC,MAAON,QACPX,KAAME,KAAKF,OACZ"}
|
||||
{"version":3,"file":"group.min.js","sources":["../src/group.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for groups within the singleview report.\n *\n * @module gradereport_singleview/group\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport GroupSearch from 'core_group/comboboxsearch/group';\nimport Url from 'core/url';\n\nexport default class Group extends GroupSearch {\n\n courseID;\n\n item = null;\n\n /**\n * Construct the class.\n *\n * @param {string} item The page type we are currently on.\n */\n constructor(item) {\n super();\n this.item = item;\n\n // Define our standard lookups.\n this.selectors = {...this.selectors,\n courseid: '[data-region=\"courseid\"]',\n };\n const component = document.querySelector(this.componentSelector());\n this.courseID = component.querySelector(this.selectors.courseid).dataset.courseid;\n }\n\n /**\n * Allow the class to be invoked via PHP.\n *\n * @param {string} item The page type we are currently on.\n * @returns {Group}\n */\n static init(item) {\n return new Group(item);\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} groupID The ID of the group selected.\n * @returns {string|*}\n */\n selectOneLink(groupID) {\n return Url.relativeUrl('/grade/report/singleview/index.php', {\n id: this.courseID,\n groupsearchvalue: this.getSearchTerm(),\n group: groupID,\n item: this.item\n }, false);\n }\n}\n"],"names":["Group","GroupSearch","constructor","item","selectors","this","courseid","component","document","querySelector","componentSelector","courseID","dataset","selectOneLink","groupID","Url","relativeUrl","id","groupsearchvalue","getSearchTerm","group"],"mappings":"mhBAyBqBA,cAAcC,eAW/BC,YAAYC,kFAPL,WASEA,KAAOA,UAGPC,UAAY,IAAIC,KAAKD,UACtBE,SAAU,kCAERC,UAAYC,SAASC,cAAcJ,KAAKK,0BACzCC,SAAWJ,UAAUE,cAAcJ,KAAKD,UAAUE,UAAUM,QAAQN,qBASjEH,aACD,IAAIH,MAAMG,MASrBU,cAAcC,gBACHC,aAAIC,YAAY,qCAAsC,CACzDC,GAAIZ,KAAKM,SACTO,iBAAkBb,KAAKc,gBACvBC,MAAON,QACPX,KAAME,KAAKF,OACZ"}
|
||||
+1
-1
@@ -5,6 +5,6 @@ define("gradereport_singleview/user",["exports","core_user/comboboxsearch/user",
|
||||
* @module gradereport_singleview/user
|
||||
* @copyright 2023 Mathew May <mathew.solutions>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_user=_interopRequireDefault(_user),_url=_interopRequireDefault(_url),Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Repository);class User extends _user.default{constructor(){super()}static init(){return new User}async renderDropdown(){const{html:html,js:js}=await(0,_templates.renderForPromise)("core_user/comboboxsearch/resultset",{users:this.getMatchedResults().slice(0,5),hasresults:this.getMatchedResults().length>0,searchterm:this.getSearchTerm()});(0,_templates.replaceNodeContents)(this.getHTMLElements().searchDropdown,html,js),this.searchInput.removeAttribute("aria-activedescendant")}selectAllResultsLink(){return null}selectOneLink(userID){return _url.default.relativeUrl("/grade/report/singleview/index.php",{id:this.courseID,searchvalue:this.getSearchTerm(),item:"user",userid:userID},!1)}fetchDataset(){const gts="string"==typeof this.groupID&&""===this.groupID?0:this.groupID;return Repository.userFetch(this.courseID,gts).then((r=>r.users))}}return _exports.default=User,_exports.default}));
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_user=_interopRequireDefault(_user),_url=_interopRequireDefault(_url),Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Repository);class User extends _user.default{constructor(){super()}static init(){return new User}async renderDropdown(){const{html:html,js:js}=await(0,_templates.renderForPromise)("core_user/comboboxsearch/resultset",{instance:this.instance,users:this.getMatchedResults().slice(0,5),hasresults:this.getMatchedResults().length>0,searchterm:this.getSearchTerm()});(0,_templates.replaceNodeContents)(this.getHTMLElements().searchDropdown,html,js),this.searchInput.removeAttribute("aria-activedescendant")}selectAllResultsLink(){return null}selectOneLink(userID){return _url.default.relativeUrl("/grade/report/singleview/index.php",{id:this.courseID,searchvalue:this.getSearchTerm(),item:"user",userid:userID},!1)}fetchDataset(){const gts="string"==typeof this.groupID&&""===this.groupID?0:this.groupID;return Repository.userFetch(this.courseID,gts).then((r=>r.users))}}return _exports.default=User,_exports.default}));
|
||||
|
||||
//# sourceMappingURL=user.min.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"user.min.js","sources":["../src/user.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for learners within the singleview report.\n *\n * @module gradereport_singleview/user\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport Url from 'core/url';\nimport {renderForPromise, replaceNodeContents} from 'core/templates';\nimport * as Repository from 'core_grades/searchwidget/repository';\n\nexport default class User extends UserSearch {\n\n constructor() {\n super();\n }\n\n static init() {\n return new User();\n }\n\n /**\n * Build the content then replace the node.\n */\n async renderDropdown() {\n const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {\n users: this.getMatchedResults().slice(0, 5),\n hasresults: this.getMatchedResults().length > 0,\n searchterm: this.getSearchTerm(),\n });\n replaceNodeContents(this.getHTMLElements().searchDropdown, html, js);\n // Remove aria-activedescendant when the available options change.\n this.searchInput.removeAttribute('aria-activedescendant');\n }\n\n /**\n * Stub out default required function unused here.\n * @returns {null}\n */\n selectAllResultsLink() {\n return null;\n }\n\n /**\n * Build up the view all link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n return Url.relativeUrl('/grade/report/singleview/index.php', {\n id: this.courseID,\n searchvalue: this.getSearchTerm(),\n item: 'user',\n userid: userID,\n }, false);\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n // Small typing checks as sometimes groups don't exist therefore the element returns a empty string.\n const gts = typeof (this.groupID) === \"string\" && this.groupID === '' ? 0 : this.groupID;\n return Repository.userFetch(this.courseID, gts).then((r) => r.users);\n }\n}\n"],"names":["User","UserSearch","constructor","html","js","users","this","getMatchedResults","slice","hasresults","length","searchterm","getSearchTerm","getHTMLElements","searchDropdown","searchInput","removeAttribute","selectAllResultsLink","selectOneLink","userID","Url","relativeUrl","id","courseID","searchvalue","item","userid","fetchDataset","gts","groupID","Repository","userFetch","then","r"],"mappings":";;;;;;;q0BA2BqBA,aAAaC,cAE9BC,2CAKW,IAAIF,kCAOLG,KAACA,KAADC,GAAOA,UAAY,+BAAiB,qCAAsC,CAC5EC,MAAOC,KAAKC,oBAAoBC,MAAM,EAAG,GACzCC,WAAYH,KAAKC,oBAAoBG,OAAS,EAC9CC,WAAYL,KAAKM,qDAEDN,KAAKO,kBAAkBC,eAAgBX,KAAMC,SAE5DW,YAAYC,gBAAgB,yBAOrCC,8BACW,KASXC,cAAcC,eACHC,aAAIC,YAAY,qCAAsC,CACzDC,GAAIhB,KAAKiB,SACTC,YAAalB,KAAKM,gBAClBa,KAAM,OACNC,OAAQP,SACT,GAQPQ,qBAEUC,IAAgC,iBAAlBtB,KAAKuB,SAA0C,KAAjBvB,KAAKuB,QAAiB,EAAIvB,KAAKuB,eAC1EC,WAAWC,UAAUzB,KAAKiB,SAAUK,KAAKI,MAAMC,GAAMA,EAAE5B"}
|
||||
{"version":3,"file":"user.min.js","sources":["../src/user.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for learners within the singleview report.\n *\n * @module gradereport_singleview/user\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport Url from 'core/url';\nimport {renderForPromise, replaceNodeContents} from 'core/templates';\nimport * as Repository from 'core_grades/searchwidget/repository';\n\nexport default class User extends UserSearch {\n\n constructor() {\n super();\n }\n\n static init() {\n return new User();\n }\n\n /**\n * Build the content then replace the node.\n */\n async renderDropdown() {\n const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {\n instance: this.instance,\n users: this.getMatchedResults().slice(0, 5),\n hasresults: this.getMatchedResults().length > 0,\n searchterm: this.getSearchTerm(),\n });\n replaceNodeContents(this.getHTMLElements().searchDropdown, html, js);\n // Remove aria-activedescendant when the available options change.\n this.searchInput.removeAttribute('aria-activedescendant');\n }\n\n /**\n * Stub out default required function unused here.\n * @returns {null}\n */\n selectAllResultsLink() {\n return null;\n }\n\n /**\n * Build up the view all link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n return Url.relativeUrl('/grade/report/singleview/index.php', {\n id: this.courseID,\n searchvalue: this.getSearchTerm(),\n item: 'user',\n userid: userID,\n }, false);\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n // Small typing checks as sometimes groups don't exist therefore the element returns a empty string.\n const gts = typeof (this.groupID) === \"string\" && this.groupID === '' ? 0 : this.groupID;\n return Repository.userFetch(this.courseID, gts).then((r) => r.users);\n }\n}\n"],"names":["User","UserSearch","constructor","html","js","instance","this","users","getMatchedResults","slice","hasresults","length","searchterm","getSearchTerm","getHTMLElements","searchDropdown","searchInput","removeAttribute","selectAllResultsLink","selectOneLink","userID","Url","relativeUrl","id","courseID","searchvalue","item","userid","fetchDataset","gts","groupID","Repository","userFetch","then","r"],"mappings":";;;;;;;q0BA2BqBA,aAAaC,cAE9BC,2CAKW,IAAIF,kCAOLG,KAACA,KAADC,GAAOA,UAAY,+BAAiB,qCAAsC,CAC5EC,SAAUC,KAAKD,SACfE,MAAOD,KAAKE,oBAAoBC,MAAM,EAAG,GACzCC,WAAYJ,KAAKE,oBAAoBG,OAAS,EAC9CC,WAAYN,KAAKO,qDAEDP,KAAKQ,kBAAkBC,eAAgBZ,KAAMC,SAE5DY,YAAYC,gBAAgB,yBAOrCC,8BACW,KASXC,cAAcC,eACHC,aAAIC,YAAY,qCAAsC,CACzDC,GAAIjB,KAAKkB,SACTC,YAAanB,KAAKO,gBAClBa,KAAM,OACNC,OAAQP,SACT,GAQPQ,qBAEUC,IAAgC,iBAAlBvB,KAAKwB,SAA0C,KAAjBxB,KAAKwB,QAAiB,EAAIxB,KAAKwB,eAC1EC,WAAWC,UAAU1B,KAAKkB,SAAUK,KAAKI,MAAMC,GAAMA,EAAE3B"}
|
||||
@@ -57,7 +57,7 @@ export default class Group extends GroupSearch {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up the view all link that is dedicated to a particular result.
|
||||
* Build up the link that is dedicated to a particular result.
|
||||
*
|
||||
* @param {Number} groupID The ID of the group selected.
|
||||
* @returns {string|*}
|
||||
|
||||
@@ -40,6 +40,7 @@ export default class User extends UserSearch {
|
||||
*/
|
||||
async renderDropdown() {
|
||||
const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {
|
||||
instance: this.instance,
|
||||
users: this.getMatchedResults().slice(0, 5),
|
||||
hasresults: this.getMatchedResults().length > 0,
|
||||
searchterm: this.getSearchTerm(),
|
||||
|
||||
@@ -58,6 +58,7 @@ class gradereport_singleview_renderer extends plugin_renderer_base {
|
||||
$data = [
|
||||
'currentvalue' => $currentvalue,
|
||||
'courseid' => $course->id,
|
||||
'instance' => rand(),
|
||||
'group' => $groupid ?? 0,
|
||||
'resetlink' => $resetlink->out(false),
|
||||
'name' => 'userid',
|
||||
@@ -88,6 +89,7 @@ class gradereport_singleview_renderer extends plugin_renderer_base {
|
||||
$data = [
|
||||
'name' => 'itemid',
|
||||
'courseid' => $course->id,
|
||||
'instance' => rand(),
|
||||
];
|
||||
|
||||
// If a particular grade item option is selected (not in zero state).
|
||||
@@ -102,6 +104,7 @@ class gradereport_singleview_renderer extends plugin_renderer_base {
|
||||
$sbody = $this->render_from_template('core/local/comboboxsearch/searchbody', [
|
||||
'courseid' => $course->id,
|
||||
'currentvalue' => optional_param('gradesearchvalue', '', PARAM_NOTAGS),
|
||||
'instance' => $data['instance'],
|
||||
]);
|
||||
$dropdown = new comboboxsearch(
|
||||
false,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
Context variables required for this template:
|
||||
* itemid - The value of the grade item selector element (id of the preselected grade item)
|
||||
* instance - The instance ID of the combo box.
|
||||
* courseid - The course ID.
|
||||
* selectedoption - (optional) Object containing information about the selected option.
|
||||
* text - The text of the selected option.
|
||||
@@ -25,6 +26,7 @@
|
||||
Example context (json):
|
||||
{
|
||||
"itemid": "21",
|
||||
"instance": "25",
|
||||
"courseid": "2",
|
||||
"selectedoption": {
|
||||
"text": "Grade item 1"
|
||||
@@ -50,3 +52,4 @@
|
||||
</div>
|
||||
<span class="d-none" data-region="courseid" data-courseid="{{courseid}}"></span>
|
||||
<span class="d-none" data-region="itemid" data-itemid="{{itemid}}"></span>
|
||||
<span class="d-none" data-region="instance" data-instance="{{instance}}"></span>
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"group.min.js","sources":["../src/group.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for groups within the user report.\n *\n * @module gradereport_user/group\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport GroupSearch from 'core_group/comboboxsearch/group';\nimport Url from 'core/url';\n\nexport default class Group extends GroupSearch {\n\n courseID;\n\n constructor() {\n super();\n\n // Define our standard lookups.\n this.selectors = {...this.selectors,\n courseid: '[data-region=\"courseid\"]',\n };\n const component = document.querySelector(this.componentSelector());\n this.courseID = component.querySelector(this.selectors.courseid).dataset.courseid;\n }\n\n static init() {\n return new Group();\n }\n\n /**\n * Build up the view all link that is dedicated to a particular result.\n *\n * @param {Number} groupID The ID of the group selected.\n * @returns {string|*}\n */\n selectOneLink(groupID) {\n return Url.relativeUrl('/grade/report/user/index.php', {\n id: this.courseID,\n groupsearchvalue: this.getSearchTerm(),\n group: groupID,\n }, false);\n }\n}\n"],"names":["Group","GroupSearch","constructor","selectors","this","courseid","component","document","querySelector","componentSelector","courseID","dataset","selectOneLink","groupID","Url","relativeUrl","id","groupsearchvalue","getSearchTerm","group"],"mappings":"yWAyBqBA,cAAcC,eAI/BC,6LAISC,UAAY,IAAIC,KAAKD,UACtBE,SAAU,kCAERC,UAAYC,SAASC,cAAcJ,KAAKK,0BACzCC,SAAWJ,UAAUE,cAAcJ,KAAKD,UAAUE,UAAUM,QAAQN,8BAIlE,IAAIL,MASfY,cAAcC,gBACHC,aAAIC,YAAY,+BAAgC,CACnDC,GAAIZ,KAAKM,SACTO,iBAAkBb,KAAKc,gBACvBC,MAAON,UACR"}
|
||||
{"version":3,"file":"group.min.js","sources":["../src/group.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for groups within the user report.\n *\n * @module gradereport_user/group\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport GroupSearch from 'core_group/comboboxsearch/group';\nimport Url from 'core/url';\n\nexport default class Group extends GroupSearch {\n\n courseID;\n\n constructor() {\n super();\n\n // Define our standard lookups.\n this.selectors = {...this.selectors,\n courseid: '[data-region=\"courseid\"]',\n };\n const component = document.querySelector(this.componentSelector());\n this.courseID = component.querySelector(this.selectors.courseid).dataset.courseid;\n }\n\n static init() {\n return new Group();\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} groupID The ID of the group selected.\n * @returns {string|*}\n */\n selectOneLink(groupID) {\n return Url.relativeUrl('/grade/report/user/index.php', {\n id: this.courseID,\n groupsearchvalue: this.getSearchTerm(),\n group: groupID,\n }, false);\n }\n}\n"],"names":["Group","GroupSearch","constructor","selectors","this","courseid","component","document","querySelector","componentSelector","courseID","dataset","selectOneLink","groupID","Url","relativeUrl","id","groupsearchvalue","getSearchTerm","group"],"mappings":"yWAyBqBA,cAAcC,eAI/BC,6LAISC,UAAY,IAAIC,KAAKD,UACtBE,SAAU,kCAERC,UAAYC,SAASC,cAAcJ,KAAKK,0BACzCC,SAAWJ,UAAUE,cAAcJ,KAAKD,UAAUE,UAAUM,QAAQN,8BAIlE,IAAIL,MASfY,cAAcC,gBACHC,aAAIC,YAAY,+BAAgC,CACnDC,GAAIZ,KAAKM,SACTO,iBAAkBb,KAAKc,gBACvBC,MAAON,UACR"}
|
||||
+1
-1
@@ -5,6 +5,6 @@ define("gradereport_user/user",["exports","core_user/comboboxsearch/user","core/
|
||||
* @module gradereport_user/user
|
||||
* @copyright 2023 Mathew May <mathew.solutions>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_user=_interopRequireDefault(_user),_url=_interopRequireDefault(_url),Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Repository);class User extends _user.default{constructor(){super()}static init(){return new User}async renderDropdown(){const{html:html,js:js}=await(0,_templates.renderForPromise)("core_user/comboboxsearch/resultset",{users:this.getMatchedResults().slice(0,5),hasresults:this.getMatchedResults().length>0,matches:this.getDatasetSize(),searchterm:this.getSearchTerm(),selectall:this.selectAllResultsLink()});(0,_templates.replaceNodeContents)(this.getHTMLElements().searchDropdown,html,js),this.searchInput.removeAttribute("aria-activedescendant")}selectAllResultsLink(){return _url.default.relativeUrl("/grade/report/user/index.php",{id:this.courseID,userid:0,searchvalue:this.getSearchTerm()},!1)}selectOneLink(userID){return _url.default.relativeUrl("/grade/report/user/index.php",{id:this.courseID,searchvalue:this.getSearchTerm(),userid:userID},!1)}fetchDataset(){const gts="string"==typeof this.groupID&&""===this.groupID?0:this.groupID;return Repository.userFetch(this.courseID,gts).then((r=>r.users))}}return _exports.default=User,_exports.default}));
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_user=_interopRequireDefault(_user),_url=_interopRequireDefault(_url),Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Repository);class User extends _user.default{constructor(){super()}static init(){return new User}async renderDropdown(){const{html:html,js:js}=await(0,_templates.renderForPromise)("core_user/comboboxsearch/resultset",{users:this.getMatchedResults().slice(0,5),hasresults:this.getMatchedResults().length>0,instance:this.instance,matches:this.getDatasetSize(),searchterm:this.getSearchTerm(),selectall:this.selectAllResultsLink()});(0,_templates.replaceNodeContents)(this.getHTMLElements().searchDropdown,html,js),this.searchInput.removeAttribute("aria-activedescendant")}selectAllResultsLink(){return _url.default.relativeUrl("/grade/report/user/index.php",{id:this.courseID,userid:0,searchvalue:this.getSearchTerm()},!1)}selectOneLink(userID){return _url.default.relativeUrl("/grade/report/user/index.php",{id:this.courseID,searchvalue:this.getSearchTerm(),userid:userID},!1)}fetchDataset(){const gts="string"==typeof this.groupID&&""===this.groupID?0:this.groupID;return Repository.userFetch(this.courseID,gts).then((r=>r.users))}}return _exports.default=User,_exports.default}));
|
||||
|
||||
//# sourceMappingURL=user.min.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"user.min.js","sources":["../src/user.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for learners within the user report.\n *\n * @module gradereport_user/user\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport Url from 'core/url';\nimport {renderForPromise, replaceNodeContents} from 'core/templates';\nimport * as Repository from 'core_grades/searchwidget/repository';\n\nexport default class User extends UserSearch {\n\n constructor() {\n super();\n }\n\n static init() {\n return new User();\n }\n\n /**\n * Build the content then replace the node.\n */\n async renderDropdown() {\n const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {\n users: this.getMatchedResults().slice(0, 5),\n hasresults: this.getMatchedResults().length > 0,\n matches: this.getDatasetSize(),\n searchterm: this.getSearchTerm(),\n selectall: this.selectAllResultsLink(),\n });\n replaceNodeContents(this.getHTMLElements().searchDropdown, html, js);\n // Remove aria-activedescendant when the available options change.\n this.searchInput.removeAttribute('aria-activedescendant');\n }\n\n /**\n * Build up the view all link.\n *\n * @returns {string|*}\n */\n selectAllResultsLink() {\n return Url.relativeUrl('/grade/report/user/index.php', {\n id: this.courseID,\n userid: 0,\n searchvalue: this.getSearchTerm()\n }, false);\n }\n\n /**\n * Build up the view all link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n return Url.relativeUrl('/grade/report/user/index.php', {\n id: this.courseID,\n searchvalue: this.getSearchTerm(),\n userid: userID,\n }, false);\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n // Small typing checks as sometimes groups don't exist therefore the element returns a empty string.\n const gts = typeof (this.groupID) === \"string\" && this.groupID === '' ? 0 : this.groupID;\n return Repository.userFetch(this.courseID, gts).then((r) => r.users);\n }\n}\n"],"names":["User","UserSearch","constructor","html","js","users","this","getMatchedResults","slice","hasresults","length","matches","getDatasetSize","searchterm","getSearchTerm","selectall","selectAllResultsLink","getHTMLElements","searchDropdown","searchInput","removeAttribute","Url","relativeUrl","id","courseID","userid","searchvalue","selectOneLink","userID","fetchDataset","gts","groupID","Repository","userFetch","then","r"],"mappings":";;;;;;;q0BA2BqBA,aAAaC,cAE9BC,2CAKW,IAAIF,kCAOLG,KAACA,KAADC,GAAOA,UAAY,+BAAiB,qCAAsC,CAC5EC,MAAOC,KAAKC,oBAAoBC,MAAM,EAAG,GACzCC,WAAYH,KAAKC,oBAAoBG,OAAS,EAC9CC,QAASL,KAAKM,iBACdC,WAAYP,KAAKQ,gBACjBC,UAAWT,KAAKU,4DAEAV,KAAKW,kBAAkBC,eAAgBf,KAAMC,SAE5De,YAAYC,gBAAgB,yBAQrCJ,8BACWK,aAAIC,YAAY,+BAAgC,CACnDC,GAAIjB,KAAKkB,SACTC,OAAQ,EACRC,YAAapB,KAAKQ,kBACnB,GASPa,cAAcC,eACHP,aAAIC,YAAY,+BAAgC,CACnDC,GAAIjB,KAAKkB,SACTE,YAAapB,KAAKQ,gBAClBW,OAAQG,SACT,GAQPC,qBAEUC,IAAgC,iBAAlBxB,KAAKyB,SAA0C,KAAjBzB,KAAKyB,QAAiB,EAAIzB,KAAKyB,eAC1EC,WAAWC,UAAU3B,KAAKkB,SAAUM,KAAKI,MAAMC,GAAMA,EAAE9B"}
|
||||
{"version":3,"file":"user.min.js","sources":["../src/user.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Allow the user to search for learners within the user report.\n *\n * @module gradereport_user/user\n * @copyright 2023 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport Url from 'core/url';\nimport {renderForPromise, replaceNodeContents} from 'core/templates';\nimport * as Repository from 'core_grades/searchwidget/repository';\n\nexport default class User extends UserSearch {\n\n constructor() {\n super();\n }\n\n static init() {\n return new User();\n }\n\n /**\n * Build the content then replace the node.\n */\n async renderDropdown() {\n const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {\n users: this.getMatchedResults().slice(0, 5),\n hasresults: this.getMatchedResults().length > 0,\n instance: this.instance,\n matches: this.getDatasetSize(),\n searchterm: this.getSearchTerm(),\n selectall: this.selectAllResultsLink(),\n });\n replaceNodeContents(this.getHTMLElements().searchDropdown, html, js);\n // Remove aria-activedescendant when the available options change.\n this.searchInput.removeAttribute('aria-activedescendant');\n }\n\n /**\n * Build up the view all link.\n *\n * @returns {string|*}\n */\n selectAllResultsLink() {\n return Url.relativeUrl('/grade/report/user/index.php', {\n id: this.courseID,\n userid: 0,\n searchvalue: this.getSearchTerm()\n }, false);\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n return Url.relativeUrl('/grade/report/user/index.php', {\n id: this.courseID,\n searchvalue: this.getSearchTerm(),\n userid: userID,\n }, false);\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n // Small typing checks as sometimes groups don't exist therefore the element returns a empty string.\n const gts = typeof (this.groupID) === \"string\" && this.groupID === '' ? 0 : this.groupID;\n return Repository.userFetch(this.courseID, gts).then((r) => r.users);\n }\n}\n"],"names":["User","UserSearch","constructor","html","js","users","this","getMatchedResults","slice","hasresults","length","instance","matches","getDatasetSize","searchterm","getSearchTerm","selectall","selectAllResultsLink","getHTMLElements","searchDropdown","searchInput","removeAttribute","Url","relativeUrl","id","courseID","userid","searchvalue","selectOneLink","userID","fetchDataset","gts","groupID","Repository","userFetch","then","r"],"mappings":";;;;;;;q0BA2BqBA,aAAaC,cAE9BC,2CAKW,IAAIF,kCAOLG,KAACA,KAADC,GAAOA,UAAY,+BAAiB,qCAAsC,CAC5EC,MAAOC,KAAKC,oBAAoBC,MAAM,EAAG,GACzCC,WAAYH,KAAKC,oBAAoBG,OAAS,EAC9CC,SAAUL,KAAKK,SACfC,QAASN,KAAKO,iBACdC,WAAYR,KAAKS,gBACjBC,UAAWV,KAAKW,4DAEAX,KAAKY,kBAAkBC,eAAgBhB,KAAMC,SAE5DgB,YAAYC,gBAAgB,yBAQrCJ,8BACWK,aAAIC,YAAY,+BAAgC,CACnDC,GAAIlB,KAAKmB,SACTC,OAAQ,EACRC,YAAarB,KAAKS,kBACnB,GASPa,cAAcC,eACHP,aAAIC,YAAY,+BAAgC,CACnDC,GAAIlB,KAAKmB,SACTE,YAAarB,KAAKS,gBAClBW,OAAQG,SACT,GAQPC,qBAEUC,IAAgC,iBAAlBzB,KAAK0B,SAA0C,KAAjB1B,KAAK0B,QAAiB,EAAI1B,KAAK0B,eAC1EC,WAAWC,UAAU5B,KAAKmB,SAAUM,KAAKI,MAAMC,GAAMA,EAAE/B"}
|
||||
@@ -43,7 +43,7 @@ export default class Group extends GroupSearch {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up the view all link that is dedicated to a particular result.
|
||||
* Build up the link that is dedicated to a particular result.
|
||||
*
|
||||
* @param {Number} groupID The ID of the group selected.
|
||||
* @returns {string|*}
|
||||
|
||||
@@ -42,6 +42,7 @@ export default class User extends UserSearch {
|
||||
const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {
|
||||
users: this.getMatchedResults().slice(0, 5),
|
||||
hasresults: this.getMatchedResults().length > 0,
|
||||
instance: this.instance,
|
||||
matches: this.getDatasetSize(),
|
||||
searchterm: this.getSearchTerm(),
|
||||
selectall: this.selectAllResultsLink(),
|
||||
@@ -65,7 +66,7 @@ export default class User extends UserSearch {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up the view all link that is dedicated to a particular result.
|
||||
* Build up the link that is dedicated to a particular result.
|
||||
*
|
||||
* @param {Number} userID The ID of the user selected.
|
||||
* @returns {string|*}
|
||||
|
||||
@@ -104,6 +104,7 @@ class gradereport_user_renderer extends plugin_renderer_base {
|
||||
|
||||
$data = [
|
||||
'currentvalue' => $currentvalue,
|
||||
'instance' => rand(),
|
||||
'resetlink' => $resetlink->out(false),
|
||||
'name' => 'userid',
|
||||
'value' => $submitteduserid ?? '',
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
define("core_group/comboboxsearch/group",["exports","core/comboboxsearch/search_combobox","core_group/comboboxsearch/repository","core/templates","core/utils","core/notification"],(function(_exports,_search_combobox,_repository,_templates,_utils,_notification){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_search_combobox=_interopRequireDefault(_search_combobox),_notification=_interopRequireDefault(_notification);class GroupSearch extends _search_combobox.default{constructor(){super(),_defineProperty(this,"courseID",void 0),_defineProperty(this,"bannedFilterFields",["id","link","groupimageurl"]),this.selectors={...this.selectors,courseid:'[data-region="courseid"]',placeholder:'.groupsearchdropdown [data-region="searchplaceholder"]'};const component=document.querySelector(this.componentSelector());this.courseID=component.querySelector(this.selectors.courseid).dataset.courseid;const searchValueElement=this.component.querySelector("#".concat(this.searchInput.dataset.inputElement));searchValueElement.addEventListener("change",(()=>{this.toggleDropdown();const valueElement=this.component.querySelector("#".concat(this.combobox.dataset.inputElement));valueElement.value!==searchValueElement.value&&(valueElement.value=searchValueElement.value,valueElement.dispatchEvent(new Event("change",{bubbles:!0}))),searchValueElement.value=""})),this.$component.on("hide.bs.dropdown",(()=>{this.searchInput.removeAttribute("aria-activedescendant");const listbox=document.querySelector("#".concat(this.searchInput.getAttribute("aria-controls"),'[role="listbox"]'));listbox.querySelectorAll('.active[role="option"]').forEach((option=>{option.classList.remove("active")})),listbox.scrollTop=0,setTimeout((()=>{""!==this.searchInput.value&&(this.searchInput.value="",this.searchInput.dispatchEvent(new Event("input",{bubbles:!0})))}))})),this.renderDefault().catch(_notification.default.exception)}static init(){return new GroupSearch}componentSelector(){return".group-search"}dropdownSelector(){return".groupsearchdropdown"}async renderDropdown(){const{html:html,js:js}=await(0,_templates.renderForPromise)("core_group/comboboxsearch/resultset",{groups:this.getMatchedResults(),hasresults:this.getMatchedResults().length>0,searchterm:this.getSearchTerm()});(0,_templates.replaceNodeContents)(this.selectors.placeholder,html,js),this.searchInput.removeAttribute("aria-activedescendant")}async renderDefault(){this.setMatchedResults(await this.filterDataset(await this.getDataset())),this.filterMatchDataset(),await this.renderDropdown(),this.updateNodes(),this.registerInputEvents()}async fetchDataset(){return await(0,_repository.groupFetch)(this.courseID).then((r=>r.groups))}async filterDataset(filterableData){return""===this.getPreppedSearchTerm()?filterableData:filterableData.filter((group=>Object.keys(group).some((key=>""!==group[key]&&!this.bannedFilterFields.includes(key)&&group[key].toString().toLowerCase().includes(this.getPreppedSearchTerm())))))}filterMatchDataset(){this.setMatchedResults(this.getMatchedResults().map((group=>({id:group.id,name:group.name,groupimageurl:group.groupimageurl}))))}registerInputEvents(){this.searchInput.addEventListener("input",(0,_utils.debounce)((async()=>{this.setSearchTerms(this.searchInput.value),""===this.searchInput.value?this.clearSearchButton.classList.add("d-none"):this.clearSearchButton.classList.remove("d-none"),await this.filterrenderpipe()}),300))}async clickHandler(e){e.target.closest(this.selectors.clearSearch)&&(e.stopPropagation(),this.searchInput.value="",this.setSearchTerms(this.searchInput.value),this.searchInput.focus(),this.clearSearchButton.classList.add("d-none"),await this.filterrenderpipe())}changeHandler(e){window.location=this.selectOneLink(e.target.value)}registerInputHandlers(){this.searchInput.addEventListener("input",(0,_utils.debounce)((()=>{this.setSearchTerms(this.searchInput.value),""===this.getSearchTerm()?this.clearSearchButton.classList.add("d-none"):this.clearSearchButton.classList.remove("d-none")}),300))}selectOneLink(groupID){throw new Error("selectOneLink(".concat(groupID,") must be implemented in ").concat(this.constructor.name))}}return _exports.default=GroupSearch,_exports.default}));
|
||||
define("core_group/comboboxsearch/group",["exports","core/comboboxsearch/search_combobox","core_group/comboboxsearch/repository","core/templates","core/utils","core/notification"],(function(_exports,_search_combobox,_repository,_templates,_utils,_notification){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_search_combobox=_interopRequireDefault(_search_combobox),_notification=_interopRequireDefault(_notification);class GroupSearch extends _search_combobox.default{constructor(){super(),_defineProperty(this,"courseID",void 0),_defineProperty(this,"bannedFilterFields",["id","link","groupimageurl"]),this.selectors={...this.selectors,courseid:'[data-region="courseid"]',placeholder:'.groupsearchdropdown [data-region="searchplaceholder"]'};const component=document.querySelector(this.componentSelector());this.courseID=component.querySelector(this.selectors.courseid).dataset.courseid,this.instance=component.querySelector(this.selectors.instance).dataset.instance;const searchValueElement=this.component.querySelector("#".concat(this.searchInput.dataset.inputElement));searchValueElement.addEventListener("change",(()=>{this.toggleDropdown();const valueElement=this.component.querySelector("#".concat(this.combobox.dataset.inputElement));valueElement.value!==searchValueElement.value&&(valueElement.value=searchValueElement.value,valueElement.dispatchEvent(new Event("change",{bubbles:!0}))),searchValueElement.value=""})),this.$component.on("hide.bs.dropdown",(()=>{this.searchInput.removeAttribute("aria-activedescendant");const listbox=document.querySelector("#".concat(this.searchInput.getAttribute("aria-controls"),'[role="listbox"]'));listbox.querySelectorAll('.active[role="option"]').forEach((option=>{option.classList.remove("active")})),listbox.scrollTop=0,setTimeout((()=>{""!==this.searchInput.value&&(this.searchInput.value="",this.searchInput.dispatchEvent(new Event("input",{bubbles:!0})))}))})),this.renderDefault().catch(_notification.default.exception)}static init(){return new GroupSearch}componentSelector(){return".group-search"}dropdownSelector(){return".groupsearchdropdown"}async renderDropdown(){const{html:html,js:js}=await(0,_templates.renderForPromise)("core_group/comboboxsearch/resultset",{groups:this.getMatchedResults(),hasresults:this.getMatchedResults().length>0,instance:this.instance,searchterm:this.getSearchTerm()});(0,_templates.replaceNodeContents)(this.selectors.placeholder,html,js),this.searchInput.removeAttribute("aria-activedescendant")}async renderDefault(){this.setMatchedResults(await this.filterDataset(await this.getDataset())),this.filterMatchDataset(),await this.renderDropdown(),this.updateNodes()}async fetchDataset(){return await(0,_repository.groupFetch)(this.courseID).then((r=>r.groups))}async filterDataset(filterableData){return""===this.getPreppedSearchTerm()?filterableData:filterableData.filter((group=>Object.keys(group).some((key=>""!==group[key]&&!this.bannedFilterFields.includes(key)&&group[key].toString().toLowerCase().includes(this.getPreppedSearchTerm())))))}filterMatchDataset(){this.setMatchedResults(this.getMatchedResults().map((group=>({id:group.id,name:group.name,groupimageurl:group.groupimageurl}))))}async clickHandler(e){e.target.closest(this.selectors.clearSearch)&&(e.stopPropagation(),this.searchInput.value="",this.setSearchTerms(this.searchInput.value),this.searchInput.focus(),this.clearSearchButton.classList.add("d-none"),await this.filterrenderpipe())}changeHandler(e){window.location=this.selectOneLink(e.target.value)}registerInputHandlers(){this.searchInput.addEventListener("input",(0,_utils.debounce)((async()=>{this.setSearchTerms(this.searchInput.value),""===this.getSearchTerm()?this.clearSearchButton.classList.add("d-none"):this.clearSearchButton.classList.remove("d-none"),await this.filterrenderpipe()}),300))}selectOneLink(groupID){throw new Error("selectOneLink(".concat(groupID,") must be implemented in ").concat(this.constructor.name))}}return _exports.default=GroupSearch,_exports.default}));
|
||||
|
||||
//# sourceMappingURL=group.min.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -39,6 +39,8 @@ export default class GroupSearch extends search_combobox {
|
||||
};
|
||||
const component = document.querySelector(this.componentSelector());
|
||||
this.courseID = component.querySelector(this.selectors.courseid).dataset.courseid;
|
||||
// Override the instance since the body is built outside the constructor for the combobox.
|
||||
this.instance = component.querySelector(this.selectors.instance).dataset.instance;
|
||||
|
||||
const searchValueElement = this.component.querySelector(`#${this.searchInput.dataset.inputElement}`);
|
||||
searchValueElement.addEventListener('change', () => {
|
||||
@@ -103,6 +105,7 @@ export default class GroupSearch extends search_combobox {
|
||||
const {html, js} = await renderForPromise('core_group/comboboxsearch/resultset', {
|
||||
groups: this.getMatchedResults(),
|
||||
hasresults: this.getMatchedResults().length > 0,
|
||||
instance: this.instance,
|
||||
searchterm: this.getSearchTerm(),
|
||||
});
|
||||
replaceNodeContents(this.selectors.placeholder, html, js);
|
||||
@@ -120,7 +123,6 @@ export default class GroupSearch extends search_combobox {
|
||||
await this.renderDropdown();
|
||||
|
||||
this.updateNodes();
|
||||
this.registerInputEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,26 +168,6 @@ export default class GroupSearch extends search_combobox {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle any keyboard inputs.
|
||||
*/
|
||||
registerInputEvents() {
|
||||
// Register & handle the text input.
|
||||
this.searchInput.addEventListener('input', debounce(async() => {
|
||||
this.setSearchTerms(this.searchInput.value);
|
||||
// We can also require a set amount of input before search.
|
||||
if (this.searchInput.value === '') {
|
||||
// Hide the "clear" search button in the search bar.
|
||||
this.clearSearchButton.classList.add('d-none');
|
||||
} else {
|
||||
// Display the "clear" search button in the search bar.
|
||||
this.clearSearchButton.classList.remove('d-none');
|
||||
}
|
||||
// User has given something for us to filter against.
|
||||
await this.filterrenderpipe();
|
||||
}, 300));
|
||||
}
|
||||
|
||||
/**
|
||||
* The handler for when a user interacts with the component.
|
||||
*
|
||||
@@ -218,7 +200,7 @@ export default class GroupSearch extends search_combobox {
|
||||
*/
|
||||
registerInputHandlers() {
|
||||
// Register & handle the text input.
|
||||
this.searchInput.addEventListener('input', debounce(() => {
|
||||
this.searchInput.addEventListener('input', debounce(async() => {
|
||||
this.setSearchTerms(this.searchInput.value);
|
||||
// We can also require a set amount of input before search.
|
||||
if (this.getSearchTerm() === '') {
|
||||
@@ -228,11 +210,14 @@ export default class GroupSearch extends search_combobox {
|
||||
// Display the "clear" search button in the search bar.
|
||||
this.clearSearchButton.classList.remove('d-none');
|
||||
}
|
||||
// User has given something for us to filter against.
|
||||
await this.filterrenderpipe();
|
||||
}, 300));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up the view all link that is dedicated to a particular result.
|
||||
* We will call this function when a user interacts with the combobox to redirect them to show their results in the page.
|
||||
*
|
||||
* @param {Number} groupID The ID of the group selected.
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
Context variables required for this template:
|
||||
* groups - Our returned groups to render.
|
||||
* instance - The instance ID of the combo box.
|
||||
* searchterm - The entered text to find these results.
|
||||
* hasgroups - Allow the handling where no users exist for the returned search term.
|
||||
|
||||
@@ -35,6 +36,7 @@
|
||||
"link": "http://foo.bar/grade/report/grader/index.php?id=42&userid=3"
|
||||
}
|
||||
],
|
||||
"instance": 25,
|
||||
"searchterm": "Foo",
|
||||
"hasresults": true
|
||||
}
|
||||
|
||||
@@ -29,42 +29,27 @@
|
||||
}
|
||||
}}
|
||||
<div class="flex-column h-100 w-100">
|
||||
<span class="d-none" data-region="courseid" data-courseid="{{courseid}}" aria-hidden="true"></span>
|
||||
<span class="d-none" data-region="groupid" data-groupid="{{groupid}}" aria-hidden="true"></span>
|
||||
<span class="d-none" data-region="courseid" data-courseid="{{courseid}}"></span>
|
||||
<span class="d-none" data-region="groupid" data-groupid="{{groupid}}"></span>
|
||||
<span class="d-none" data-region="instance" data-instance="{{instance}}"></span>
|
||||
|
||||
{{#currentvalue}}
|
||||
{{< core/search_input_auto }}
|
||||
{{$label}}{{#str}}
|
||||
searchgroups, core
|
||||
{{/str}}{{/label}}
|
||||
{{$value}}{{currentvalue}}{{/value}}
|
||||
{{$additionalattributes}}
|
||||
role="combobox"
|
||||
aria-expanded="true"
|
||||
aria-controls="groups-result-listbox"
|
||||
aria-autocomplete="list"
|
||||
data-input-element="input-{{uniqid}}"
|
||||
{{/additionalattributes}}
|
||||
{{/ core/search_input_auto }}
|
||||
{{/currentvalue}}
|
||||
{{^currentvalue}}
|
||||
{{< core/search_input_auto }}
|
||||
{{$label}}{{#str}}
|
||||
searchgroups, core
|
||||
{{/str}}{{/label}}
|
||||
{{$placeholder}}{{#str}}
|
||||
searchgroups, core
|
||||
{{/str}}{{/placeholder}}
|
||||
{{$additionalattributes}}
|
||||
role="combobox"
|
||||
aria-expanded="true"
|
||||
aria-controls="groups-result-listbox"
|
||||
aria-autocomplete="list"
|
||||
data-input-element="input-{{uniqid}}"
|
||||
{{/additionalattributes}}
|
||||
{{/ core/search_input_auto }}
|
||||
{{/currentvalue}}
|
||||
<input type="hidden" name="search" id="input-{{uniqid}}"/>
|
||||
{{< core/search_input_auto }}
|
||||
{{$label}}{{#str}}
|
||||
searchgroups, core
|
||||
{{/str}}{{/label}}
|
||||
{{$placeholder}}{{#str}}
|
||||
searchgroups, core
|
||||
{{/str}}{{/placeholder}}
|
||||
{{$value}}{{currentvalue}}{{/value}}
|
||||
{{$additionalattributes}}
|
||||
role="combobox"
|
||||
aria-expanded="true"
|
||||
aria-controls="groups-{{instance}}-result-listbox"
|
||||
aria-autocomplete="list"
|
||||
data-input-element="input-{{uniqid}}-{{instance}}"
|
||||
{{/additionalattributes}}
|
||||
{{/ core/search_input_auto }}
|
||||
<input type="hidden" name="search" id="input-{{uniqid}}-{{instance}}"/>
|
||||
|
||||
<div data-region="searchplaceholder"></div>
|
||||
</div>
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -30,6 +30,7 @@ export default class {
|
||||
selectors = {
|
||||
component: this.componentSelector(),
|
||||
toggle: '[data-toggle="dropdown"]',
|
||||
instance: '[data-region="instance"]',
|
||||
input: '[data-action="search"]',
|
||||
clearSearch: '[data-action="clearsearch"]',
|
||||
dropdown: this.dropdownSelector(),
|
||||
@@ -62,6 +63,7 @@ export default class {
|
||||
|
||||
// DOM nodes that persist.
|
||||
component = document.querySelector(this.selectors.component);
|
||||
instance = this.component.dataset.instance;
|
||||
toggle = this.component.querySelector(this.selectors.toggle);
|
||||
searchInput = this.component.querySelector(this.selectors.input);
|
||||
searchDropdown = this.component.querySelector(this.selectors.dropdown);
|
||||
@@ -74,7 +76,10 @@ export default class {
|
||||
this.setSearchTerms(this.searchInput?.value ?? '');
|
||||
// Begin handling the base search component.
|
||||
this.registerClickHandlers();
|
||||
|
||||
// Conditionally set up the input handler since we don't know exactly how we were called.
|
||||
// If the combobox is rendered later, then you'll need to call this.registerInputHandlers() manually.
|
||||
// An example of this is the collapse columns in the gradebook.
|
||||
if (this.searchInput !== null) {
|
||||
this.registerInputHandlers();
|
||||
this.registerChangeHandlers();
|
||||
|
||||
@@ -30,7 +30,9 @@ use templatable;
|
||||
*/
|
||||
class comboboxsearch implements renderable, templatable {
|
||||
|
||||
/** @var bool $renderlater Should the dropdown render straightaway? */
|
||||
/** @var bool $renderlater Should the dropdown render straightaway? We sometimes need to output the component without all of the
|
||||
* data and leave the rendering of any defaults and actual data to the caller. We will give you a basic placeholder that can
|
||||
* then be easily replaced.*/
|
||||
protected $renderlater;
|
||||
|
||||
/** @var string $buttoncontent What is the content of the "Button" that users will always see. */
|
||||
@@ -68,16 +70,16 @@ class comboboxsearch implements renderable, templatable {
|
||||
*
|
||||
* @param bool $renderlater How we figure out if we should render the template instantly.
|
||||
* @param string $buttoncontent What gets placed in the button.
|
||||
* @param ?string $dropdowncontent What can be placed in the dropdown if we are rendering now.
|
||||
* @param ?string $dropdowncontent What will be placed in the dropdown if we are rendering now.
|
||||
* @param ?string $parentclasses The classes that can be added that the bootstrap events are attached to.
|
||||
* @param ?string $buttonclasses Any special classes that may be needed.
|
||||
* @param ?string $dropdownclasses Any special classes that may be needed.
|
||||
* @param ?string $buttonheader If the button item in the tertiary nav needs an extra top header for context.
|
||||
* @param ?string $buttonheader Sometimes we want extra context for a button before it is shown, basically a pseudo header.
|
||||
* @param ?bool $usebutton If we want the mustache to add the button roles for us or do we have another aria role node?
|
||||
* @param ?string $label The label of the combobox.
|
||||
* @param ?string $name The name of the input element representing the combobox.
|
||||
* @param ?string $value The value of the input element representing the combobox.
|
||||
* @throws moodle_exception If the implementor incorrectly call this module.
|
||||
* @throws moodle_exception If the implementor incorrectly calls this module.
|
||||
*/
|
||||
public function __construct(
|
||||
bool $renderlater,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
* name - The name of the input element representing the combobox.
|
||||
* value - The value of the input element representing the combobox.
|
||||
* renderlater - This determines if we show a placeholder whilst fetching content to replace within the placeholder region
|
||||
* buttonheader - The header to be shown above the button
|
||||
* buttoncontent - The string to be shown to users to trigger the dropdown
|
||||
* usebutton - If we want to use a button to trigger the dropdown, or just the dropdown itself
|
||||
* dropdowncontent - If rendering now, The content within the dropdown
|
||||
@@ -35,8 +36,9 @@
|
||||
"name": "input-1",
|
||||
"value": "0",
|
||||
"renderlater": false,
|
||||
"buttonheader": "Example:",
|
||||
"usebutton": true,
|
||||
"buttoncontent": "Example dropdown button",
|
||||
"buttoncontent": "Dropdown button",
|
||||
"dropdowncontent": "Some body content to render right now",
|
||||
"parentclasses": "my-dropdown",
|
||||
"buttonclasses": "my-button",
|
||||
@@ -47,7 +49,7 @@
|
||||
{{#buttonheader}}
|
||||
<small>{{.}}</small>
|
||||
{{/buttonheader}}
|
||||
<div class="{{#parentclasses}}{{.}}{{/parentclasses}} dropdown">
|
||||
<div class="{{#parentclasses}}{{.}}{{/parentclasses}} dropdown" data-instance="{{instance}}">
|
||||
|
||||
{{#usebutton}}
|
||||
<div tabindex="0"
|
||||
@@ -56,7 +58,7 @@
|
||||
role="combobox"
|
||||
aria-haspopup="dialog"
|
||||
aria-controls="dialog-{{instance}}-{{uniqid}}"
|
||||
class="{{#buttonclasses}}{{.}}{{/buttonclasses}} btn dropdown-toggle keep-open d-flex text-left align-items-center p-0 font-weight-bold"
|
||||
class="{{#buttonclasses}}{{.}}{{/buttonclasses}} btn dropdown-toggle d-flex text-left align-items-center p-0 font-weight-bold"
|
||||
aria-label="{{label}}"
|
||||
data-input-element="input-{{instance}}-{{uniqid}}">
|
||||
{{{buttoncontent}}}
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
Context variables required for this template:
|
||||
* id - Result item system ID.
|
||||
* instance - The instance ID of the combo box.
|
||||
* name - Result item human readable name.
|
||||
* link - The link used to redirect upon self to show only this specific result item.
|
||||
|
||||
The shorttext pragma can be used to provide a short text for the result item.
|
||||
This is especially useful when the result item content contains html tags.
|
||||
@@ -27,11 +27,12 @@
|
||||
Example context (json):
|
||||
{
|
||||
"id": 2,
|
||||
"instance": 25,
|
||||
"name": "Foo bar"
|
||||
}
|
||||
}}
|
||||
<li
|
||||
id="result-{{id}}"
|
||||
id="result-{{instance}}-{{id}}"
|
||||
class="w-100 dropdown-item d-flex px-0 align-items-center"
|
||||
role="option"
|
||||
{{! aria.js would use the data-short-text attribute if it is provided. }}
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
Wrapping template for returned result items.
|
||||
|
||||
Context variables required for this template:
|
||||
* instance - The instance ID of the combo box.
|
||||
* results - Our returned results to render.
|
||||
* searchterm - The entered text to find these results.
|
||||
* hasresult - Allow the handling where no results exist for the returned search term.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"instance": 25,
|
||||
"results": [
|
||||
{
|
||||
"id": 2,
|
||||
@@ -39,7 +41,7 @@
|
||||
}}
|
||||
<div class="d-flex flex-column mh-100 h-100">
|
||||
<ul
|
||||
id="{{$listid}}list{{/listid}}-result-listbox"
|
||||
id="{{$listid}}list{{/listid}}-{{instance}}-result-listbox"
|
||||
class="searchresultitemscontainer d-flex flex-column mw-100 position-relative py-2 list-group h-100 mx-0 {{$listclasses}}{{/listclasses}}"
|
||||
role="listbox"
|
||||
data-region="search-result-items-container"
|
||||
|
||||
@@ -28,39 +28,22 @@
|
||||
}}
|
||||
<div class="flex-column h-100 w-100">
|
||||
<span class="d-none" data-region="courseid" data-courseid="{{courseid}}" aria-hidden="true"></span>
|
||||
|
||||
{{#currentvalue}}
|
||||
{{< core/search_input_auto }}
|
||||
{{$label}}{{#str}}
|
||||
searchitems, core
|
||||
{{/str}}{{/label}}
|
||||
{{$value}}{{currentvalue}}{{/value}}
|
||||
{{$additionalattributes}}
|
||||
role="combobox"
|
||||
aria-expanded="true"
|
||||
aria-controls="list-result-listbox"
|
||||
aria-autocomplete="list"
|
||||
data-input-element="result-input-{{uniqid}}"
|
||||
{{/additionalattributes}}
|
||||
{{/ core/search_input_auto }}
|
||||
{{/currentvalue}}
|
||||
{{^currentvalue}}
|
||||
{{< core/search_input_auto }}
|
||||
{{$label}}{{#str}}
|
||||
searchitems, core
|
||||
{{/str}}{{/label}}
|
||||
{{$placeholder}}{{#str}}
|
||||
searchitems, core
|
||||
{{/str}}{{/placeholder}}
|
||||
{{$additionalattributes}}
|
||||
role="combobox"
|
||||
aria-expanded="true"
|
||||
aria-controls="list-result-listbox"
|
||||
aria-autocomplete="list"
|
||||
data-input-element="result-input-{{uniqid}}"
|
||||
{{/additionalattributes}}
|
||||
{{/ core/search_input_auto }}
|
||||
{{/currentvalue}}
|
||||
<input type="hidden" name="search" id="result-input-{{uniqid}}"/>
|
||||
{{< core/search_input_auto }}
|
||||
{{$label}}{{#str}}
|
||||
searchitems, core
|
||||
{{/str}}{{/label}}
|
||||
{{$placeholder}}{{#str}}
|
||||
searchitems, core
|
||||
{{/str}}{{/placeholder}}
|
||||
{{$value}}{{currentvalue}}{{/value}}
|
||||
{{$additionalattributes}}
|
||||
role="combobox"
|
||||
aria-expanded="true"
|
||||
aria-controls="list-{{instance}}-result-listbox"
|
||||
aria-autocomplete="list"
|
||||
data-input-element="result-input-{{uniqid}}-{{instance}}"
|
||||
{{/additionalattributes}}
|
||||
{{/ core/search_input_auto }}
|
||||
<input type="hidden" name="search" id="result-input-{{uniqid}}-{{instance}}"/>
|
||||
<div data-region="searchplaceholder"></div>
|
||||
</div>
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -55,9 +55,9 @@ export default class UserSearch extends search_combobox {
|
||||
resetPageButton: '[data-action="resetpage"]',
|
||||
};
|
||||
|
||||
const component = document.querySelector(this.componentSelector());
|
||||
this.courseID = component.querySelector(this.selectors.courseid).dataset.courseid;
|
||||
this.courseID = this.component.querySelector(this.selectors.courseid).dataset.courseid;
|
||||
this.groupID = document.querySelector(this.selectors.groupid)?.dataset?.groupid;
|
||||
this.instance = this.component.querySelector(this.selectors.instance).dataset.instance;
|
||||
|
||||
// We need to render some content by default for ARIA purposes.
|
||||
this.renderDefault();
|
||||
@@ -92,6 +92,7 @@ export default class UserSearch extends search_combobox {
|
||||
const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {
|
||||
users: this.getMatchedResults().slice(0, 5),
|
||||
hasresults: this.getMatchedResults().length > 0,
|
||||
instance: this.instance,
|
||||
matches: this.getMatchedResults().length,
|
||||
searchterm: this.getSearchTerm(),
|
||||
selectall: this.selectAllResultsLink(),
|
||||
@@ -261,6 +262,7 @@ export default class UserSearch extends search_combobox {
|
||||
|
||||
/**
|
||||
* Build up the view all link that is dedicated to a particular result.
|
||||
* We will call this function when a user interacts with the combobox to redirect them to show their results in the page.
|
||||
*
|
||||
* @param {Number} userID The ID of the user selected.
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
Wrapping template for returned result items.
|
||||
|
||||
Context variables required for this template:
|
||||
* instance - The instance ID of the combo box.
|
||||
* users - Our returned users to render.
|
||||
* found - Count of the found users.
|
||||
* total - Total count of users within this report.
|
||||
@@ -26,6 +27,7 @@
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"instance": 25,
|
||||
"users": [
|
||||
{
|
||||
"id": 2,
|
||||
@@ -58,7 +60,7 @@
|
||||
{{$selectall}}
|
||||
{{#selectall}}
|
||||
<li
|
||||
id="result-row-0"
|
||||
id="result-row-{{instance}}-0"
|
||||
class="w-100 p-1 border-top bottom-0 position-sticky dropdown-item d-flex small p-3"
|
||||
role="option"
|
||||
{{! The data-short-text attribute is provided so that aria.js would use it rather than the whole content. }}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
}}
|
||||
<span class="d-none" data-region="courseid" data-courseid="{{courseid}}"></span>
|
||||
<span class="d-none" data-region="groupid" data-groupid="{{group}}"></span>
|
||||
<span class="d-none" data-region="instance" data-instance="{{instance}}"></span>
|
||||
{{< core/search_input_auto }}
|
||||
{{$label}}{{#str}}searchusers, core{{/str}}{{/label}}
|
||||
{{$placeholder}}{{#str}}searchusers, core{{/str}}{{/placeholder}}
|
||||
@@ -46,10 +47,10 @@
|
||||
{{$additionalattributes}}
|
||||
role="combobox"
|
||||
aria-expanded="false"
|
||||
aria-controls="user-result-listbox"
|
||||
aria-controls="user-{{instance}}-result-listbox"
|
||||
aria-autocomplete="list"
|
||||
aria-haspopup="listbox"
|
||||
data-input-element="user-input-{{uniqid}}"
|
||||
data-input-element="user-input-{{uniqid}}-{{instance}}"
|
||||
{{/additionalattributes}}
|
||||
{{/ core/search_input_auto }}
|
||||
{{#currentvalue}}
|
||||
@@ -57,4 +58,4 @@
|
||||
{{#str}}clear{{/str}}
|
||||
</a>
|
||||
{{/currentvalue}}
|
||||
<input type="hidden" name="{{name}}" value="{{value}}" id="user-input-{{uniqid}}"/>
|
||||
<input type="hidden" name="{{name}}" value="{{value}}" id="user-input-{{uniqid}}-{{instance}}"/>
|
||||
|
||||
Reference in New Issue
Block a user