blocks/amd/src/add_modal.js

  1. // This file is part of Moodle - http://moodle.org/
  2. //
  3. // Moodle is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // Moodle is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  15. /**
  16. * Show an add block modal instead of doing it on a separate page.
  17. *
  18. * @module core_block/add_modal
  19. * @copyright 2016 Damyon Wiese <damyon@moodle.com>
  20. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  21. */
  22. import Templates from 'core/templates';
  23. import {getString} from 'core/str';
  24. import Ajax from 'core/ajax';
  25. import ModalForm from "core_form/modalform";
  26. import CancelModal from 'core/modal_cancel';
  27. const SELECTORS = {
  28. ADD_BLOCK: '[data-key="addblock"]',
  29. SHOW_BLOCK_FORM: '[data-action="showaddblockform"][data-blockname][data-blockform]'
  30. };
  31. // Ensure we only add our listeners once.
  32. let listenerEventsRegistered = false;
  33. /**
  34. * Register related event listeners.
  35. *
  36. * @method registerListenerEvents
  37. * @param {String|null} addBlockUrl The add block URL
  38. * @param {String} pagehash
  39. */
  40. const registerListenerEvents = (addBlockUrl, pagehash) => {
  41. let addBlockModal = null;
  42. document.addEventListener('click', e => {
  43. const showAddBlockForm = e.target.closest(SELECTORS.SHOW_BLOCK_FORM);
  44. if (showAddBlockForm) {
  45. e.preventDefault();
  46. const modalForm = new ModalForm({
  47. modalConfig: {
  48. title: getString('addblock', 'core_block',
  49. showAddBlockForm.getAttribute('data-blocktitle')),
  50. },
  51. args: {blockname: showAddBlockForm.getAttribute('data-blockname'), pagehash,
  52. blockregion: showAddBlockForm.getAttribute('data-blockregion')},
  53. formClass: showAddBlockForm.getAttribute('data-blockform'),
  54. returnFocus: showAddBlockForm,
  55. });
  56. modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => {
  57. addBlockModal.destroy();
  58. window.location.reload();
  59. });
  60. modalForm.show();
  61. }
  62. const addBlock = e.target.closest(SELECTORS.ADD_BLOCK);
  63. if (addBlock) {
  64. e.preventDefault();
  65. let addBlockModalUrl = addBlockUrl ?? addBlock.dataset.url;
  66. buildAddBlockModal()
  67. .then(modal => {
  68. addBlockModal = modal;
  69. const modalBody = renderBlocks(addBlockModalUrl, pagehash,
  70. addBlock.getAttribute('data-blockregion'));
  71. modal.setBody(modalBody);
  72. modal.show();
  73. return modalBody;
  74. })
  75. .catch(() => {
  76. addBlockModal.destroy();
  77. });
  78. }
  79. });
  80. };
  81. /**
  82. * Method that creates the 'add block' modal.
  83. *
  84. * @method buildAddBlockModal
  85. * @returns {Promise} The modal promise (modal's body will be rendered later).
  86. */
  87. const buildAddBlockModal = () => CancelModal.create({
  88. title: getString('addblock'),
  89. });
  90. /**
  91. * Method that renders the list of available blocks.
  92. *
  93. * @method renderBlocks
  94. * @param {String} addBlockUrl The add block URL
  95. * @param {String} pagehash
  96. * @param {String} region
  97. * @return {Promise}
  98. */
  99. const renderBlocks = async(addBlockUrl, pagehash, region) => {
  100. // Fetch all addable blocks in the given page.
  101. const blocks = await getAddableBlocks(pagehash);
  102. return Templates.render('core/add_block_body', {
  103. blocks: blocks,
  104. url: addBlockUrl,
  105. blockregion: region,
  106. pagehash
  107. });
  108. };
  109. /**
  110. * Method that fetches all addable blocks in a given page.
  111. *
  112. * @method getAddableBlocks
  113. * @param {String} pagehash
  114. * @return {Promise}
  115. */
  116. const getAddableBlocks = async(pagehash) => {
  117. const request = {
  118. methodname: 'core_block_fetch_addable_blocks',
  119. args: {
  120. pagecontextid: 0,
  121. pagetype: '',
  122. pagelayout: '',
  123. subpage: '',
  124. pagehash: pagehash,
  125. },
  126. };
  127. return Ajax.call([request])[0];
  128. };
  129. /**
  130. * Set up the actions.
  131. *
  132. * @method init
  133. * @param {String} addBlockUrl The add block URL
  134. * @param {String} pagehash
  135. */
  136. export const init = (addBlockUrl = null, pagehash = '') => {
  137. if (!listenerEventsRegistered) {
  138. registerListenerEvents(addBlockUrl, pagehash);
  139. listenerEventsRegistered = true;
  140. }
  141. };