LTI plugin updates. Finishing support of course level plugins.
[moodle.git] / mod / lti / mod_form.js
CommitLineData
6831c7cd
CS
1(function(){
2 var Y;
3 var self;
996b0fd9 4
6831c7cd
CS
5 M.mod_lti = M.mod_lti || {};
6
7 M.mod_lti.editor = {
8 init: function(yui3, settings){
9 if(yui3){
10 Y = yui3;
996b0fd9 11 }
996b0fd9 12
6831c7cd
CS
13 self = this;
14 this.settings = Y.JSON.parse(settings);
15
16 this.urlCache = {};
17
18 this.addOptGroups();
19
20 var typeSelector = Y.one('#id_typeid');
21 typeSelector.on('change', function(e){
22 self.toggleEditButtons();
23 });
24
25 this.createTypeEditorButtons();
26
27 this.toggleEditButtons();
28
29 var textAreas = new Y.NodeList([
30 Y.one('#id_toolurl'),
31 Y.one('#id_resourcekey'),
32 Y.one('#id_password')
33 ]);
34
35 var debounce;
36 textAreas.on('keyup', function(e){
37 clearTimeout(debounce);
38
39 //If no more changes within 2 seconds, look up the matching tool URL
40 debounce = setTimeout(function(){
41 self.updateAutomaticToolMatch();
42 }, 2000);
43 });
44
45 self.updateAutomaticToolMatch();
46 },
47
48 updateAutomaticToolMatch: function(){
49 var toolurl = Y.one('#id_toolurl');
50 var automatchToolDisplay = Y.one('#lti_automatch_tool');
51
52 if(!automatchToolDisplay){
53 automatchToolDisplay = Y.Node.create('<span />')
54 .set('id', 'lti_automatch_tool')
55 .setStyle('padding-left', '1em');
56
57 toolurl.insert(automatchToolDisplay, 'after');
58 }
59
60 var url = toolurl.get('value');
996b0fd9 61
6831c7cd
CS
62 if(!url){
63 automatchToolDisplay.setStyle('display', 'none');
64 return;
65 }
66
67 var key = Y.one('#id_resourcekey');
68 var secret = Y.one('#id_password');
69
70 //We don't care what tool type this tool is associated with if it's manually configured'
71 if(key.get('value') !== '' && secret.get('value') !== ''){
72 automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />Using custom tool configuration.');
73 } else {
74 var continuation = function(toolInfo){
75 automatchToolDisplay.setStyle('display', '');
76
77 if(toolInfo.toolname){
78 automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />Using tool configuration: ' + toolInfo.toolname);
79 } else {
80 //Inform them custom configuration is in use
81 if(key.get('value') === '' || secret.get('value') === ''){
82 automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.yellow_check_icon_url + '" />Tool configuration not found for this URL.');
996b0fd9
CS
83 }
84 }
6831c7cd
CS
85 };
86
87 //Cache urls which have already been checked to increaes performance
88 if(self.urlCache[url]){
89 continuation(self.urlCache[url]);
90 } else {
91 self.findToolByUrl(url, function(toolInfo){
92 self.urlCache[url] = toolInfo;
93
94 continuation(toolInfo);
95 });
96 }
97 }
98 },
99
100 getSelectedToolTypeOption: function(){
101 var typeSelector = Y.one('#id_typeid');
102
103 return typeSelector.one('option[value=' + typeSelector.get('value') + ']');
104 },
105
106 /**
107 * Separate tool listing into option groups. Server-side select control
108 * doesn't seem to support this.
109 */
110 addOptGroups: function(){
111 var typeSelector = Y.one('#id_typeid');
112
113 if(typeSelector.one('option[courseTool=1]')){
114 //One ore more course tools exist
115
116 var globalGroup = Y.Node.create('<optgroup />')
117 .set('id', 'global_tool_group')
118 .set('label', M.str.lti.global_tool_types);
119
120 var courseGroup = Y.Node.create('<optgroup />')
121 .set('id', 'course_tool_group')
122 .set('label', M.str.lti.course_tool_types);
123
124 typeSelector.all('option[globalTool=1]').remove().each(function(node){
125 globalGroup.append(node);
126 });
127
128 typeSelector.all('option[courseTool=1]').remove().each(function(node){
129 courseGroup.append(node);
996b0fd9 130 });
6831c7cd
CS
131
132 typeSelector.append(globalGroup);
133 typeSelector.append(courseGroup);
996b0fd9 134 }
6831c7cd
CS
135 },
136
137 /**
138 * Adds buttons for creating, editing, and deleting tool types.
139 * Javascript is a requirement to edit course level tools at this point.
140 */
141 createTypeEditorButtons: function(){
142 var typeSelector = Y.one('#id_typeid');
143
144 var createIcon = function(id, tooltip, iconUrl){
145 return Y.Node.create('<a />')
146 .set('id', id)
147 .set('title', tooltip)
148 .setStyle('margin-left', '.5em')
149 .set('href', 'javascript:void(0);')
150 .append(Y.Node.create('<img src="' + iconUrl + '" />'));
151 }
152
153 var addIcon = createIcon('lti_add_tool_type', M.str.lti.addtype, this.settings.add_icon_url);
154 var editIcon = createIcon('lti_edit_tool_type', M.str.lti.edittype, this.settings.edit_icon_url);
155 var deleteIcon = createIcon('lti_delete_tool_type', M.str.lti.deletetype, this.settings.delete_icon_url);
156
157 editIcon.on('click', function(e){
158 var toolTypeId = typeSelector.get('value');
159
160 if(self.getSelectedToolTypeOption().getAttribute('editable')){
161 window.open(self.settings.instructor_tool_type_edit_url + '&action=edit&typeid=' + toolTypeId, 'edit_tool');
162 } else {
163 alert(M.str.lti.cannot_edit);
164 }
165 });
166
167 addIcon.on('click', function(e){
168 window.open(self.settings.instructor_tool_type_edit_url + '&action=add', 'add_tool');
169 });
170
171 deleteIcon.on('click', function(e){
172 var toolTypeId = typeSelector.get('value');
173
174 if(self.getSelectedToolTypeOption().getAttribute('editable')){
175 if(confirm(M.str.lti.delete_confirmation)){
176
177 Y.io(self.settings.instructor_tool_type_edit_url + '&action=delete&typeid=' + toolTypeId, {
178 on: {
179 success: function(){
180 self.getSelectedToolTypeOption().remove();
181 },
182 failure: function(){
996b0fd9 183
6831c7cd
CS
184 }
185 }
186 });
187 }
188 } else {
189 alert(M.str.lti.cannot_delete);
190 }
191 });
192
193 typeSelector.insert(addIcon, 'after');
194 addIcon.insert(editIcon, 'after');
195 editIcon.insert(deleteIcon, 'after');
196 },
197
198 toggleEditButtons: function(){
199 var lti_edit_tool_type = Y.one('#lti_edit_tool_type');
200 var lti_delete_tool_type = Y.one('#lti_delete_tool_type');
201
202 //Make the edit / delete icons look enabled / disabled.
203 //Does not work in older browsers, but alerts will catch those cases.
204 if(this.getSelectedToolTypeOption().getAttribute('editable')){
205 lti_edit_tool_type.setStyle('opacity', '1');
206 lti_delete_tool_type.setStyle('opacity', '1');
207 } else {
208 lti_edit_tool_type.setStyle('opacity', '.2');
209 lti_delete_tool_type.setStyle('opacity', '.2');
210 }
211 },
212
213 addToolType: function(text, value){
214 var typeSelector = Y.one('#id_typeid');
215 var course_tool_group = Y.one('#course_tool_group');
216
217 var option = Y.Node.create('<option />')
218 .set('text', text)
219 .set('value', value)
220 .set('selected', 'selected')
221 .setAttribute('editable', '1')
222 .setAttribute('courseTool', '1');
223
224 if(course_tool_group){
225 course_tool_group.append(option);
226 } else {
227 typeSelector.append(option);
228 }
229 },
230
231 updateToolType: function(text, value){
232 var typeSelector = Y.one('#id_typeid');
233
234 var option = typeSelector.one('option[value=' + value + ']');
235 option.set('text', text);
236 },
237
238 findToolByUrl: function(url, callback){
239 Y.io(self.settings.ajax_url, {
240 data: { action: 'find_tool_config',
241 course: self.settings.courseId,
242 toolurl: url
243 },
996b0fd9 244
6831c7cd
CS
245 on: {
246 success: function(transactionid, xhr){
247 var response = xhr.response;
248
249 var toolInfo = Y.JSON.parse(response);
250
251 callback(toolInfo);
252 },
253 failure: function(){
996b0fd9 254
6831c7cd
CS
255 }
256 }
257 });
258 }
996b0fd9 259
6831c7cd
CS
260 };
261})();