Commit | Line | Data |
---|---|---|
01e0e704 ARN |
1 | YUI.add('moodle-core-chooserdialogue', function(Y) { |
2 | ||
3 | var CHOOSERDIALOGUE = function() { | |
4 | CHOOSERDIALOGUE.superclass.constructor.apply(this, arguments); | |
5 | } | |
6 | ||
7 | Y.extend(CHOOSERDIALOGUE, Y.Base, { | |
8 | // The overlay widget | |
9 | overlay: null, | |
10 | ||
11 | // The submit button - we disable this until an element is set | |
12 | submitbutton : null, | |
13 | ||
14 | // The chooserdialogue container | |
15 | container : null, | |
16 | ||
17 | setup_chooser_dialogue : function(bodycontent, headercontent, config) { | |
18 | // Set Default options | |
19 | var params = { | |
20 | bodyContent : bodycontent.get('innerHTML'), | |
21 | headerContent : headercontent.get('innerHTML'), | |
22 | visible : false, // Hide by default | |
23 | zindex : 100, // Display in front of other items | |
24 | lightbox : true, // This dialogue should be modal | |
25 | shim : true | |
26 | } | |
27 | ||
28 | // Override with additional options | |
29 | for (paramkey in config) { | |
30 | params[paramkey] = config[paramkey]; | |
31 | } | |
32 | ||
33 | // Create the overlay | |
34 | this.overlay = new M.core.dialogue(params); | |
35 | ||
36 | // Remove the template for the chooser | |
37 | bodycontent.remove(); | |
38 | headercontent.remove(); | |
39 | ||
40 | // Hide and then render the overlay | |
41 | this.overlay.hide(); | |
42 | this.overlay.render(); | |
43 | ||
44 | // Set useful links | |
45 | this.container = this.overlay.get('boundingBox').one('#choosercontainer'); | |
46 | this.options = this.container.all('.option input[type=radio]'); | |
47 | }, | |
48 | /** | |
49 | * Display the module chooser | |
50 | * | |
51 | * @param e Event Triggering Event | |
52 | * @return void | |
53 | */ | |
54 | display_chooser : function (e) { | |
55 | // Stop the default event actions before we proceed | |
56 | e.preventDefault(); | |
57 | ||
58 | var bb = this.overlay.get('boundingBox'); | |
59 | var dialogue = this.container.one('.alloptions'); | |
60 | ||
01e0e704 ARN |
61 | // These will trigger a check_options call to display the correct help |
62 | this.container.on('click', this.check_options, this); | |
63 | this.container.on('key_up', this.check_options, this); | |
64 | this.container.on('dblclick', function(e) { | |
65 | if (e.target.ancestor('div.option')) { | |
66 | this.check_options(); | |
67 | this.container.one('form').submit(); | |
68 | } | |
69 | }, this); | |
70 | ||
71 | // Hook onto the cancel button to hide the form | |
72 | this.container.one('#addcancel').on('click', this.cancel_popup, this); | |
73 | ||
74 | // Grab global keyup events and handle them | |
75 | Y.one('document').on('keyup', this.handle_key_press, this); | |
76 | ||
77 | // Add references to various elements we adjust | |
78 | this.jumplink = this.container.one('#jump'); | |
79 | this.submitbutton = this.container.one('#submitbutton'); | |
80 | ||
81 | // Disable the submit element until the user makes a selection | |
82 | this.submitbutton.set('disabled', 'true'); | |
83 | ||
84 | // Display the overlay | |
85 | this.overlay.show(); | |
86 | ||
af75421c ARN |
87 | // Re-centre the dialogue after we've shown it. |
88 | this.center_dialogue(dialogue); | |
89 | ||
01e0e704 ARN |
90 | // Finally, focus the first radio element - this enables form selection via the keyboard |
91 | this.container.one('.option input[type=radio]').focus(); | |
92 | ||
93 | // Trigger check_options to set the initial jumpurl | |
94 | this.check_options(); | |
95 | }, | |
96 | /** | |
97 | * Calculate the optimum height of the chooser dialogue | |
98 | * | |
99 | * This tries to set a sensible maximum and minimum to ensure that some options are always shown, and preferably | |
100 | * all, whilst fitting the box within the current viewport | |
101 | * | |
102 | * @param dialogue Y.Node The dialogue | |
103 | * @return void | |
104 | */ | |
af75421c ARN |
105 | center_dialogue : function(dialogue) { |
106 | var bb = this.overlay.get('boundingBox'); | |
107 | ||
108 | var winheight = bb.get('winHeight'); | |
109 | var offsettop = 0; | |
01e0e704 ARN |
110 | |
111 | // Try and set a sensible max-height -- this must be done before setting the top | |
112 | // Set a default height of 640px | |
113 | var newheight = this.get('maxheight'); | |
114 | if (winheight <= newheight) { | |
115 | // Deal with smaller window sizes | |
116 | if (winheight <= this.get('minheight')) { | |
117 | newheight = this.get('minheight'); | |
118 | } else { | |
119 | newheight = winheight; | |
120 | } | |
121 | } | |
122 | ||
123 | // Set a fixed position if the window is large enough | |
124 | if (newheight > this.get('minheight')) { | |
af75421c | 125 | bb.setStyle('position', 'fixed'); |
01e0e704 | 126 | } else { |
af75421c ARN |
127 | bb.setStyle('position', 'absolute'); |
128 | offsettop = Y.one('window').get('scrollTop'); | |
01e0e704 ARN |
129 | } |
130 | ||
131 | // Take off 15px top and bottom for borders, plus 40px each for the title and button area before setting the | |
132 | // new max-height | |
af75421c | 133 | var totalheight = newheight; |
01e0e704 ARN |
134 | newheight = newheight - (15 + 15 + 40 + 40); |
135 | dialogue.setStyle('max-height', newheight + 'px'); | |
af75421c | 136 | dialogue.setStyle('height', newheight + 'px'); |
01e0e704 ARN |
137 | |
138 | // Re-calculate the location now that we've changed the size | |
af75421c ARN |
139 | var dialoguetop = Math.max(12, ((winheight - totalheight) / 2)) + offsettop; |
140 | ||
141 | // We need to set the height for the yui3-widget - can't work | |
142 | // out what we're setting at present -- shoud be the boudingBox | |
143 | bb.setStyle('top', dialoguetop + 'px'); | |
01e0e704 ARN |
144 | }, |
145 | handle_key_press : function(e) { | |
146 | if (e.keyCode == 27) { | |
147 | this.cancel_popup(e); | |
148 | } | |
149 | }, | |
150 | cancel_popup : function (e) { | |
151 | // Prevent normal form submission before hiding | |
152 | e.preventDefault(); | |
153 | this.hide(); | |
154 | }, | |
155 | hide : function() { | |
156 | // Detach the global keypress handler before hiding | |
157 | Y.one('document').detach('keyup', this.handle_key_press, this); | |
158 | this.container.detachAll(); | |
159 | this.overlay.hide(); | |
160 | }, | |
161 | check_options : function(e) { | |
162 | // Check which options are set, and change the parent class | |
163 | // to show/hide help as required | |
164 | this.options.each(function(thisoption) { | |
165 | var optiondiv = thisoption.get('parentNode').get('parentNode'); | |
166 | if (thisoption.get('checked')) { | |
167 | optiondiv.addClass('selected'); | |
168 | ||
169 | // Trigger any events for this option | |
170 | this.option_selected(thisoption); | |
171 | ||
172 | // Ensure that the form may be submitted | |
173 | this.submitbutton.removeAttribute('disabled'); | |
174 | ||
175 | // Ensure that the radio remains focus so that keyboard navigation is still possible | |
176 | thisoption.focus(); | |
177 | } else { | |
178 | optiondiv.removeClass('selected'); | |
179 | } | |
180 | }, this); | |
181 | }, | |
182 | option_selected : function(e) { | |
183 | } | |
184 | }, | |
185 | { | |
186 | NAME : 'moodle-core-chooserdialogue', | |
187 | ATTRS : { | |
188 | minheight : { | |
189 | value : 300 | |
190 | }, | |
191 | maxheight : { | |
192 | value : 660 | |
193 | } | |
194 | } | |
195 | }); | |
196 | M.core = M.core || {}; | |
197 | M.core.chooserdialogue = CHOOSERDIALOGUE; | |
198 | }, | |
199 | '@VERSION@', { | |
200 | requires:['base', 'overlay', 'moodle-enrol-notification'] | |
201 | } | |
202 | ); |