| 1 | efrain | 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;
 | 
        
           |  |  | 17 |   | 
        
           |  |  | 18 |         this.samenodelabel = {
 | 
        
           |  |  | 19 |             identifier: 'afterresource',
 | 
        
           |  |  | 20 |             component: 'moodle'
 | 
        
           |  |  | 21 |         };
 | 
        
           |  |  | 22 |         this.parentnodelabel = {
 | 
        
           |  |  | 23 |             identifier: 'totopofsection',
 | 
        
           |  |  | 24 |             component: 'moodle'
 | 
        
           |  |  | 25 |         };
 | 
        
           |  |  | 26 |   | 
        
           |  |  | 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);
 | 
        
           |  |  | 32 |   | 
        
           |  |  | 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);
 | 
        
           |  |  | 52 |   | 
        
           |  |  | 53 |             M.course.coursebase.register_module(this);
 | 
        
           |  |  | 54 |             M.course.dragres = this;
 | 
        
           |  |  | 55 |         }
 | 
        
           |  |  | 56 |     },
 | 
        
           |  |  | 57 |   | 
        
           |  |  | 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 |             });
 | 
        
           |  |  | 80 |   | 
        
           |  |  | 81 |             // Initialise each resource/activity in this section
 | 
        
           |  |  | 82 |             this.setup_for_resource('#' + sectionnode.get('id') + ' li.' + CSS.ACTIVITY);
 | 
        
           |  |  | 83 |         }, this);
 | 
        
           |  |  | 84 |     },
 | 
        
           |  |  | 85 |   | 
        
           |  |  | 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 |             }
 | 
        
           |  |  | 105 |   | 
        
           |  |  | 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 |     },
 | 
        
           |  |  | 115 |   | 
        
           |  |  | 116 |     drag_start: function(e) {
 | 
        
           |  |  | 117 |         // Get our drag object
 | 
        
           |  |  | 118 |         var drag = e.target;
 | 
        
           |  |  | 119 |         if (drag.get('dragNode') === drag.get('node')) {
 | 
        
           |  |  | 120 |             // We do not want to modify the contents of the real node.
 | 
        
           |  |  | 121 |             // They will be the same during a keyboard drag and drop.
 | 
        
           |  |  | 122 |             return;
 | 
        
           |  |  | 123 |         }
 | 
        
           |  |  | 124 |         drag.get('dragNode').setContent(drag.get('node').get('innerHTML'));
 | 
        
           |  |  | 125 |         drag.get('dragNode').all('img.iconsmall').setStyle('vertical-align', 'baseline');
 | 
        
           |  |  | 126 |     },
 | 
        
           |  |  | 127 |   | 
        
           |  |  | 128 |     drag_dropmiss: function(e) {
 | 
        
           |  |  | 129 |         // Missed the target, but we assume the user intended to drop it
 | 
        
           |  |  | 130 |         // on the last last ghost node location, e.drag and e.drop should be
 | 
        
           |  |  | 131 |         // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
 | 
        
           |  |  | 132 |         this.drop_hit(e);
 | 
        
           |  |  | 133 |     },
 | 
        
           |  |  | 134 |   | 
        
           |  |  | 135 |     drop_hit: function(e) {
 | 
        
           |  |  | 136 |         var drag = e.drag;
 | 
        
           |  |  | 137 |         // Get a reference to our drag node
 | 
        
           |  |  | 138 |         var dragnode = drag.get('node');
 | 
        
           |  |  | 139 |         var dropnode = e.drop.get('node');
 | 
        
           |  |  | 140 |   | 
        
           |  |  | 141 |         // Add spinner if it not there
 | 
        
           |  |  | 142 |         var actionarea = dragnode.one(CSS.ACTIONAREA);
 | 
        
           |  |  | 143 |         var spinner = M.util.add_spinner(Y, actionarea);
 | 
        
           |  |  | 144 |   | 
        
           |  |  | 145 |         var params = {};
 | 
        
           |  |  | 146 |   | 
        
           |  |  | 147 |         // Handle any variables which we must pass back through to
 | 
        
           |  |  | 148 |         var pageparams = this.get('config').pageparams;
 | 
        
           |  |  | 149 |         var varname;
 | 
        
           |  |  | 150 |         for (varname in pageparams) {
 | 
        
           |  |  | 151 |             params[varname] = pageparams[varname];
 | 
        
           |  |  | 152 |         }
 | 
        
           |  |  | 153 |   | 
        
           |  |  | 154 |         // Variables needed to update the course state.
 | 
        
           |  |  | 155 |         var cmid = Number(Y.Moodle.core_course.util.cm.getId(dragnode));
 | 
        
           |  |  | 156 |         var beforeid = null;
 | 
        
           |  |  | 157 |   | 
        
           |  |  | 158 |         // Prepare request parameters
 | 
        
           |  |  | 159 |         params.sesskey = M.cfg.sesskey;
 | 
        
           |  |  | 160 |         params.courseId = this.get('courseid');
 | 
        
           |  |  | 161 |         params['class'] = 'resource';
 | 
        
           |  |  | 162 |         params.field = 'move';
 | 
        
           |  |  | 163 |         params.id = cmid;
 | 
        
           |  |  | 164 |         params.sectionId = Y.Moodle.core_course.util.section.getId(dropnode.ancestor(M.course.format.get_section_wrapper(Y), true));
 | 
        
           |  |  | 165 |   | 
        
           |  |  | 166 |         if (dragnode.next()) {
 | 
        
           |  |  | 167 |             beforeid = Number(Y.Moodle.core_course.util.cm.getId(dragnode.next()));
 | 
        
           |  |  | 168 |             params.beforeId = beforeid;
 | 
        
           |  |  | 169 |         }
 | 
        
           |  |  | 170 |   | 
        
           |  |  | 171 |         // Do AJAX request
 | 
        
           |  |  | 172 |         var uri = M.cfg.wwwroot + this.get('ajaxurl');
 | 
        
           |  |  | 173 |   | 
        
           |  |  | 174 |         Y.io(uri, {
 | 
        
           |  |  | 175 |             method: 'POST',
 | 
        
           |  |  | 176 |             data: params,
 | 
        
           |  |  | 177 |             on: {
 | 
        
           |  |  | 178 |                 start: function() {
 | 
        
           |  |  | 179 |                     this.lock_drag_handle(drag, CSS.EDITINGMOVE);
 | 
        
           |  |  | 180 |                     spinner.show();
 | 
        
           |  |  | 181 |                 },
 | 
        
           |  |  | 182 |                 success: function(tid, response) {
 | 
        
           |  |  | 183 |                     var responsetext = Y.JSON.parse(response.responseText);
 | 
        
           |  |  | 184 |                     // Update course state.
 | 
        
           |  |  | 185 |                     M.course.coursebase.invoke_function(
 | 
        
           |  |  | 186 |                         'updateMovedCmState',
 | 
        
           |  |  | 187 |                         {
 | 
        
           |  |  | 188 |                             cmid: cmid,
 | 
        
           |  |  | 189 |                             beforeid: beforeid,
 | 
        
           |  |  | 190 |                             visible: responsetext.visible,
 | 
        
           |  |  | 191 |                         }
 | 
        
           |  |  | 192 |                     );
 | 
        
           |  |  | 193 |                     // Set visibility in course content.
 | 
        
           |  |  | 194 |                     var params = {element: dragnode, visible: responsetext.visible};
 | 
        
           |  |  | 195 |                     M.course.coursebase.invoke_function('set_visibility_resource_ui', params);
 | 
        
           |  |  | 196 |                     this.unlock_drag_handle(drag, CSS.EDITINGMOVE);
 | 
        
           |  |  | 197 |                     window.setTimeout(function() {
 | 
        
           |  |  | 198 |                         spinner.hide();
 | 
        
           |  |  | 199 |                     }, 250);
 | 
        
           |  |  | 200 |                 },
 | 
        
           |  |  | 201 |                 failure: function(tid, response) {
 | 
        
           |  |  | 202 |                     this.ajax_failure(response);
 | 
        
           |  |  | 203 |                     this.unlock_drag_handle(drag, CSS.SECTIONHANDLE);
 | 
        
           |  |  | 204 |                     spinner.hide();
 | 
        
           |  |  | 205 |                     // TODO: revert nodes location
 | 
        
           |  |  | 206 |                 }
 | 
        
           |  |  | 207 |             },
 | 
        
           |  |  | 208 |             context: this
 | 
        
           |  |  | 209 |         });
 | 
        
           |  |  | 210 |     }
 | 
        
           |  |  | 211 | }, {
 | 
        
           |  |  | 212 |     NAME: 'course-dragdrop-resource',
 | 
        
           |  |  | 213 |     ATTRS: {
 | 
        
           |  |  | 214 |         courseid: {
 | 
        
           |  |  | 215 |             value: null
 | 
        
           |  |  | 216 |         },
 | 
        
           |  |  | 217 |         ajaxurl: {
 | 
        
           |  |  | 218 |             value: 0
 | 
        
           |  |  | 219 |         },
 | 
        
           |  |  | 220 |         config: {
 | 
        
           |  |  | 221 |             value: 0
 | 
        
           |  |  | 222 |         }
 | 
        
           |  |  | 223 |     }
 | 
        
           |  |  | 224 | });
 | 
        
           |  |  | 225 |   | 
        
           |  |  | 226 | M.course = M.course || {};
 | 
        
           |  |  | 227 | M.course.init_resource_dragdrop = function(params) {
 | 
        
           |  |  | 228 |     new DRAGRESOURCE(params);
 | 
        
           |  |  | 229 | };
 |