From 2efc12e104330dff25ea684d83dd5130fff3855c Mon Sep 17 00:00:00 2001 From: David Woloszyn Date: Tue, 20 Sep 2022 14:44:53 +1000 Subject: [PATCH] MDL-75459 Collapsable Form Sections: Default state bug fix In circumstances where all collapsible form sections were expanded on page load, a check is now made to ensure the expand all/collapse all button behaves as intended. --- lib/form/amd/build/collapsesections.min.js | 2 +- lib/form/amd/build/collapsesections.min.js.map | 2 +- lib/form/amd/src/collapsesections.js | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/form/amd/build/collapsesections.min.js b/lib/form/amd/build/collapsesections.min.js index e1a4f48336b..020f2d1d81b 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=".fcontainer",CLASSES_SHOW="show",CLASSES_COLLAPSED="collapsed";_exports.init=collapsesections=>{const pendingPromise=new _pending.default("core_form/collapsesections"),collapsemenu=document.querySelector(collapsesections);collapsemenu.addEventListener("keydown",(e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),collapsemenu.click())})),collapsemenu.addEventListener("click",(()=>{let action="hide";collapsemenu.classList.contains(CLASSES_COLLAPSED)&&(action="show"),document.querySelectorAll(SELECTORS_FORMCONTAINER).forEach((collapsecontainer=>{(0,_jquery.default)(collapsecontainer).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",(()=>{let allcollapsed=!0;(0,_jquery.default)(SELECTORS_FORMCONTAINER).each(((_,collapsecontainer)=>{collapsecontainer.classList.contains(CLASSES_SHOW)&&(allcollapsed=!1)})),allcollapsed&&(collapsemenu.classList.add(CLASSES_COLLAPSED),collapsemenu.setAttribute("aria-expanded",!1))})),(0,_jquery.default)(SELECTORS_FORMCONTAINER).on("shown.bs.collapse",(()=>{var allexpanded=!0;(0,_jquery.default)(SELECTORS_FORMCONTAINER).each(((_,collapsecontainer)=>{collapsecontainer.classList.contains(CLASSES_SHOW)||(allexpanded=!1)})),allexpanded&&(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_FORMHEADER=".fheader",SELECTORS_FORMCONTAINER=".fcontainer",CLASSES_SHOW="show",CLASSES_COLLAPSED="collapsed";_exports.init=collapsesections=>{const pendingPromise=new _pending.default("core_form/collapsesections"),collapsemenu=document.querySelector(collapsesections);collapsemenu.addEventListener("keydown",(e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),collapsemenu.click())}));let expandedcount=0;const formcontainercount=(0,_jquery.default)(SELECTORS_FORMCONTAINER).length;(0,_jquery.default)(SELECTORS_FORMCONTAINER).each(((_,collapsecontainer)=>{collapsecontainer.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"),document.querySelectorAll(SELECTORS_FORMCONTAINER).forEach((collapsecontainer=>{(0,_jquery.default)(collapsecontainer).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",(()=>{let allcollapsed=!0;(0,_jquery.default)(SELECTORS_FORMCONTAINER).each(((_,collapsecontainer)=>{collapsecontainer.classList.contains(CLASSES_SHOW)&&(allcollapsed=!1)})),allcollapsed&&(collapsemenu.classList.add(CLASSES_COLLAPSED),collapsemenu.setAttribute("aria-expanded",!1))})),(0,_jquery.default)(SELECTORS_FORMCONTAINER).on("shown.bs.collapse",(()=>{var allexpanded=!0;(0,_jquery.default)(SELECTORS_FORMCONTAINER).each(((_,collapsecontainer)=>{collapsecontainer.classList.contains(CLASSES_SHOW)||(allexpanded=!1)})),allexpanded&&(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 231c7c2a7cb..badcfbc8df2 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: '.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 collapsemenu.addEventListener('keydown', e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n collapsemenu.click();\n }\n });\n collapsemenu.addEventListener('click', () => {\n let action = 'hide';\n if (collapsemenu.classList.contains(CLASSES.COLLAPSED)) {\n action = 'show';\n }\n\n document.querySelectorAll(SELECTORS.FORMCONTAINER).forEach((collapsecontainer) => {\n $(collapsecontainer).collapse(action);\n });\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 $(SELECTORS.FORMCONTAINER).on('hidden.bs.collapse', () => {\n let allcollapsed = true;\n $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n if (collapsecontainer.classList.contains(CLASSES.SHOW)) {\n allcollapsed = false;\n }\n });\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 var allexpanded = true;\n $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n if (!collapsecontainer.classList.contains(CLASSES.SHOW)) {\n allexpanded = false;\n }\n });\n\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","addEventListener","e","key","preventDefault","click","action","classList","contains","querySelectorAll","forEach","collapsecontainer","collapse","collapseElementIds","map","element","index","id","setAttribute","join","on","allcollapsed","each","_","add","allexpanded","remove","resolve"],"mappings":";;;;;;;;0KA2BMA,qBACU,WADVA,wBAEa,cAGbC,aACI,OADJA,kBAES,0BAQKC,yBAEVC,eAAiB,IAAIC,iBAAQ,8BAC7BC,aAAeC,SAASC,cAAcL,kBAC5CG,aAAaG,iBAAiB,WAAWC,IACvB,UAAVA,EAAEC,KAA6B,MAAVD,EAAEC,MACvBD,EAAEE,iBACFN,aAAaO,YAGrBP,aAAaG,iBAAiB,SAAS,SAC/BK,OAAS,OACTR,aAAaS,UAAUC,SAASd,qBAChCY,OAAS,QAGbP,SAASU,iBAAiBhB,yBAAyBiB,SAASC,wCACtDA,mBAAmBC,SAASN,oBAMhCO,mBAAqB,KADF,mBAAEpB,uBACsBqB,KAAI,CAACC,QAASC,SAC3DD,QAAQE,GAAKF,QAAQE,8BAAyBD,OACvCD,QAAQE,MAEnBnB,aAAaoB,aAAa,gBAAiBL,mBAAmBM,KAAK,0BAEjE1B,yBAAyB2B,GAAG,sBAAsB,SAC5CC,cAAe,sBACjB5B,yBAAyB6B,MAAK,CAACC,EAAGZ,qBAC5BA,kBAAkBJ,UAAUC,SAASd,gBACrC2B,cAAe,MAGnBA,eACAvB,aAAaS,UAAUiB,IAAI9B,mBAC3BI,aAAaoB,aAAa,iBAAiB,2BAGjDzB,yBAAyB2B,GAAG,qBAAqB,SAC3CK,aAAc,sBAChBhC,yBAAyB6B,MAAK,CAACC,EAAGZ,qBAC3BA,kBAAkBJ,UAAUC,SAASd,gBACtC+B,aAAc,MAIlBA,cACA3B,aAAaS,UAAUmB,OAAOhC,mBAC9BI,aAAaoB,aAAa,iBAAiB,OAGnDtB,eAAe+B"} \ 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 FORMHEADER: '.fheader',\n FORMCONTAINER: '.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 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 $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n if (collapsecontainer.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 collapsemenu.addEventListener('click', () => {\n let action = 'hide';\n if (collapsemenu.classList.contains(CLASSES.COLLAPSED)) {\n action = 'show';\n }\n\n document.querySelectorAll(SELECTORS.FORMCONTAINER).forEach((collapsecontainer) => {\n $(collapsecontainer).collapse(action);\n });\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 $(SELECTORS.FORMCONTAINER).on('hidden.bs.collapse', () => {\n let allcollapsed = true;\n $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n if (collapsecontainer.classList.contains(CLASSES.SHOW)) {\n allcollapsed = false;\n }\n });\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 var allexpanded = true;\n $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => {\n if (!collapsecontainer.classList.contains(CLASSES.SHOW)) {\n allexpanded = false;\n }\n });\n\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","addEventListener","e","key","preventDefault","click","expandedcount","formcontainercount","length","each","_","collapsecontainer","classList","contains","remove","setAttribute","action","querySelectorAll","forEach","collapse","collapseElementIds","map","element","index","id","join","on","allcollapsed","add","allexpanded","resolve"],"mappings":";;;;;;;;0KA2BMA,qBACU,WADVA,wBAEa,cAGbC,aACI,OADJA,kBAES,0BAQKC,yBAEVC,eAAiB,IAAIC,iBAAQ,8BAC7BC,aAAeC,SAASC,cAAcL,kBAC5CG,aAAaG,iBAAiB,WAAWC,IACvB,UAAVA,EAAEC,KAA6B,MAAVD,EAAEC,MACvBD,EAAEE,iBACFN,aAAaO,gBAKjBC,cAAgB,QACdC,oBAAqB,mBAAEd,yBAAyBe,2BACpDf,yBAAyBgB,MAAK,CAACC,EAAGC,qBAC5BA,kBAAkBC,UAAUC,SAASnB,eACrCY,mBAIJC,qBAAuBD,gBACvBR,aAAac,UAAUE,OAAOpB,mBAC9BI,aAAaiB,aAAa,iBAAiB,IAG/CjB,aAAaG,iBAAiB,SAAS,SAC/Be,OAAS,OACTlB,aAAac,UAAUC,SAASnB,qBAChCsB,OAAS,QAGbjB,SAASkB,iBAAiBxB,yBAAyByB,SAASP,wCACtDA,mBAAmBQ,SAASH,oBAMhCI,mBAAqB,KADF,mBAAE3B,uBACsB4B,KAAI,CAACC,QAASC,SAC3DD,QAAQE,GAAKF,QAAQE,8BAAyBD,OACvCD,QAAQE,MAEnB1B,aAAaiB,aAAa,gBAAiBK,mBAAmBK,KAAK,0BAEjEhC,yBAAyBiC,GAAG,sBAAsB,SAC5CC,cAAe,sBACjBlC,yBAAyBgB,MAAK,CAACC,EAAGC,qBAC5BA,kBAAkBC,UAAUC,SAASnB,gBACrCiC,cAAe,MAGnBA,eACA7B,aAAac,UAAUgB,IAAIlC,mBAC3BI,aAAaiB,aAAa,iBAAiB,2BAGjDtB,yBAAyBiC,GAAG,qBAAqB,SAC3CG,aAAc,sBAChBpC,yBAAyBgB,MAAK,CAACC,EAAGC,qBAC3BA,kBAAkBC,UAAUC,SAASnB,gBACtCmC,aAAc,MAIlBA,cACA/B,aAAac,UAAUE,OAAOpB,mBAC9BI,aAAaiB,aAAa,iBAAiB,OAGnDnB,eAAekC"} \ No newline at end of file diff --git a/lib/form/amd/src/collapsesections.js b/lib/form/amd/src/collapsesections.js index fdf80fcadd0..6c8cea2e724 100644 --- a/lib/form/amd/src/collapsesections.js +++ b/lib/form/amd/src/collapsesections.js @@ -50,6 +50,21 @@ export const init = collapsesections => { collapsemenu.click(); } }); + + // Override default collapse class if all containers are expanded on page load + let expandedcount = 0; + const formcontainercount = $(SELECTORS.FORMCONTAINER).length; + $(SELECTORS.FORMCONTAINER).each((_, collapsecontainer) => { + if (collapsecontainer.classList.contains(CLASSES.SHOW)) { + expandedcount++; + } + }); + + if (formcontainercount === expandedcount) { + collapsemenu.classList.remove(CLASSES.COLLAPSED); + collapsemenu.setAttribute('aria-expanded', true); + } + collapsemenu.addEventListener('click', () => { let action = 'hide'; if (collapsemenu.classList.contains(CLASSES.COLLAPSED)) {