Commit | Line | Data |
---|---|---|
2bcef559 RW |
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 | /** | |
17 | * Create a modal. | |
18 | * | |
19 | * @module core/modal_factory | |
20 | * @class modal_factory | |
21 | * @package core | |
22 | * @copyright 2016 Ryan Wyllie <ryan@moodle.com> | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
0531ce1a RW |
25 | define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal', |
26 | 'core/modal_save_cancel', 'core/modal_confirm', 'core/modal_cancel', | |
10ea8270 | 27 | 'core/templates', 'core/notification', 'core/custom_interaction_events'], |
0531ce1a RW |
28 | function($, ModalEvents, ModalRegistry, Modal, ModalSaveCancel, ModalConfirm, |
29 | ModalCancel, Templates, Notification, CustomEvents) { | |
2bcef559 RW |
30 | |
31 | // The templates for each type of modal. | |
32 | var TEMPLATES = { | |
33 | DEFAULT: 'core/modal', | |
34 | SAVE_CANCEL: 'core/modal_save_cancel', | |
10ea8270 | 35 | CONFIRM: 'core/modal_confirm', |
be2247fb | 36 | CANCEL: 'core/modal_cancel', |
2bcef559 RW |
37 | }; |
38 | ||
2bcef559 RW |
39 | // The available types of modals. |
40 | var TYPES = { | |
41 | DEFAULT: 'DEFAULT', | |
42 | SAVE_CANCEL: 'SAVE_CANCEL', | |
10ea8270 | 43 | CONFIRM: 'CONFIRM', |
be2247fb | 44 | CANCEL: 'CANCEL', |
2bcef559 RW |
45 | }; |
46 | ||
0531ce1a RW |
47 | // Register the common set of modals. |
48 | ModalRegistry.register(TYPES.DEFAULT, Modal, TEMPLATES.DEFAULT); | |
49 | ModalRegistry.register(TYPES.SAVE_CANCEL, ModalSaveCancel, TEMPLATES.SAVE_CANCEL); | |
50 | ModalRegistry.register(TYPES.CONFIRM, ModalConfirm, TEMPLATES.CONFIRM); | |
51 | ModalRegistry.register(TYPES.CANCEL, ModalCancel, TEMPLATES.CANCEL); | |
52 | ||
2bcef559 RW |
53 | /** |
54 | * Set up the events required to show the modal and return focus when the modal | |
55 | * is closed. | |
56 | * | |
57 | * @method setUpTrigger | |
72835770 | 58 | * @param {Promise} modalPromise The modal instance |
2bcef559 RW |
59 | * @param {object} triggerElement The jQuery element to open the modal |
60 | */ | |
72835770 | 61 | var setUpTrigger = function(modalPromise, triggerElement) { |
2bcef559 | 62 | if (typeof triggerElement != 'undefined') { |
6a7ad2cb RW |
63 | if (Array.isArray(triggerElement)) { |
64 | var selector = triggerElement[1]; | |
65 | triggerElement = triggerElement[0]; | |
66 | ||
67 | CustomEvents.define(triggerElement, [CustomEvents.events.activate]); | |
68 | triggerElement.on(CustomEvents.events.activate, selector, function(e, data) { | |
72835770 AN |
69 | modalPromise.then(function(modal) { |
70 | modal.show(); | |
71 | ||
72 | return modal; | |
73 | }); | |
6a7ad2cb RW |
74 | data.originalEvent.preventDefault(); |
75 | }); | |
76 | } else { | |
77 | CustomEvents.define(triggerElement, [CustomEvents.events.activate]); | |
78 | triggerElement.on(CustomEvents.events.activate, function(e, data) { | |
72835770 AN |
79 | modalPromise.then(function(modal) { |
80 | modal.show(); | |
81 | ||
82 | return modal; | |
83 | }); | |
6a7ad2cb RW |
84 | data.originalEvent.preventDefault(); |
85 | }); | |
86 | } | |
2bcef559 | 87 | |
72835770 AN |
88 | modalPromise.then(function(modal) { |
89 | modal.getRoot().on(ModalEvents.hidden, function() { | |
90 | triggerElement.focus(); | |
91 | }); | |
92 | ||
93 | return modal; | |
2bcef559 RW |
94 | }); |
95 | } | |
96 | }; | |
97 | ||
98 | /** | |
99 | * Create the correct instance of a modal based on the givem type. Sets up | |
100 | * the trigger between the modal and the trigger element. | |
101 | * | |
102 | * @method createFromElement | |
0531ce1a | 103 | * @param {object} registryConf A config from the ModalRegistry |
2bcef559 RW |
104 | * @param {object} modalElement The modal HTML jQuery object |
105 | * @param {object} triggerElement The trigger HTML jQuery object | |
106 | * @return {object} Modal instance | |
107 | */ | |
72835770 | 108 | var createFromElement = function(registryConf, modalElement) { |
2bcef559 | 109 | modalElement = $(modalElement); |
0531ce1a RW |
110 | var module = registryConf.module; |
111 | var modal = new module(modalElement); | |
2bcef559 RW |
112 | |
113 | return modal; | |
114 | }; | |
115 | ||
116 | /** | |
117 | * Create the correct modal instance for the given type, including loading | |
118 | * the correct template and setting up the trigger relationship with the | |
119 | * trigger element. | |
120 | * | |
121 | * @method createFromType | |
0531ce1a | 122 | * @param {object} registryConf A config from the ModalRegistry |
2bcef559 RW |
123 | * @param {object} triggerElement The trigger HTML jQuery object |
124 | * @return {promise} Resolved with a Modal instance | |
125 | */ | |
a50768b9 | 126 | var createFromType = function(registryConf, templateContext, triggerElement) { |
0531ce1a | 127 | var templateName = registryConf.template; |
2bcef559 | 128 | |
72835770 | 129 | var modalPromise = Templates.render(templateName, templateContext) |
2bcef559 RW |
130 | .then(function(html) { |
131 | var modalElement = $(html); | |
72835770 | 132 | return createFromElement(registryConf, modalElement); |
2bcef559 RW |
133 | }) |
134 | .fail(Notification.exception); | |
72835770 AN |
135 | |
136 | setUpTrigger(modalPromise, triggerElement); | |
137 | ||
138 | return modalPromise; | |
2bcef559 RW |
139 | }; |
140 | ||
141 | /** | |
142 | * Create a Modal instance. | |
143 | * | |
144 | * @method create | |
145 | * @param {object} modalConfig The configuration to create the modal instance | |
146 | * @param {object} triggerElement The trigger HTML jQuery object | |
147 | * @return {promise} Resolved with a Modal instance | |
148 | */ | |
149 | var create = function(modalConfig, triggerElement) { | |
150 | var type = modalConfig.type || TYPES.DEFAULT; | |
151 | var isLarge = modalConfig.large ? true : false; | |
0531ce1a | 152 | var registryConf = null; |
a50768b9 | 153 | var templateContext = {}; |
0531ce1a RW |
154 | |
155 | registryConf = ModalRegistry.get(type); | |
2bcef559 | 156 | |
0531ce1a RW |
157 | if (!registryConf) { |
158 | Notification.exception({message: 'Unable to find modal of type: ' + type}); | |
2bcef559 RW |
159 | } |
160 | ||
a50768b9 RW |
161 | if (typeof modalConfig.templateContext != 'undefined') { |
162 | templateContext = modalConfig.templateContext; | |
163 | } | |
164 | ||
165 | return createFromType(registryConf, templateContext, triggerElement) | |
2bcef559 RW |
166 | .then(function(modal) { |
167 | if (typeof modalConfig.title != 'undefined') { | |
168 | modal.setTitle(modalConfig.title); | |
169 | } | |
170 | ||
171 | if (typeof modalConfig.body != 'undefined') { | |
172 | modal.setBody(modalConfig.body); | |
173 | } | |
174 | ||
175 | if (typeof modalConfig.footer != 'undefined') { | |
176 | modal.setFooter(modalConfig.footer); | |
177 | } | |
178 | ||
179 | if (isLarge) { | |
180 | modal.setLarge(); | |
181 | } | |
182 | ||
183 | return modal; | |
184 | }); | |
185 | }; | |
186 | ||
187 | return { | |
188 | create: create, | |
189 | types: TYPES, | |
190 | }; | |
191 | }); |