[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/yui/src/blocks/js/ -> manager.js (source)

   1  /**
   2   * This file contains the drag and drop manager class.
   3   *
   4   * Provides drag and drop functionality for blocks.
   5   *
   6   * @module moodle-core-blockdraganddrop
   7   */
   8  
   9  /**
  10   * Constructs a new Block drag and drop manager.
  11   *
  12   * @namespace M.core.blockdraganddrop
  13   * @class Manager
  14   * @constructor
  15   * @extends M.core.dragdrop
  16   */
  17  var MANAGER = function() {
  18      MANAGER.superclass.constructor.apply(this, arguments);
  19  };
  20  MANAGER.prototype = {
  21  
  22      /**
  23       * The skip block link from above the block being dragged while a drag is in progress.
  24       * Required by the M.core.dragdrop from whom this class extends.
  25       * @private
  26       * @property skipnodetop
  27       * @type Node
  28       * @default null
  29       */
  30      skipnodetop : null,
  31  
  32      /**
  33       * The skip block link from below the block being dragged while a drag is in progress.
  34       * Required by the M.core.dragdrop from whom this class extends.
  35       * @private
  36       * @property skipnodebottom
  37       * @type Node
  38       * @default null
  39       */
  40      skipnodebottom : null,
  41  
  42      /**
  43       * An associative object of regions and the
  44       * @property regionobjects
  45       * @type {Object} Primitive object mocking an associative array.
  46       * @type {BLOCKREGION} [regionname]* Each item uses the region name as the key with the value being
  47       *      an instance of the BLOCKREGION class.
  48       */
  49      regionobjects : {},
  50  
  51      /**
  52       * Called during the initialisation process of the object.
  53       * @method initializer
  54       */
  55      initializer : function() {
  56          Y.log('Initialising drag and drop for blocks.', 'info');
  57          var regionnames = this.get('regions'),
  58              i = 0,
  59              region,
  60              regionname,
  61              dragdelegation;
  62  
  63          // Evil required by M.core.dragdrop.
  64          this.groups = ['block'];
  65          this.samenodeclass = CSS.BLOCK;
  66          this.parentnodeclass = CSS.BLOCKREGION;
  67  
  68          // Add relevant classes and ID to 'content' block region on My Home page.
  69          var myhomecontent = Y.Node.all('body#'+CSS.MYINDEX+' #'+CSS.REGIONMAIN+' > .'+CSS.REGIONCONTENT);
  70          if (myhomecontent.size() > 0) {
  71              var contentregion = myhomecontent.item(0);
  72              contentregion.addClass(CSS.BLOCKREGION);
  73              contentregion.set('id', CSS.REGIONCONTENT);
  74              contentregion.one('div').addClass(CSS.REGIONCONTENT);
  75          }
  76  
  77          for (i in regionnames) {
  78              regionname = regionnames[i];
  79              region = new BLOCKREGION({
  80                  manager : this,
  81                  region : regionname,
  82                  node : Y.one('#block-region-'+regionname)
  83              });
  84              this.regionobjects[regionname] = region;
  85  
  86              // Setting blockregion as droptarget (the case when it is empty)
  87              // The region-post (the right one)
  88              // is very narrow, so add extra padding on the left to drop block on it.
  89              new Y.DD.Drop({
  90                  node: region.get_droptarget(),
  91                  groups: this.groups,
  92                  padding: '40 240 40 240'
  93              });
  94  
  95              // Make each div element in the list of blocks draggable
  96              dragdelegation = new Y.DD.Delegate({
  97                  container: region.get_droptarget(),
  98                  nodes: '.'+CSS.BLOCK,
  99                  target: true,
 100                  handles: [SELECTOR.DRAGHANDLE],
 101                  invalid: '.block-hider-hide, .block-hider-show, .moveto, .block_fake',
 102                  dragConfig: {groups: this.groups}
 103              });
 104              dragdelegation.dd.plug(Y.Plugin.DDProxy, {
 105                  // Don't move the node at the end of the drag
 106                  moveOnEnd: false
 107              });
 108              dragdelegation.dd.plug(Y.Plugin.DDWinScroll);
 109  
 110              // On the DD Manager start operation, we enable all block regions so that they can be drop targets. This
 111              // must be done *before* drag:start but after dragging has been initialised.
 112              Y.DD.DDM.on('ddm:start', this.enable_all_regions, this);
 113  
 114              region.change_block_move_icons(this);
 115          }
 116          Y.log('Initialisation of drag and drop for blocks complete.', 'info');
 117      },
 118  
 119      /**
 120       * Returns the ID of the block the given node represents.
 121       * @method get_block_id
 122       * @param {Node} node
 123       * @return {int} The blocks ID in the database.
 124       */
 125      get_block_id : function(node) {
 126          return Number(node.get('id').replace(/inst/i, ''));
 127      },
 128  
 129      /**
 130       * Returns the block region that the node is part of or belonging to.
 131       * @method get_block_region
 132       * @param {Y.Node} node
 133       * @return {string} The region name.
 134       */
 135      get_block_region : function(node) {
 136          if (!node.test('[data-blockregion]')) {
 137              node = node.ancestor('[data-blockregion]');
 138          }
 139          return node.getData('blockregion');
 140      },
 141  
 142      /**
 143       * Returns the BLOCKREGION instance that represents the block region the given node is part of.
 144       * @method get_region_object
 145       * @param {Y.Node} node
 146       * @return {BLOCKREGION}
 147       */
 148      get_region_object : function(node) {
 149          return this.regionobjects[this.get_block_region(node)];
 150      },
 151  
 152      /**
 153       * Enables all fo the regions so that they are all visible while dragging is occuring.
 154       *
 155       * @method enable_all_regions
 156       */
 157      enable_all_regions : function() {
 158          var groups = Y.DD.DDM.activeDrag.get('groups');
 159  
 160          // As we're called by Y.DD.DDM, we can't be certain that the call
 161          // relates specifically to a block drag/drop operation. Test
 162          // whether the relevant group applies here.
 163          if (!groups || Y.Array.indexOf(groups, 'block') === -1) {
 164              return;
 165          }
 166  
 167          var i;
 168          for (i in this.regionobjects) {
 169              if (!this.regionobjects.hasOwnProperty(i)) {
 170                  continue;
 171              }
 172              this.regionobjects[i].enable();
 173          }
 174      },
 175  
 176      /**
 177       * Disables enabled regions if they contain no blocks.
 178       * @method disable_regions_if_required
 179       */
 180      disable_regions_if_required : function() {
 181          var i = 0;
 182          for (i in this.regionobjects) {
 183              this.regionobjects[i].disable_if_required();
 184          }
 185      },
 186  
 187      /**
 188       * Called by M.core.dragdrop.global_drag_start when dragging starts.
 189       * @method drag_start
 190       * @param {Event} e
 191       */
 192      drag_start : function(e) {
 193          // Get our drag object
 194          var drag = e.target;
 195  
 196          // Store the parent node of original drag node (block)
 197          // we will need it later for show/hide empty regions
 198  
 199          // Determine skipnodes and store them
 200          if (drag.get('node').previous() && drag.get('node').previous().hasClass(CSS.SKIPBLOCK)) {
 201              this.skipnodetop = drag.get('node').previous();
 202          }
 203          if (drag.get('node').next() && drag.get('node').next().hasClass(CSS.SKIPBLOCKTO)) {
 204              this.skipnodebottom = drag.get('node').next();
 205          }
 206      },
 207  
 208      /**
 209       * Called by M.core.dragdrop.global_drop_over when something is dragged over a drop target.
 210       * @method drop_over
 211       * @param {Event} e
 212       */
 213      drop_over : function(e) {
 214          // Get a reference to our drag and drop nodes
 215          var drag = e.drag.get('node');
 216          var drop = e.drop.get('node');
 217  
 218          // We need to fix the case when parent drop over event has determined
 219          // 'goingup' and appended the drag node after admin-block.
 220          if (drop.hasClass(CSS.REGIONCONTENT) && drop.one('.'+CSS.BLOCKADMINBLOCK) && drop.one('.'+CSS.BLOCKADMINBLOCK).next('.'+CSS.BLOCK)) {
 221              drop.prepend(drag);
 222          }
 223      },
 224  
 225      /**
 226       * Called by M.core.dragdrop.global_drop_end when a drop has been completed.
 227       * @method drop_end
 228       */
 229      drop_end : function() {
 230          // Clear variables.
 231          this.skipnodetop = null;
 232          this.skipnodebottom = null;
 233          this.disable_regions_if_required();
 234      },
 235  
 236      /**
 237       * Called by M.core.dragdrop.global_drag_dropmiss when something has been dropped on a node that isn't contained by a drop target.
 238       * @method drag_dropmiss
 239       * @param {Event} e
 240       */
 241      drag_dropmiss : function(e) {
 242          // Missed the target, but we assume the user intended to drop it
 243          // on the last ghost node location, e.drag and e.drop should be
 244          // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
 245          this.drop_hit(e);
 246      },
 247  
 248      /**
 249       * Called by M.core.dragdrop.global_drag_hit when something has been dropped on a drop target.
 250       * @method drop_hit
 251       * @param {Event} e
 252       */
 253      drop_hit : function(e) {
 254          // Get a reference to our drag node
 255          var dragnode = e.drag.get('node');
 256          var dropnode = e.drop.get('node');
 257  
 258          // Amend existing skipnodes
 259          if (dragnode.previous() && dragnode.previous().hasClass(CSS.SKIPBLOCK)) {
 260              // the one that belongs to block below move below
 261              dragnode.insert(dragnode.previous(), 'after');
 262          }
 263          // Move original skipnodes
 264          if (this.skipnodetop) {
 265              dragnode.insert(this.skipnodetop, 'before');
 266          }
 267          if (this.skipnodebottom) {
 268              dragnode.insert(this.skipnodebottom, 'after');
 269          }
 270  
 271          // Add lightbox if it not there
 272          var lightbox = M.util.add_lightbox(Y, dragnode);
 273  
 274          // Prepare request parameters
 275          var params = {
 276              sesskey : M.cfg.sesskey,
 277              courseid : this.get('courseid'),
 278              pagelayout : this.get('pagelayout'),
 279              pagetype : this.get('pagetype'),
 280              subpage : this.get('subpage'),
 281              contextid : this.get('contextid'),
 282              action : 'move',
 283              bui_moveid : this.get_block_id(dragnode),
 284              bui_newregion : this.get_block_region(dropnode)
 285          };
 286  
 287          if (this.get('cmid')) {
 288              params.cmid = this.get('cmid');
 289          }
 290  
 291          if (dragnode.next('.'+CSS.BLOCK) && !dragnode.next('.'+CSS.BLOCK).hasClass(CSS.BLOCKADMINBLOCK)) {
 292              params.bui_beforeid = this.get_block_id(dragnode.next('.'+CSS.BLOCK));
 293          }
 294  
 295          // Do AJAX request
 296          Y.io(M.cfg.wwwroot+AJAXURL, {
 297              method: 'POST',
 298              data: params,
 299              on: {
 300                  start : function() {
 301                      lightbox.show();
 302                  },
 303                  success: function(tid, response) {
 304                      window.setTimeout(function() {
 305                          lightbox.hide();
 306                      }, 250);
 307                      try {
 308                          var responsetext = Y.JSON.parse(response.responseText);
 309                          if (responsetext.error) {
 310                              new M.core.ajaxException(responsetext);
 311                          }
 312                      } catch (e) {}
 313                  },
 314                  failure: function(tid, response) {
 315                      this.ajax_failure(response);
 316                      lightbox.hide();
 317                  },
 318                  complete : function() {
 319                      this.disable_regions_if_required();
 320                  }
 321              },
 322              context:this
 323          });
 324      }
 325  };
 326  Y.extend(MANAGER, M.core.dragdrop, MANAGER.prototype, {
 327      NAME : 'core-blocks-dragdrop-manager',
 328      ATTRS : {
 329          /**
 330           * The Course ID if there is one.
 331           * @attribute courseid
 332           * @type int|null
 333           * @default null
 334           */
 335          courseid : {
 336              value : null
 337          },
 338  
 339          /**
 340           * The Course Module ID if there is one.
 341           * @attribute cmid
 342           * @type int|null
 343           * @default null
 344           */
 345          cmid : {
 346              value : null
 347          },
 348  
 349          /**
 350           * The Context ID.
 351           * @attribute contextid
 352           * @type int|null
 353           * @default null
 354           */
 355          contextid : {
 356              value : null
 357          },
 358  
 359          /**
 360           * The current page layout.
 361           * @attribute pagelayout
 362           * @type string|null
 363           * @default null
 364           */
 365          pagelayout : {
 366              value : null
 367          },
 368  
 369          /**
 370           * The page type string, should be used as the id for the body tag in the theme.
 371           * @attribute pagetype
 372           * @type string|null
 373           * @default null
 374           */
 375          pagetype : {
 376              value : null
 377          },
 378  
 379          /**
 380           * The subpage identifier, if any.
 381           * @attribute subpage
 382           * @type string|null
 383           * @default null
 384           */
 385          subpage : {
 386              value : null
 387          },
 388  
 389          /**
 390           * An array of block regions that are present on the page.
 391           * @attribute regions
 392           * @type array|null
 393           * @default Array[]
 394           */
 395          regions : {
 396              value : []
 397          }
 398      }
 399  });


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1