79fad16c3829477d879407fb83128cc45152049b
[moodle.git] / mod / lti / mod_form.js
1 (function(){
2     var Y;
3     var self;
4     
5     M.mod_lti = M.mod_lti || {};
7     M.mod_lti.editor = {
8         init: function(yui3, settings){
9             if(yui3){
10                 Y = yui3;
11             }
12             
13             self = this;
14             this.settings = Y.JSON.parse(settings);
16             this.urlCache = {};
18             this.addOptGroups();
20             var typeSelector = Y.one('#id_typeid');
21             typeSelector.on('change', function(e){
22                 self.toggleEditButtons();
23             });
25             this.createTypeEditorButtons();
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);
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         },
48         updateAutomaticToolMatch: function(){
49             var toolurl = Y.one('#id_toolurl');
50             var automatchToolDisplay = Y.one('#lti_automatch_tool');
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             }
60             var url = toolurl.get('value');
62             if(!url){
63                 automatchToolDisplay.setStyle('display', 'none');
64                 return;
65             }
67             var key = Y.one('#id_resourcekey');
68             var secret = Y.one('#id_password');
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', '');
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.');
83                         }
84                     }
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;
94                         continuation(toolInfo);
95                     });
96                 }
97             }
98         },
100         getSelectedToolTypeOption: function(){
101             var typeSelector = Y.one('#id_typeid');
103             return typeSelector.one('option[value=' + typeSelector.get('value') + ']');
104         },
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');
113             if(typeSelector.one('option[courseTool=1]')){
114                 //One ore more course tools exist
116                 var globalGroup = Y.Node.create('<optgroup />')
117                                     .set('id', 'global_tool_group')
118                                     .set('label', M.str.lti.global_tool_types);
120                 var courseGroup = Y.Node.create('<optgroup />')
121                                     .set('id', 'course_tool_group')
122                                     .set('label', M.str.lti.course_tool_types);
124                 typeSelector.all('option[globalTool=1]').remove().each(function(node){
125                     globalGroup.append(node);
126                 });
128                 typeSelector.all('option[courseTool=1]').remove().each(function(node){
129                     courseGroup.append(node);
130                 });
132                 typeSelector.append(globalGroup);
133                 typeSelector.append(courseGroup);
134             }
135         },
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');
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             }
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);
157             editIcon.on('click', function(e){
158                 var toolTypeId = typeSelector.get('value');
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             });
167             addIcon.on('click', function(e){
168                 window.open(self.settings.instructor_tool_type_edit_url + '&action=add', 'add_tool');
169             });
171             deleteIcon.on('click', function(e){
172                 var toolTypeId = typeSelector.get('value');
174                 if(self.getSelectedToolTypeOption().getAttribute('editable')){
175                     if(confirm(M.str.lti.delete_confirmation)){
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(){
184                                 }
185                             }
186                         });
187                     }
188                 } else {
189                     alert(M.str.lti.cannot_delete);
190                 }
191             });
193             typeSelector.insert(addIcon, 'after');
194             addIcon.insert(editIcon, 'after');
195             editIcon.insert(deleteIcon, 'after');
196         },
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');
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         },
213         addToolType: function(text, value){
214             var typeSelector = Y.one('#id_typeid');
215             var course_tool_group = Y.one('#course_tool_group');
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');
224             if(course_tool_group){
225                 course_tool_group.append(option);
226             } else {
227                 typeSelector.append(option);
228             }
229         },
231         updateToolType: function(text, value){
232             var typeSelector = Y.one('#id_typeid');
234             var option = typeSelector.one('option[value=' + value + ']');
235             option.set('text', text);
236         },
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                 },
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(){
255                     }
256                 }
257             });
258         }
260     };
261 })();