[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

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

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


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