[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/quiz/yui/build/moodle-mod_quiz-dragdrop/ -> moodle-mod_quiz-dragdrop-debug.js (source)

   1  YUI.add('moodle-mod_quiz-dragdrop', function (Y, NAME) {
   2  
   3  /* eslint-disable no-unused-vars */
   4  /**
   5   * Drag and Drop for Quiz sections and slots.
   6   *
   7   * @module moodle-mod-quiz-dragdrop
   8   */
   9  
  10  var CSS = {
  11      ACTIONAREA: '.actions',
  12      ACTIVITY: 'activity',
  13      ACTIVITYINSTANCE: 'activityinstance',
  14      CONTENT: 'content',
  15      COURSECONTENT: 'mod-quiz-edit-content',
  16      EDITINGMOVE: 'editing_move',
  17      ICONCLASS: 'iconsmall',
  18      JUMPMENU: 'jumpmenu',
  19      LEFT: 'left',
  20      LIGHTBOX: 'lightbox',
  21      MOVEDOWN: 'movedown',
  22      MOVEUP: 'moveup',
  23      PAGE: 'page',
  24      PAGECONTENT: 'page-content',
  25      RIGHT: 'right',
  26      SECTION: 'slots',
  27      SECTIONADDMENUS: 'section_add_menus',
  28      SECTIONHANDLE: 'section-handle',
  29      SLOTS: 'slots',
  30      SUMMARY: 'summary',
  31      SECTIONDRAGGABLE: 'sectiondraggable'
  32  },
  33  // The CSS selectors we use.
  34  SELECTOR = {
  35      PAGE: 'li.page',
  36      SLOT: 'li.slot'
  37  };
  38  /**
  39   * Section drag and drop.
  40   *
  41   * @class M.mod_quiz.dragdrop.section
  42   * @constructor
  43   * @extends M.core.dragdrop
  44   */
  45  var DRAGSECTION = function() {
  46      DRAGSECTION.superclass.constructor.apply(this, arguments);
  47  };
  48  Y.extend(DRAGSECTION, M.core.dragdrop, {
  49      sectionlistselector: null,
  50  
  51      initializer: function() {
  52          // Set group for parent class
  53          this.groups = [CSS.SECTIONDRAGGABLE];
  54          this.samenodeclass = 'section';
  55          this.parentnodeclass = 'slots';
  56  
  57          // Check if we are in single section mode
  58          if (Y.Node.one('.' + CSS.JUMPMENU)) {
  59              return false;
  60          }
  61          // Initialise sections dragging
  62          this.sectionlistselector = 'li.section';
  63          if (this.sectionlistselector) {
  64              this.sectionlistselector = '.' + CSS.COURSECONTENT + ' ' + this.sectionlistselector;
  65  
  66              this.setup_for_section(this.sectionlistselector);
  67  
  68              // Make each li element in the lists of sections draggable
  69              var del = new Y.DD.Delegate({
  70                  container: '.' + CSS.COURSECONTENT,
  71                  nodes: '.' + CSS.SECTIONDRAGGABLE,
  72                  target: true,
  73                  handles: ['.' + CSS.LEFT],
  74                  dragConfig: {groups: this.groups}
  75              });
  76              del.dd.plug(Y.Plugin.DDProxy, {
  77                  // Don't move the node at the end of the drag
  78                  moveOnEnd: false
  79              });
  80              del.dd.plug(Y.Plugin.DDConstrained, {
  81                  // Keep it inside the .mod-quiz-edit-content
  82                  constrain: '#' + CSS.PAGECONTENT,
  83                  stickY: true
  84              });
  85              del.dd.plug(Y.Plugin.DDWinScroll);
  86          }
  87      },
  88  
  89      /**
  90       * Apply dragdrop features to the specified selector or node that refers to section(s)
  91       *
  92       * @method setup_for_section
  93       * @param {String} baseselector The CSS selector or node to limit scope to
  94       */
  95      setup_for_section: function(baseselector) {
  96          Y.Node.all(baseselector).each(function(sectionnode) {
  97              // Determine the section ID
  98              var sectionid = Y.Moodle.core_course.util.section.getId(sectionnode);
  99  
 100              // We skip the top section as it is not draggable
 101              if (sectionid > 0) {
 102                  // Remove move icons
 103                  var movedown = sectionnode.one('.' + CSS.RIGHT + ' a.' + CSS.MOVEDOWN);
 104                  var moveup = sectionnode.one('.' + CSS.RIGHT + ' a.' + CSS.MOVEUP);
 105  
 106                  // Add dragger icon
 107                  var title = M.util.get_string('movesection', 'moodle', sectionid);
 108                  var cssleft = sectionnode.one('.' + CSS.LEFT);
 109  
 110                  if ((movedown || moveup) && cssleft) {
 111                      cssleft.setStyle('cursor', 'move');
 112                      cssleft.appendChild(this.get_drag_handle(title, CSS.SECTIONHANDLE, 'icon', true));
 113  
 114                      if (moveup) {
 115                          moveup.remove();
 116                      }
 117                      if (movedown) {
 118                          movedown.remove();
 119                      }
 120  
 121                      // This section can be moved - add the class to indicate this to Y.DD.
 122                      sectionnode.addClass(CSS.SECTIONDRAGGABLE);
 123                  }
 124              }
 125          }, this);
 126      },
 127  
 128      /*
 129       * Drag-dropping related functions
 130       */
 131      drag_start: function(e) {
 132          // Get our drag object
 133          var drag = e.target;
 134          // Creat a dummy structure of the outer elemnents for clean styles application
 135          var containernode = Y.Node.create('<ul class="slots"></ul>');
 136          var sectionnode = Y.Node.create('<ul class="section"></ul>');
 137          sectionnode.setStyle('margin', 0);
 138          sectionnode.setContent(drag.get('node').get('innerHTML'));
 139          containernode.appendChild(sectionnode);
 140          drag.get('dragNode').setContent(containernode);
 141          drag.get('dragNode').addClass(CSS.COURSECONTENT);
 142      },
 143  
 144      drag_dropmiss: function(e) {
 145          // Missed the target, but we assume the user intended to drop it
 146          // on the last last ghost node location, e.drag and e.drop should be
 147          // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
 148          this.drop_hit(e);
 149      },
 150  
 151      get_section_index: function(node) {
 152          var sectionlistselector = '.' + CSS.COURSECONTENT + ' li.section',
 153              sectionList = Y.all(sectionlistselector),
 154              nodeIndex = sectionList.indexOf(node),
 155              zeroIndex = sectionList.indexOf(Y.one('#section-0'));
 156  
 157          return (nodeIndex - zeroIndex);
 158      },
 159  
 160      drop_hit: function(e) {
 161          var drag = e.drag;
 162  
 163          // Get references to our nodes and their IDs.
 164          var dragnode = drag.get('node'),
 165              dragnodeid = Y.Moodle.core_course.util.section.getId(dragnode),
 166              loopstart = dragnodeid,
 167  
 168              dropnodeindex = this.get_section_index(dragnode),
 169              loopend = dropnodeindex;
 170  
 171          if (dragnodeid === dropnodeindex) {
 172              Y.log("Skipping move - same location moving " + dragnodeid + " to " + dropnodeindex,
 173                    'debug', 'moodle-mod_quiz-dragdrop');
 174              return;
 175          }
 176  
 177          Y.log("Moving from position " + dragnodeid + " to position " + dropnodeindex, 'debug', 'moodle-mod_quiz-dragdrop');
 178  
 179          if (loopstart > loopend) {
 180              // If we're going up, we need to swap the loop order
 181              // because loops can't go backwards.
 182              loopstart = dropnodeindex;
 183              loopend = dragnodeid;
 184          }
 185  
 186          // Get the list of nodes.
 187          drag.get('dragNode').removeClass(CSS.COURSECONTENT);
 188          var sectionlist = Y.Node.all(this.sectionlistselector);
 189  
 190          // Add a lightbox if it's not there.
 191          var lightbox = M.util.add_lightbox(Y, dragnode);
 192  
 193          // Handle any variables which we must pass via AJAX.
 194          var params = {},
 195              pageparams = this.get('config').pageparams,
 196              varname;
 197  
 198          for (varname in pageparams) {
 199              if (!pageparams.hasOwnProperty(varname)) {
 200                  continue;
 201              }
 202              params[varname] = pageparams[varname];
 203          }
 204  
 205          // Prepare request parameters
 206          params.sesskey = M.cfg.sesskey;
 207          params.courseid = this.get('courseid');
 208          params.quizid = this.get('quizid');
 209          params['class'] = 'section';
 210          params.field = 'move';
 211          params.id = dragnodeid;
 212          params.value = dropnodeindex;
 213  
 214          // Perform the AJAX request.
 215          var uri = M.cfg.wwwroot + this.get('ajaxurl');
 216          Y.io(uri, {
 217              method: 'POST',
 218              data: params,
 219              on: {
 220                  start: function() {
 221                      lightbox.show();
 222                  },
 223                  success: function(tid, response) {
 224                      // Update section titles, we can't simply swap them as
 225                      // they might have custom title
 226                      try {
 227                          var responsetext = Y.JSON.parse(response.responseText);
 228                          if (responsetext.error) {
 229                              new M.core.ajaxException(responsetext);
 230                          }
 231                          M.mod_quiz.edit.process_sections(Y, sectionlist, responsetext, loopstart, loopend);
 232                      } catch (e) {
 233                          // Ignore.
 234                      }
 235  
 236                      // Update all of the section IDs - first unset them, then set them
 237                      // to avoid duplicates in the DOM.
 238                      var index;
 239  
 240                      // Classic bubble sort algorithm is applied to the section
 241                      // nodes between original drag node location and the new one.
 242                      var swapped = false;
 243                      do {
 244                          swapped = false;
 245                          for (index = loopstart; index <= loopend; index++) {
 246                              if (Y.Moodle.core_course.util.section.getId(sectionlist.item(index - 1)) >
 247                                          Y.Moodle.core_course.util.section.getId(sectionlist.item(index))) {
 248                                  Y.log("Swapping " + Y.Moodle.core_course.util.section.getId(sectionlist.item(index - 1)) +
 249                                          " with " + Y.Moodle.core_course.util.section.getId(sectionlist.item(index)),
 250                                          "debug", "moodle-mod_quiz-dragdrop");
 251                                  // Swap section id.
 252                                  var sectionid = sectionlist.item(index - 1).get('id');
 253                                  sectionlist.item(index - 1).set('id', sectionlist.item(index).get('id'));
 254                                  sectionlist.item(index).set('id', sectionid);
 255  
 256                                  // See what format needs to swap.
 257                                  M.mod_quiz.edit.swap_sections(Y, index - 1, index);
 258  
 259                                  // Update flag.
 260                                  swapped = true;
 261                              }
 262                          }
 263                          loopend = loopend - 1;
 264                      } while (swapped);
 265  
 266                      window.setTimeout(function() {
 267                          lightbox.hide();
 268                      }, 250);
 269                  },
 270  
 271                  failure: function(tid, response) {
 272                      this.ajax_failure(response);
 273                      lightbox.hide();
 274                  }
 275              },
 276              context: this
 277          });
 278      }
 279  
 280  }, {
 281      NAME: 'mod_quiz-dragdrop-section',
 282      ATTRS: {
 283          courseid: {
 284              value: null
 285          },
 286          quizid: {
 287              value: null
 288          },
 289          ajaxurl: {
 290              value: 0
 291          },
 292          config: {
 293              value: 0
 294          }
 295      }
 296  });
 297  
 298  M.mod_quiz = M.mod_quiz || {};
 299  M.mod_quiz.init_section_dragdrop = function(params) {
 300      new DRAGSECTION(params);
 301  };
 302  /* global SELECTOR */
 303  /**
 304   * Resource drag and drop.
 305   *
 306   * @class M.course.dragdrop.resource
 307   * @constructor
 308   * @extends M.core.dragdrop
 309   */
 310  var DRAGRESOURCE = function() {
 311      DRAGRESOURCE.superclass.constructor.apply(this, arguments);
 312  };
 313  Y.extend(DRAGRESOURCE, M.core.dragdrop, {
 314      initializer: function() {
 315          // Set group for parent class
 316          this.groups = ['resource'];
 317          this.samenodeclass = CSS.ACTIVITY;
 318          this.parentnodeclass = CSS.SECTION;
 319          this.resourcedraghandle = this.get_drag_handle(M.util.get_string('move', 'moodle'), CSS.EDITINGMOVE, CSS.ICONCLASS, true);
 320  
 321          this.samenodelabel = {
 322              identifier: 'dragtoafter',
 323              component: 'quiz'
 324          };
 325          this.parentnodelabel = {
 326              identifier: 'dragtostart',
 327              component: 'quiz'
 328          };
 329  
 330          // Go through all sections
 331          this.setup_for_section();
 332  
 333          // Initialise drag & drop for all resources/activities
 334          var nodeselector = 'li.' + CSS.ACTIVITY;
 335          var del = new Y.DD.Delegate({
 336              container: '.' + CSS.COURSECONTENT,
 337              nodes: nodeselector,
 338              target: true,
 339              handles: ['.' + CSS.EDITINGMOVE],
 340              dragConfig: {groups: this.groups}
 341          });
 342          del.dd.plug(Y.Plugin.DDProxy, {
 343              // Don't move the node at the end of the drag
 344              moveOnEnd: false,
 345              cloneNode: true
 346          });
 347          del.dd.plug(Y.Plugin.DDConstrained, {
 348              // Keep it inside the .mod-quiz-edit-content
 349              constrain: '#' + CSS.SLOTS
 350          });
 351          del.dd.plug(Y.Plugin.DDWinScroll);
 352  
 353          M.mod_quiz.quizbase.register_module(this);
 354          M.mod_quiz.dragres = this;
 355      },
 356  
 357      /**
 358       * Apply dragdrop features to the specified selector or node that refers to section(s)
 359       *
 360       * @method setup_for_section
 361       * @param {String} baseselector The CSS selector or node to limit scope to
 362       */
 363      setup_for_section: function() {
 364          Y.Node.all('.mod-quiz-edit-content ul.slots ul.section').each(function(resources) {
 365              resources.setAttribute('data-draggroups', this.groups.join(' '));
 366              // Define empty ul as droptarget, so that item could be moved to empty list
 367              new Y.DD.Drop({
 368                  node: resources,
 369                  groups: this.groups,
 370                  padding: '20 0 20 0'
 371              });
 372  
 373              // Initialise each resource/activity in this section
 374              this.setup_for_resource('li.activity');
 375          }, this);
 376      },
 377  
 378      /**
 379       * Apply dragdrop features to the specified selector or node that refers to resource(s)
 380       *
 381       * @method setup_for_resource
 382       * @param {String} baseselector The CSS selector or node to limit scope to
 383       */
 384      setup_for_resource: function(baseselector) {
 385          Y.Node.all(baseselector).each(function(resourcesnode) {
 386              // Replace move icons
 387              var move = resourcesnode.one('a.' + CSS.EDITINGMOVE);
 388              if (move) {
 389                  move.replace(this.resourcedraghandle.cloneNode(true));
 390              }
 391          }, this);
 392      },
 393  
 394      drag_start: function(e) {
 395          // Get our drag object
 396          var drag = e.target;
 397          drag.get('dragNode').setContent(drag.get('node').get('innerHTML'));
 398          drag.get('dragNode').all('img.iconsmall').setStyle('vertical-align', 'baseline');
 399      },
 400  
 401      drag_dropmiss: function(e) {
 402          // Missed the target, but we assume the user intended to drop it
 403          // on the last ghost node location, e.drag and e.drop should be
 404          // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
 405          this.drop_hit(e);
 406      },
 407  
 408      drop_hit: function(e) {
 409          var drag = e.drag;
 410          // Get a reference to our drag node
 411          var dragnode = drag.get('node');
 412          var dropnode = e.drop.get('node');
 413  
 414          // Add spinner if it not there
 415          var actionarea = dragnode.one(CSS.ACTIONAREA);
 416          var spinner = M.util.add_spinner(Y, actionarea);
 417  
 418          var params = {};
 419  
 420          // Handle any variables which we must pass back through to
 421          var pageparams = this.get('config').pageparams;
 422          var varname;
 423          for (varname in pageparams) {
 424              params[varname] = pageparams[varname];
 425          }
 426  
 427          // Prepare request parameters
 428          params.sesskey = M.cfg.sesskey;
 429          params.courseid = this.get('courseid');
 430          params.quizid = this.get('quizid');
 431          params['class'] = 'resource';
 432          params.field = 'move';
 433          params.id = Number(Y.Moodle.mod_quiz.util.slot.getId(dragnode));
 434          params.sectionId = Y.Moodle.core_course.util.section.getId(dropnode.ancestor('li.section', true));
 435  
 436          var previousslot = dragnode.previous(SELECTOR.SLOT);
 437          if (previousslot) {
 438              params.previousid = Number(Y.Moodle.mod_quiz.util.slot.getId(previousslot));
 439          }
 440  
 441          var previouspage = dragnode.previous(SELECTOR.PAGE);
 442          if (previouspage) {
 443              params.page = Number(Y.Moodle.mod_quiz.util.page.getId(previouspage));
 444          }
 445  
 446          // Do AJAX request
 447          var uri = M.cfg.wwwroot + this.get('ajaxurl');
 448  
 449          Y.io(uri, {
 450              method: 'POST',
 451              data: params,
 452              on: {
 453                  start: function() {
 454                      this.lock_drag_handle(drag, CSS.EDITINGMOVE);
 455                      spinner.show();
 456                  },
 457                  success: function(tid, response) {
 458                      var responsetext = Y.JSON.parse(response.responseText);
 459                      var params = {element: dragnode, visible: responsetext.visible};
 460                      M.mod_quiz.quizbase.invoke_function('set_visibility_resource_ui', params);
 461                      this.unlock_drag_handle(drag, CSS.EDITINGMOVE);
 462                      window.setTimeout(function() {
 463                          spinner.hide();
 464                      }, 250);
 465                      M.mod_quiz.resource_toolbox.reorganise_edit_page();
 466                  },
 467                  failure: function(tid, response) {
 468                      this.ajax_failure(response);
 469                      this.unlock_drag_handle(drag, CSS.SECTIONHANDLE);
 470                      spinner.hide();
 471                      window.location.reload(true);
 472                  }
 473              },
 474              context: this
 475          });
 476      },
 477  
 478      global_drop_over: function(e) {
 479          // Overriding parent method so we can stop the slots being dragged before the first page node.
 480  
 481          // Check that drop object belong to correct group.
 482          if (!e.drop || !e.drop.inGroup(this.groups)) {
 483              return;
 484          }
 485  
 486          // Get a reference to our drag and drop nodes.
 487          var drag = e.drag.get('node'),
 488              drop = e.drop.get('node');
 489  
 490          // Save last drop target for the case of missed target processing.
 491          this.lastdroptarget = e.drop;
 492  
 493          // Are we dropping within the same parent node?
 494          if (drop.hasClass(this.samenodeclass)) {
 495              var where;
 496  
 497              if (this.goingup) {
 498                  where = "before";
 499              } else {
 500                  where = "after";
 501              }
 502  
 503              drop.insert(drag, where);
 504          } else if ((drop.hasClass(this.parentnodeclass) || drop.test('[data-droptarget="1"]')) && !drop.contains(drag)) {
 505              // We are dropping on parent node and it is empty
 506              if (this.goingup) {
 507                  drop.append(drag);
 508              } else {
 509                  drop.prepend(drag);
 510              }
 511          }
 512          this.drop_over(e);
 513      }
 514  }, {
 515      NAME: 'mod_quiz-dragdrop-resource',
 516      ATTRS: {
 517          courseid: {
 518              value: null
 519          },
 520          quizid: {
 521              value: null
 522          },
 523          ajaxurl: {
 524              value: 0
 525          },
 526          config: {
 527              value: 0
 528          }
 529      }
 530  });
 531  
 532  M.mod_quiz = M.mod_quiz || {};
 533  M.mod_quiz.init_resource_dragdrop = function(params) {
 534      new DRAGRESOURCE(params);
 535  };
 536  
 537  
 538  }, '@VERSION@', {
 539      "requires": [
 540          "base",
 541          "node",
 542          "io",
 543          "dom",
 544          "dd",
 545          "dd-scroll",
 546          "moodle-core-dragdrop",
 547          "moodle-core-notification",
 548          "moodle-mod_quiz-quizbase",
 549          "moodle-mod_quiz-util-base",
 550          "moodle-mod_quiz-util-page",
 551          "moodle-mod_quiz-util-slot",
 552          "moodle-course-util"
 553      ]
 554  });


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1