MDL-67818 check: Rename renderer to be less generic
[moodle.git] / course / yui / src / dragdrop / js / resource.js
1 /**
2  * Resource drag and drop.
3  *
4  * @class M.course.dragdrop.resource
5  * @constructor
6  * @extends M.core.dragdrop
7  */
8 var DRAGRESOURCE = function() {
9     DRAGRESOURCE.superclass.constructor.apply(this, arguments);
10 };
11 Y.extend(DRAGRESOURCE, M.core.dragdrop, {
12     initializer: function() {
13         // Set group for parent class
14         this.groups = ['resource'];
15         this.samenodeclass = CSS.ACTIVITY;
16         this.parentnodeclass = CSS.SECTION;
18         this.samenodelabel = {
19             identifier: 'afterresource',
20             component: 'moodle'
21         };
22         this.parentnodelabel = {
23             identifier: 'totopofsection',
24             component: 'moodle'
25         };
27         // Go through all sections
28         var sectionlistselector = M.course.format.get_section_selector(Y);
29         if (sectionlistselector) {
30             sectionlistselector = '.' + CSS.COURSECONTENT + ' ' + sectionlistselector;
31             this.setup_for_section(sectionlistselector);
33             // Initialise drag & drop for all resources/activities
34             var nodeselector = sectionlistselector.slice(CSS.COURSECONTENT.length + 2) + ' li.' + CSS.ACTIVITY;
35             var del = new Y.DD.Delegate({
36                 container: '.' + CSS.COURSECONTENT,
37                 nodes: nodeselector,
38                 target: true,
39                 handles: ['.' + CSS.EDITINGMOVE],
40                 dragConfig: {groups: this.groups}
41             });
42             del.dd.plug(Y.Plugin.DDProxy, {
43                 // Don't move the node at the end of the drag
44                 moveOnEnd: false,
45                 cloneNode: true
46             });
47             del.dd.plug(Y.Plugin.DDConstrained, {
48                 // Keep it inside the .course-content
49                 constrain: '#' + CSS.PAGECONTENT
50             });
51             del.dd.plug(Y.Plugin.DDWinScroll);
53             M.course.coursebase.register_module(this);
54             M.course.dragres = this;
55         }
56     },
58     /**
59      * Apply dragdrop features to the specified selector or node that refers to section(s)
60      *
61      * @method setup_for_section
62      * @param {String} baseselector The CSS selector or node to limit scope to
63      */
64     setup_for_section: function(baseselector) {
65         Y.Node.all(baseselector).each(function(sectionnode) {
66             var resources = sectionnode.one('.' + CSS.CONTENT + ' ul.' + CSS.SECTION);
67             // See if resources ul exists, if not create one
68             if (!resources) {
69                 resources = Y.Node.create('<ul></ul>');
70                 resources.addClass(CSS.SECTION);
71                 sectionnode.one('.' + CSS.CONTENT + ' div.' + CSS.SUMMARY).insert(resources, 'after');
72             }
73             resources.setAttribute('data-draggroups', this.groups.join(' '));
74             // Define empty ul as droptarget, so that item could be moved to empty list
75             new Y.DD.Drop({
76                 node: resources,
77                 groups: this.groups,
78                 padding: '20 0 20 0'
79             });
81             // Initialise each resource/activity in this section
82             this.setup_for_resource('#' + sectionnode.get('id') + ' li.' + CSS.ACTIVITY);
83         }, this);
84     },
86     /**
87      * Apply dragdrop features to the specified selector or node that refers to resource(s)
88      *
89      * @method setup_for_resource
90      * @param {String} baseselector The CSS selector or node to limit scope to
91      */
92     setup_for_resource: function(baseselector) {
93         Y.Node.all(baseselector).each(function(resourcesnode) {
94             var draggroups = resourcesnode.getData('draggroups');
95             if (!draggroups) {
96                 // This Drop Node has not been set up. Configure it now.
97                 resourcesnode.setAttribute('data-draggroups', this.groups.join(' '));
98                 // Define empty ul as droptarget, so that item could be moved to empty list
99                 new Y.DD.Drop({
100                     node: resourcesnode,
101                     groups: this.groups,
102                     padding: '20 0 20 0'
103                 });
104             }
106             // Replace move icons
107             var move = resourcesnode.one('a.' + CSS.EDITINGMOVE);
108             if (move) {
109                 var sr = move.getData('sectionreturn');
110                 move.replace(this.get_drag_handle(M.util.get_string('movecoursemodule', 'moodle'),
111                              CSS.EDITINGMOVE, CSS.ICONCLASS, true).setAttribute('data-sectionreturn', sr));
112             }
113         }, this);
114     },
116     drag_start: function(e) {
117         // Get our drag object
118         var drag = e.target;
119         drag.get('dragNode').setContent(drag.get('node').get('innerHTML'));
120         drag.get('dragNode').all('img.iconsmall').setStyle('vertical-align', 'baseline');
121     },
123     drag_dropmiss: function(e) {
124         // Missed the target, but we assume the user intended to drop it
125         // on the last last ghost node location, e.drag and e.drop should be
126         // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
127         this.drop_hit(e);
128     },
130     drop_hit: function(e) {
131         var drag = e.drag;
132         // Get a reference to our drag node
133         var dragnode = drag.get('node');
134         var dropnode = e.drop.get('node');
136         // Add spinner if it not there
137         var actionarea = dragnode.one(CSS.ACTIONAREA);
138         var spinner = M.util.add_spinner(Y, actionarea);
140         var params = {};
142         // Handle any variables which we must pass back through to
143         var pageparams = this.get('config').pageparams;
144         var varname;
145         for (varname in pageparams) {
146             params[varname] = pageparams[varname];
147         }
149         // Prepare request parameters
150         params.sesskey = M.cfg.sesskey;
151         params.courseId = this.get('courseid');
152         params['class'] = 'resource';
153         params.field = 'move';
154         params.id = Number(Y.Moodle.core_course.util.cm.getId(dragnode));
155         params.sectionId = Y.Moodle.core_course.util.section.getId(dropnode.ancestor(M.course.format.get_section_wrapper(Y), true));
157         if (dragnode.next()) {
158             params.beforeId = Number(Y.Moodle.core_course.util.cm.getId(dragnode.next()));
159         }
161         // Do AJAX request
162         var uri = M.cfg.wwwroot + this.get('ajaxurl');
164         Y.io(uri, {
165             method: 'POST',
166             data: params,
167             on: {
168                 start: function() {
169                     this.lock_drag_handle(drag, CSS.EDITINGMOVE);
170                     spinner.show();
171                 },
172                 success: function(tid, response) {
173                     var responsetext = Y.JSON.parse(response.responseText);
174                     var params = {element: dragnode, visible: responsetext.visible};
175                     M.course.coursebase.invoke_function('set_visibility_resource_ui', params);
176                     this.unlock_drag_handle(drag, CSS.EDITINGMOVE);
177                     window.setTimeout(function() {
178                         spinner.hide();
179                     }, 250);
180                 },
181                 failure: function(tid, response) {
182                     this.ajax_failure(response);
183                     this.unlock_drag_handle(drag, CSS.SECTIONHANDLE);
184                     spinner.hide();
185                     // TODO: revert nodes location
186                 }
187             },
188             context: this
189         });
190     }
191 }, {
192     NAME: 'course-dragdrop-resource',
193     ATTRS: {
194         courseid: {
195             value: null
196         },
197         ajaxurl: {
198             value: 0
199         },
200         config: {
201             value: 0
202         }
203     }
204 });
206 M.course = M.course || {};
207 M.course.init_resource_dragdrop = function(params) {
208     new DRAGRESOURCE(params);
209 };