diff --git a/lib/form/amd/build/collapsesections.min.js b/lib/form/amd/build/collapsesections.min.js
index 59ff37dac55..34fcd0937a9 100644
--- a/lib/form/amd/build/collapsesections.min.js
+++ b/lib/form/amd/build/collapsesections.min.js
@@ -6,6 +6,6 @@ define("core_form/collapsesections",["exports","jquery","core/pending"],(functio
* @copyright 2021 Bas Brands
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 4.0
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_pending=_interopRequireDefault(_pending);const SELECTORS_FORMHEADER=".fheader",SELECTORS_FORMCONTAINER="fieldset > .fcontainer",CLASSES_SHOW="show",CLASSES_COLLAPSED="collapsed";_exports.init=collapsesections=>{const pendingPromise=new _pending.default("core_form/collapsesections"),collapsemenu=document.querySelector(collapsesections),formParent=collapsemenu.closest("form"),formContainers=(null==formParent?void 0:formParent.querySelectorAll(SELECTORS_FORMCONTAINER))||[];collapsemenu.addEventListener("keydown",(e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),collapsemenu.click())}));let expandedcount=0;const formcontainercount=(0,_jquery.default)(SELECTORS_FORMCONTAINER).length;formContainers.forEach((container=>{container.classList.contains(CLASSES_SHOW)&&expandedcount++})),formcontainercount===expandedcount&&(collapsemenu.classList.remove(CLASSES_COLLAPSED),collapsemenu.setAttribute("aria-expanded",!0)),collapsemenu.addEventListener("click",(()=>{let action="hide";collapsemenu.classList.contains(CLASSES_COLLAPSED)&&(action="show"),formContainers.forEach((container=>(0,_jquery.default)(container).collapse(action)))}));const collapseElementIds=[...(0,_jquery.default)(SELECTORS_FORMHEADER)].map(((element,index)=>(element.id=element.id||"collapseElement-".concat(index),element.id)));collapsemenu.setAttribute("aria-controls",collapseElementIds.join(" ")),(0,_jquery.default)(SELECTORS_FORMCONTAINER).on("hidden.bs.collapse",(()=>{[...formContainers].every((container=>!container.classList.contains(CLASSES_SHOW)))&&(collapsemenu.classList.add(CLASSES_COLLAPSED),collapsemenu.setAttribute("aria-expanded",!1))})),(0,_jquery.default)(SELECTORS_FORMCONTAINER).on("shown.bs.collapse",(()=>{[...formContainers].every((container=>container.classList.contains(CLASSES_SHOW)))&&(collapsemenu.classList.remove(CLASSES_COLLAPSED),collapsemenu.setAttribute("aria-expanded",!0))})),pendingPromise.resolve()}}));
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_pending=_interopRequireDefault(_pending);const SELECTORS_FORM=".mform",SELECTORS_FORMHEADER=".fheader",SELECTORS_FORMCONTAINER="fieldset > .fcontainer",CLASSES_SHOW="show",CLASSES_COLLAPSED="collapsed";_exports.init=collapsesections=>{const pendingPromise=new _pending.default("core_form/collapsesections"),collapsemenu=document.querySelector(collapsesections),formParent=collapsemenu.closest(SELECTORS_FORM),formContainers=formParent.querySelectorAll(SELECTORS_FORMCONTAINER);collapsemenu.addEventListener("keydown",(e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),collapsemenu.click())}));let expandedcount=0;const formcontainercount=(0,_jquery.default)(SELECTORS_FORMCONTAINER).length;formContainers.forEach((container=>{container.classList.contains(CLASSES_SHOW)&&expandedcount++})),formcontainercount===expandedcount&&(collapsemenu.classList.remove(CLASSES_COLLAPSED),collapsemenu.setAttribute("aria-expanded",!0)),collapsemenu.addEventListener("click",(()=>{let action="hide";collapsemenu.classList.contains(CLASSES_COLLAPSED)&&(action="show"),formContainers.forEach((container=>(0,_jquery.default)(container).collapse(action)))}));const collapseElementIds=[...formParent.querySelectorAll(SELECTORS_FORMHEADER)].map(((element,index)=>(element.id=element.id||"collapseElement-".concat(index),element.id)));collapsemenu.setAttribute("aria-controls",collapseElementIds.join(" ")),(0,_jquery.default)(SELECTORS_FORMCONTAINER).on("hidden.bs.collapse",(()=>{[...formContainers].every((container=>!container.classList.contains(CLASSES_SHOW)))&&(collapsemenu.classList.add(CLASSES_COLLAPSED),collapsemenu.setAttribute("aria-expanded",!1))})),(0,_jquery.default)(SELECTORS_FORMCONTAINER).on("shown.bs.collapse",(()=>{[...formContainers].every((container=>container.classList.contains(CLASSES_SHOW)))&&(collapsemenu.classList.remove(CLASSES_COLLAPSED),collapsemenu.setAttribute("aria-expanded",!0))})),pendingPromise.resolve()}}));
//# sourceMappingURL=collapsesections.min.js.map
\ No newline at end of file
diff --git a/lib/form/amd/build/collapsesections.min.js.map b/lib/form/amd/build/collapsesections.min.js.map
index d9b59b0bd69..230675ed516 100644
--- a/lib/form/amd/build/collapsesections.min.js.map
+++ b/lib/form/amd/build/collapsesections.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"collapsesections.min.js","sources":["../src/collapsesections.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 .\n\n/**\n * Collapse or expand all form sections on clicking the expand all / collapse al link.\n *\n * @module core_form/collapsesections\n * @copyright 2021 Bas Brands\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.0\n */\n\nimport $ from 'jquery';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n FORMHEADER: '.fheader',\n FORMCONTAINER: 'fieldset > .fcontainer',\n};\n\nconst CLASSES = {\n SHOW: 'show',\n COLLAPSED: 'collapsed'\n};\n\n/**\n * Initialises the form section collapse / expand action.\n *\n * @param {string} collapsesections the collapse/expand link id.\n */\nexport const init = collapsesections => {\n // All jQuery in this code can be replaced when MDL-71979 is integrated (move to Bootstrap 5).\n const pendingPromise = new Pending('core_form/collapsesections');\n const collapsemenu = document.querySelector(collapsesections);\n const formParent = collapsemenu.closest('form');\n const formContainers = formParent?.querySelectorAll(SELECTORS.FORMCONTAINER) || [];\n\n collapsemenu.addEventListener('keydown', e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n collapsemenu.click();\n }\n });\n\n // Override default collapse class if all containers are expanded on page load\n let expandedcount = 0;\n const formcontainercount = $(SELECTORS.FORMCONTAINER).length;\n formContainers.forEach(container => {\n if (container.classList.contains(CLASSES.SHOW)) {\n expandedcount++;\n }\n });\n\n if (formcontainercount === expandedcount) {\n collapsemenu.classList.remove(CLASSES.COLLAPSED);\n collapsemenu.setAttribute('aria-expanded', true);\n }\n\n // When the collapse menu is toggled, update each form container to match.\n collapsemenu.addEventListener('click', () => {\n let action = 'hide';\n if (collapsemenu.classList.contains(CLASSES.COLLAPSED)) {\n action = 'show';\n }\n\n formContainers.forEach(container => $(container).collapse(action));\n });\n\n // Ensure collapse menu button adds aria-controls attribute referring to each collapsible element.\n const collapseElements = $(SELECTORS.FORMHEADER);\n const collapseElementIds = [...collapseElements].map((element, index) => {\n element.id = element.id || `collapseElement-${index}`;\n return element.id;\n });\n collapsemenu.setAttribute('aria-controls', collapseElementIds.join(' '));\n\n // When any form container is toggled, re-calculate collapse menu state.\n $(SELECTORS.FORMCONTAINER).on('hidden.bs.collapse', () => {\n const allCollapsed = [...formContainers].every(container => !container.classList.contains(CLASSES.SHOW));\n if (allCollapsed) {\n collapsemenu.classList.add(CLASSES.COLLAPSED);\n collapsemenu.setAttribute('aria-expanded', false);\n }\n });\n $(SELECTORS.FORMCONTAINER).on('shown.bs.collapse', () => {\n const allExpanded = [...formContainers].every(container => container.classList.contains(CLASSES.SHOW));\n if (allExpanded) {\n collapsemenu.classList.remove(CLASSES.COLLAPSED);\n collapsemenu.setAttribute('aria-expanded', true);\n }\n });\n pendingPromise.resolve();\n};\n"],"names":["SELECTORS","CLASSES","collapsesections","pendingPromise","Pending","collapsemenu","document","querySelector","formParent","closest","formContainers","querySelectorAll","addEventListener","e","key","preventDefault","click","expandedcount","formcontainercount","length","forEach","container","classList","contains","remove","setAttribute","action","collapse","collapseElementIds","map","element","index","id","join","on","every","add","resolve"],"mappings":";;;;;;;;0KA2BMA,qBACU,WADVA,wBAEa,yBAGbC,aACI,OADJA,kBAES,0BAQKC,yBAEVC,eAAiB,IAAIC,iBAAQ,8BAC7BC,aAAeC,SAASC,cAAcL,kBACtCM,WAAaH,aAAaI,QAAQ,QAClCC,gBAAiBF,MAAAA,kBAAAA,WAAYG,iBAAiBX,2BAA4B,GAEhFK,aAAaO,iBAAiB,WAAWC,IACvB,UAAVA,EAAEC,KAA6B,MAAVD,EAAEC,MACvBD,EAAEE,iBACFV,aAAaW,gBAKjBC,cAAgB,QACdC,oBAAqB,mBAAElB,yBAAyBmB,OACtDT,eAAeU,SAAQC,YACfA,UAAUC,UAAUC,SAAStB,eAC7BgB,mBAIJC,qBAAuBD,gBACvBZ,aAAaiB,UAAUE,OAAOvB,mBAC9BI,aAAaoB,aAAa,iBAAiB,IAI/CpB,aAAaO,iBAAiB,SAAS,SAC/Bc,OAAS,OACTrB,aAAaiB,UAAUC,SAAStB,qBAChCyB,OAAS,QAGbhB,eAAeU,SAAQC,YAAa,mBAAEA,WAAWM,SAASD,mBAKxDE,mBAAqB,KADF,mBAAE5B,uBACsB6B,KAAI,CAACC,QAASC,SAC3DD,QAAQE,GAAKF,QAAQE,8BAAyBD,OACvCD,QAAQE,MAEnB3B,aAAaoB,aAAa,gBAAiBG,mBAAmBK,KAAK,0BAGjEjC,yBAAyBkC,GAAG,sBAAsB,KAC3B,IAAIxB,gBAAgByB,OAAMd,YAAcA,UAAUC,UAAUC,SAAStB,kBAEtFI,aAAaiB,UAAUc,IAAInC,mBAC3BI,aAAaoB,aAAa,iBAAiB,2BAGjDzB,yBAAyBkC,GAAG,qBAAqB,KAC3B,IAAIxB,gBAAgByB,OAAMd,WAAaA,UAAUC,UAAUC,SAAStB,kBAEpFI,aAAaiB,UAAUE,OAAOvB,mBAC9BI,aAAaoB,aAAa,iBAAiB,OAGnDtB,eAAekC"}
\ No newline at end of file
+{"version":3,"file":"collapsesections.min.js","sources":["../src/collapsesections.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 .\n\n/**\n * Collapse or expand all form sections on clicking the expand all / collapse al link.\n *\n * @module core_form/collapsesections\n * @copyright 2021 Bas Brands\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.0\n */\n\nimport $ from 'jquery';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n FORM: '.mform',\n FORMHEADER: '.fheader',\n FORMCONTAINER: 'fieldset > .fcontainer',\n};\n\nconst CLASSES = {\n SHOW: 'show',\n COLLAPSED: 'collapsed'\n};\n\n/**\n * Initialises the form section collapse / expand action.\n *\n * @param {string} collapsesections the collapse/expand link id.\n */\nexport const init = collapsesections => {\n // All jQuery in this code can be replaced when MDL-71979 is integrated (move to Bootstrap 5).\n const pendingPromise = new Pending('core_form/collapsesections');\n const collapsemenu = document.querySelector(collapsesections);\n\n const formParent = collapsemenu.closest(SELECTORS.FORM);\n const formContainers = formParent.querySelectorAll(SELECTORS.FORMCONTAINER);\n\n collapsemenu.addEventListener('keydown', e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n collapsemenu.click();\n }\n });\n\n // Override default collapse class if all containers are expanded on page load\n let expandedcount = 0;\n const formcontainercount = $(SELECTORS.FORMCONTAINER).length;\n formContainers.forEach(container => {\n if (container.classList.contains(CLASSES.SHOW)) {\n expandedcount++;\n }\n });\n\n if (formcontainercount === expandedcount) {\n collapsemenu.classList.remove(CLASSES.COLLAPSED);\n collapsemenu.setAttribute('aria-expanded', true);\n }\n\n // When the collapse menu is toggled, update each form container to match.\n collapsemenu.addEventListener('click', () => {\n let action = 'hide';\n if (collapsemenu.classList.contains(CLASSES.COLLAPSED)) {\n action = 'show';\n }\n\n formContainers.forEach(container => $(container).collapse(action));\n });\n\n // Ensure collapse menu button adds aria-controls attribute referring to each collapsible element.\n const collapseElements = formParent.querySelectorAll(SELECTORS.FORMHEADER);\n const collapseElementIds = [...collapseElements].map((element, index) => {\n element.id = element.id || `collapseElement-${index}`;\n return element.id;\n });\n collapsemenu.setAttribute('aria-controls', collapseElementIds.join(' '));\n\n // When any form container is toggled, re-calculate collapse menu state.\n $(SELECTORS.FORMCONTAINER).on('hidden.bs.collapse', () => {\n const allCollapsed = [...formContainers].every(container => !container.classList.contains(CLASSES.SHOW));\n if (allCollapsed) {\n collapsemenu.classList.add(CLASSES.COLLAPSED);\n collapsemenu.setAttribute('aria-expanded', false);\n }\n });\n $(SELECTORS.FORMCONTAINER).on('shown.bs.collapse', () => {\n const allExpanded = [...formContainers].every(container => container.classList.contains(CLASSES.SHOW));\n if (allExpanded) {\n collapsemenu.classList.remove(CLASSES.COLLAPSED);\n collapsemenu.setAttribute('aria-expanded', true);\n }\n });\n pendingPromise.resolve();\n};\n"],"names":["SELECTORS","CLASSES","collapsesections","pendingPromise","Pending","collapsemenu","document","querySelector","formParent","closest","formContainers","querySelectorAll","addEventListener","e","key","preventDefault","click","expandedcount","formcontainercount","length","forEach","container","classList","contains","remove","setAttribute","action","collapse","collapseElementIds","map","element","index","id","join","on","every","add","resolve"],"mappings":";;;;;;;;0KA2BMA,eACI,SADJA,qBAEU,WAFVA,wBAGa,yBAGbC,aACI,OADJA,kBAES,0BAQKC,yBAEVC,eAAiB,IAAIC,iBAAQ,8BAC7BC,aAAeC,SAASC,cAAcL,kBAEtCM,WAAaH,aAAaI,QAAQT,gBAClCU,eAAiBF,WAAWG,iBAAiBX,yBAEnDK,aAAaO,iBAAiB,WAAWC,IACvB,UAAVA,EAAEC,KAA6B,MAAVD,EAAEC,MACvBD,EAAEE,iBACFV,aAAaW,gBAKjBC,cAAgB,QACdC,oBAAqB,mBAAElB,yBAAyBmB,OACtDT,eAAeU,SAAQC,YACfA,UAAUC,UAAUC,SAAStB,eAC7BgB,mBAIJC,qBAAuBD,gBACvBZ,aAAaiB,UAAUE,OAAOvB,mBAC9BI,aAAaoB,aAAa,iBAAiB,IAI/CpB,aAAaO,iBAAiB,SAAS,SAC/Bc,OAAS,OACTrB,aAAaiB,UAAUC,SAAStB,qBAChCyB,OAAS,QAGbhB,eAAeU,SAAQC,YAAa,mBAAEA,WAAWM,SAASD,mBAKxDE,mBAAqB,IADFpB,WAAWG,iBAAiBX,uBACJ6B,KAAI,CAACC,QAASC,SAC3DD,QAAQE,GAAKF,QAAQE,8BAAyBD,OACvCD,QAAQE,MAEnB3B,aAAaoB,aAAa,gBAAiBG,mBAAmBK,KAAK,0BAGjEjC,yBAAyBkC,GAAG,sBAAsB,KAC3B,IAAIxB,gBAAgByB,OAAMd,YAAcA,UAAUC,UAAUC,SAAStB,kBAEtFI,aAAaiB,UAAUc,IAAInC,mBAC3BI,aAAaoB,aAAa,iBAAiB,2BAGjDzB,yBAAyBkC,GAAG,qBAAqB,KAC3B,IAAIxB,gBAAgByB,OAAMd,WAAaA,UAAUC,UAAUC,SAAStB,kBAEpFI,aAAaiB,UAAUE,OAAOvB,mBAC9BI,aAAaoB,aAAa,iBAAiB,OAGnDtB,eAAekC"}
\ No newline at end of file
diff --git a/lib/form/amd/src/collapsesections.js b/lib/form/amd/src/collapsesections.js
index 1a8d5a42024..b7fa64a29ac 100644
--- a/lib/form/amd/src/collapsesections.js
+++ b/lib/form/amd/src/collapsesections.js
@@ -26,6 +26,7 @@ import $ from 'jquery';
import Pending from 'core/pending';
const SELECTORS = {
+ FORM: '.mform',
FORMHEADER: '.fheader',
FORMCONTAINER: 'fieldset > .fcontainer',
};
@@ -44,8 +45,9 @@ export const init = collapsesections => {
// All jQuery in this code can be replaced when MDL-71979 is integrated (move to Bootstrap 5).
const pendingPromise = new Pending('core_form/collapsesections');
const collapsemenu = document.querySelector(collapsesections);
- const formParent = collapsemenu.closest('form');
- const formContainers = formParent?.querySelectorAll(SELECTORS.FORMCONTAINER) || [];
+
+ const formParent = collapsemenu.closest(SELECTORS.FORM);
+ const formContainers = formParent.querySelectorAll(SELECTORS.FORMCONTAINER);
collapsemenu.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') {
@@ -79,7 +81,7 @@ export const init = collapsesections => {
});
// Ensure collapse menu button adds aria-controls attribute referring to each collapsible element.
- const collapseElements = $(SELECTORS.FORMHEADER);
+ const collapseElements = formParent.querySelectorAll(SELECTORS.FORMHEADER);
const collapseElementIds = [...collapseElements].map((element, index) => {
element.id = element.id || `collapseElement-${index}`;
return element.id;
diff --git a/lib/tests/behat/readonlyform.feature b/lib/tests/behat/readonlyform.feature
index 6ebe972af22..02ef27e3f34 100644
--- a/lib/tests/behat/readonlyform.feature
+++ b/lib/tests/behat/readonlyform.feature
@@ -6,27 +6,23 @@ Feature: Read-only forms should work
@javascript
Scenario: Shortforms expand collapsing should work for read-only forms - one-section form
- Given the following "courses" exist:
- | fullname | shortname | format |
- | Course 1 | C1 | topics |
- And the following "activities" exist:
- | activity | name | intro | course | idnumber |
- | label | L1 | Fixture link | C1 | label1 |
- Given I am on the "C1" "Course" page logged in as "admin"
- And I follow "Fixture link"
- When I expand all fieldsets
- Then the field "Name" matches value "Important information"
+ Given I log in as "admin"
+ And I visit "/lib/tests/fixtures/readonlyform.php?sections=1"
+ When I press "First section"
+ Then "Name" "field" should be visible
+ And the field "Name" matches value "Important information"
+ And I press "First section"
+ And "Name" "field" should not be visible
@javascript
Scenario: Shortforms expand collapsing should work for read-only forms - two-section form
- Given the following "courses" exist:
- | fullname | shortname | format |
- | Course 1 | C1 | topics |
- And the following "activities" exist:
- | activity | name | intro | course | idnumber |
- | label | L1 | Fixture link | C1 | label1 |
- Given I am on the "C1" "Course" page logged in as "admin"
- And I follow "Fixture link"
- When I expand all fieldsets
- Then the field "Name" matches value "Important information"
- Then the field "Other" matches value "Other information"
+ Given I log in as "admin"
+ And I visit "/lib/tests/fixtures/readonlyform.php?sections=2"
+ When I press "Expand all"
+ Then "Name" "field" should be visible
+ And the field "Name" matches value "Important information"
+ And "Other" "field" should be visible
+ And the field "Other" matches value "Other information"
+ And I press "Collapse all"
+ And "Name" "field" should not be visible
+ And "Other" "field" should not be visible