Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/**
2
 * Section drag and drop.
3
 *
4
 * @class M.mod_quiz.dragdrop.section
5
 * @constructor
6
 * @extends M.core.dragdrop
7
 */
8
var DRAGSECTION = function() {
9
    DRAGSECTION.superclass.constructor.apply(this, arguments);
10
};
11
Y.extend(DRAGSECTION, M.core.dragdrop, {
12
    sectionlistselector: null,
13
 
14
    initializer: function() {
15
        // Set group for parent class
16
        this.groups = [CSS.SECTIONDRAGGABLE];
17
        this.samenodeclass = 'section';
18
        this.parentnodeclass = 'slots';
19
 
20
        // Check if we are in single section mode
21
        if (Y.Node.one('.' + CSS.JUMPMENU)) {
22
            return false;
23
        }
24
        // Initialise sections dragging
25
        this.sectionlistselector = 'li.section';
26
        if (this.sectionlistselector) {
27
            this.sectionlistselector = '.' + CSS.COURSECONTENT + ' ' + this.sectionlistselector;
28
 
29
            this.setup_for_section(this.sectionlistselector);
30
 
31
            // Make each li element in the lists of sections draggable
32
            var del = new Y.DD.Delegate({
33
                container: '.' + CSS.COURSECONTENT,
34
                nodes: '.' + CSS.SECTIONDRAGGABLE,
35
                target: true,
36
                handles: ['.' + CSS.LEFT],
37
                dragConfig: {groups: this.groups}
38
            });
39
            del.dd.plug(Y.Plugin.DDProxy, {
40
                // Don't move the node at the end of the drag
41
                moveOnEnd: false
42
            });
43
            del.dd.plug(Y.Plugin.DDConstrained, {
44
                // Keep it inside the .mod-quiz-edit-content
45
                constrain: '#' + CSS.PAGECONTENT,
46
                stickY: true
47
            });
48
            del.dd.plug(Y.Plugin.DDWinScroll);
49
        }
50
    },
51
 
52
    /**
53
     * Apply dragdrop features to the specified selector or node that refers to section(s)
54
     *
55
     * @method setup_for_section
56
     * @param {String} baseselector The CSS selector or node to limit scope to
57
     */
58
    setup_for_section: function(baseselector) {
59
        Y.Node.all(baseselector).each(function(sectionnode) {
60
            // Determine the section ID
61
            var sectionid = Y.Moodle.core_course.util.section.getId(sectionnode);
62
 
63
            // We skip the top section as it is not draggable
64
            if (sectionid > 0) {
65
                // Remove move icons
66
                var movedown = sectionnode.one('.' + CSS.RIGHT + ' a.' + CSS.MOVEDOWN);
67
                var moveup = sectionnode.one('.' + CSS.RIGHT + ' a.' + CSS.MOVEUP);
68
 
69
                // Add dragger icon
70
                var title = M.util.get_string('movesection', 'moodle', sectionid);
71
                var cssleft = sectionnode.one('.' + CSS.LEFT);
72
 
73
                if ((movedown || moveup) && cssleft) {
74
                    cssleft.setStyle('cursor', 'move');
75
                    cssleft.appendChild(this.get_drag_handle(title, CSS.SECTIONHANDLE, 'icon', true));
76
 
77
                    if (moveup) {
78
                        moveup.remove();
79
                    }
80
                    if (movedown) {
81
                        movedown.remove();
82
                    }
83
 
84
                    // This section can be moved - add the class to indicate this to Y.DD.
85
                    sectionnode.addClass(CSS.SECTIONDRAGGABLE);
86
                }
87
            }
88
        }, this);
89
    },
90
 
91
    /*
92
     * Drag-dropping related functions
93
     */
94
    drag_start: function(e) {
95
        // Get our drag object
96
        var drag = e.target;
97
        // Creat a dummy structure of the outer elemnents for clean styles application
98
        var containernode = Y.Node.create('<ul class="slots"></ul>');
99
        var sectionnode = Y.Node.create('<ul class="section"></ul>');
100
        sectionnode.setStyle('margin', 0);
101
        sectionnode.setContent(drag.get('node').get('innerHTML'));
102
        containernode.appendChild(sectionnode);
103
        drag.get('dragNode').setContent(containernode);
104
        drag.get('dragNode').addClass(CSS.COURSECONTENT);
105
    },
106
 
107
    drag_dropmiss: function(e) {
108
        // Missed the target, but we assume the user intended to drop it
109
        // on the last last ghost node location, e.drag and e.drop should be
110
        // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
111
        this.drop_hit(e);
112
    },
113
 
114
    get_section_index: function(node) {
115
        var sectionlistselector = '.' + CSS.COURSECONTENT + ' li.section',
116
            sectionList = Y.all(sectionlistselector),
117
            nodeIndex = sectionList.indexOf(node),
118
            zeroIndex = sectionList.indexOf(Y.one('#section-0'));
119
 
120
        return (nodeIndex - zeroIndex);
121
    },
122
 
123
    drop_hit: function(e) {
124
        var drag = e.drag;
125
 
126
        // Get references to our nodes and their IDs.
127
        var dragnode = drag.get('node'),
128
            dragnodeid = Y.Moodle.core_course.util.section.getId(dragnode),
129
            loopstart = dragnodeid,
130
 
131
            dropnodeindex = this.get_section_index(dragnode),
132
            loopend = dropnodeindex;
133
 
134
        if (dragnodeid === dropnodeindex) {
135
            Y.log("Skipping move - same location moving " + dragnodeid + " to " + dropnodeindex,
136
                  'debug', 'moodle-mod_quiz-dragdrop');
137
            return;
138
        }
139
 
140
        Y.log("Moving from position " + dragnodeid + " to position " + dropnodeindex, 'debug', 'moodle-mod_quiz-dragdrop');
141
 
142
        if (loopstart > loopend) {
143
            // If we're going up, we need to swap the loop order
144
            // because loops can't go backwards.
145
            loopstart = dropnodeindex;
146
            loopend = dragnodeid;
147
        }
148
 
149
        // Get the list of nodes.
150
        drag.get('dragNode').removeClass(CSS.COURSECONTENT);
151
        var sectionlist = Y.Node.all(this.sectionlistselector);
152
 
153
        // Add a lightbox if it's not there.
154
        var lightbox = M.util.add_lightbox(Y, dragnode);
155
 
156
        // Handle any variables which we must pass via AJAX.
157
        var params = {},
158
            pageparams = this.get('config').pageparams,
159
            varname;
160
 
161
        for (varname in pageparams) {
162
            if (!pageparams.hasOwnProperty(varname)) {
163
                continue;
164
            }
165
            params[varname] = pageparams[varname];
166
        }
167
 
168
        // Prepare request parameters
169
        params.sesskey = M.cfg.sesskey;
170
        params.courseid = this.get('courseid');
171
        params.quizid = this.get('quizid');
172
        params['class'] = 'section';
173
        params.field = 'move';
174
        params.id = dragnodeid;
175
        params.value = dropnodeindex;
176
 
177
        // Perform the AJAX request.
178
        var uri = M.cfg.wwwroot + this.get('ajaxurl');
179
        Y.io(uri, {
180
            method: 'POST',
181
            data: params,
182
            on: {
183
                start: function() {
184
                    lightbox.show();
185
                },
186
                success: function(tid, response) {
187
                    // Update section titles, we can't simply swap them as
188
                    // they might have custom title
189
                    try {
190
                        var responsetext = Y.JSON.parse(response.responseText);
191
                        if (responsetext.error) {
192
                            new M.core.ajaxException(responsetext);
193
                        }
194
                        M.mod_quiz.edit.process_sections(Y, sectionlist, responsetext, loopstart, loopend);
195
                    } catch (e) {
196
                        // Ignore.
197
                    }
198
 
199
                    // Update all of the section IDs - first unset them, then set them
200
                    // to avoid duplicates in the DOM.
201
                    var index;
202
 
203
                    // Classic bubble sort algorithm is applied to the section
204
                    // nodes between original drag node location and the new one.
205
                    var swapped = false;
206
                    do {
207
                        swapped = false;
208
                        for (index = loopstart; index <= loopend; index++) {
209
                            if (Y.Moodle.core_course.util.section.getId(sectionlist.item(index - 1)) >
210
                                        Y.Moodle.core_course.util.section.getId(sectionlist.item(index))) {
211
                                Y.log("Swapping " + Y.Moodle.core_course.util.section.getId(sectionlist.item(index - 1)) +
212
                                        " with " + Y.Moodle.core_course.util.section.getId(sectionlist.item(index)),
213
                                        "debug", "moodle-mod_quiz-dragdrop");
214
                                // Swap section id.
215
                                var sectionid = sectionlist.item(index - 1).get('id');
216
                                sectionlist.item(index - 1).set('id', sectionlist.item(index).get('id'));
217
                                sectionlist.item(index).set('id', sectionid);
218
 
219
                                // See what format needs to swap.
220
                                M.mod_quiz.edit.swap_sections(Y, index - 1, index);
221
 
222
                                // Update flag.
223
                                swapped = true;
224
                            }
225
                        }
226
                        loopend = loopend - 1;
227
                    } while (swapped);
228
 
229
                    window.setTimeout(function() {
230
                        lightbox.hide();
231
                    }, 250);
232
                },
233
 
234
                failure: function(tid, response) {
235
                    this.ajax_failure(response);
236
                    lightbox.hide();
237
                }
238
            },
239
            context: this
240
        });
241
    }
242
 
243
}, {
244
    NAME: 'mod_quiz-dragdrop-section',
245
    ATTRS: {
246
        courseid: {
247
            value: null
248
        },
249
        quizid: {
250
            value: null
251
        },
252
        ajaxurl: {
253
            value: 0
254
        },
255
        config: {
256
            value: 0
257
        }
258
    }
259
});
260
 
261
M.mod_quiz = M.mod_quiz || {};
262
M.mod_quiz.init_section_dragdrop = function(params) {
263
    new DRAGSECTION(params);
264
};