[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

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

   1  YUI.add('moodle-mod_quiz-toolboxes', function (Y, NAME) {
   2  
   3  /**
   4   * Resource and activity toolbox class.
   5   *
   6   * This class is responsible for managing AJAX interactions with activities and resources
   7   * when viewing a course in editing mode.
   8   *
   9   * @module moodle-course-toolboxes
  10   * @namespace M.course.toolboxes
  11   */
  12  
  13  // The CSS classes we use.
  14      var CSS = {
  15          ACTIVITYINSTANCE : 'activityinstance',
  16          AVAILABILITYINFODIV : 'div.availabilityinfo',
  17          CONTENTWITHOUTLINK : 'contentwithoutlink',
  18          CONDITIONALHIDDEN : 'conditionalhidden',
  19          DIMCLASS : 'dimmed',
  20          DIMMEDTEXT : 'dimmed_text',
  21          EDITINSTRUCTIONS : 'editinstructions',
  22          EDITINGMAXMARK: 'editor_displayed',
  23          HIDE : 'hide',
  24          JOIN: 'page_join',
  25          MODINDENTCOUNT : 'mod-indent-',
  26          MODINDENTHUGE : 'mod-indent-huge',
  27          MODULEIDPREFIX : 'slot-',
  28          PAGE: 'page',
  29          SECTIONHIDDENCLASS : 'hidden',
  30          SECTIONIDPREFIX : 'section-',
  31          SLOT : 'slot',
  32          SHOW : 'editing_show',
  33          TITLEEDITOR : 'titleeditor'
  34      },
  35      // The CSS selectors we use.
  36      SELECTOR = {
  37          ACTIONAREA: '.actions',
  38          ACTIONLINKTEXT : '.actionlinktext',
  39          ACTIVITYACTION : 'a.cm-edit-action[data-action], a.editing_maxmark',
  40          ACTIVITYFORM : 'span.instancemaxmarkcontainer form',
  41          ACTIVITYICON : 'img.activityicon',
  42          ACTIVITYINSTANCE : '.' + CSS.ACTIVITYINSTANCE,
  43          ACTIVITYLINK: '.' + CSS.ACTIVITYINSTANCE + ' > a',
  44          ACTIVITYLI : 'li.activity',
  45          ACTIVITYMAXMARK : 'input[name=maxmark]',
  46          COMMANDSPAN : '.commands',
  47          CONTENTAFTERLINK : 'div.contentafterlink',
  48          CONTENTWITHOUTLINK : 'div.contentwithoutlink',
  49          EDITMAXMARK: 'a.editing_maxmark',
  50          HIDE : 'a.editing_hide',
  51          HIGHLIGHT : 'a.editing_highlight',
  52          INSTANCENAME : 'span.instancename',
  53          INSTANCEMAXMARK : 'span.instancemaxmark',
  54          MODINDENTDIV : '.mod-indent',
  55          MODINDENTOUTER : '.mod-indent-outer',
  56          NUMQUESTIONS : '.numberofquestions',
  57          PAGECONTENT : 'div#page-content',
  58          PAGELI : 'li.page',
  59          SECTIONUL : 'ul.section',
  60          SHOW : 'a.' + CSS.SHOW,
  61          SHOWHIDE : 'a.editing_showhide',
  62          SLOTLI : 'li.slot',
  63          SUMMARKS : '.mod_quiz_summarks'
  64      },
  65      BODY = Y.one(document.body);
  66  
  67  // Setup the basic namespace.
  68  M.mod_quiz = M.mod_quiz || {};
  69  
  70  /**
  71   * The toolbox class is a generic class which should never be directly
  72   * instantiated. Please extend it instead.
  73   *
  74   * @class toolbox
  75   * @constructor
  76   * @protected
  77   * @extends Base
  78   */
  79  var TOOLBOX = function() {
  80      TOOLBOX.superclass.constructor.apply(this, arguments);
  81  };
  82  
  83  Y.extend(TOOLBOX, Y.Base, {
  84      /**
  85       * Send a request using the REST API
  86       *
  87       * @method send_request
  88       * @param {Object} data The data to submit with the AJAX request
  89       * @param {Node} [statusspinner] A statusspinner which may contain a section loader
  90       * @param {Function} success_callback The callback to use on success
  91       * @param {Object} [optionalconfig] Any additional configuration to submit
  92       * @chainable
  93       */
  94      send_request: function(data, statusspinner, success_callback, optionalconfig) {
  95          // Default data structure
  96          if (!data) {
  97              data = {};
  98          }
  99          // Handle any variables which we must pass back through to
 100          var pageparams = this.get('config').pageparams,
 101              varname;
 102          for (varname in pageparams) {
 103              data[varname] = pageparams[varname];
 104          }
 105  
 106          data.sesskey = M.cfg.sesskey;
 107          data.courseid = this.get('courseid');
 108          data.quizid = this.get('quizid');
 109  
 110          var uri = M.cfg.wwwroot + this.get('ajaxurl');
 111  
 112          // Define the configuration to send with the request
 113          var responsetext = [];
 114          var config = {
 115              method: 'POST',
 116              data: data,
 117              on: {
 118                  success: function(tid, response) {
 119                      try {
 120                          responsetext = Y.JSON.parse(response.responseText);
 121                          if (responsetext.error) {
 122                              new M.core.ajaxException(responsetext);
 123                          }
 124                      } catch (e) {}
 125  
 126                      // Run the callback if we have one.
 127                      if (responsetext.hasOwnProperty('newsummarks')) {
 128                          Y.one(SELECTOR.SUMMARKS).setHTML(responsetext.newsummarks);
 129                      }
 130                      if (responsetext.hasOwnProperty('newnumquestions')) {
 131                          Y.one(SELECTOR.NUMQUESTIONS).setHTML(M.util.get_string('numquestionsx', 'quiz', responsetext.newnumquestions));
 132                      }
 133                      if (success_callback) {
 134                          Y.bind(success_callback, this, responsetext)();
 135                      }
 136  
 137                      if (statusspinner) {
 138                          window.setTimeout(function() {
 139                              statusspinner.hide();
 140                          }, 400);
 141                      }
 142                  },
 143                  failure: function(tid, response) {
 144                      if (statusspinner) {
 145                          statusspinner.hide();
 146                      }
 147                      new M.core.ajaxException(response);
 148                  }
 149              },
 150              context: this
 151          };
 152  
 153          // Apply optional config
 154          if (optionalconfig) {
 155              for (varname in optionalconfig) {
 156                  config[varname] = optionalconfig[varname];
 157              }
 158          }
 159  
 160          if (statusspinner) {
 161              statusspinner.show();
 162          }
 163  
 164          // Send the request
 165          Y.io(uri, config);
 166          return this;
 167      }
 168  },
 169  {
 170      NAME: 'mod_quiz-toolbox',
 171      ATTRS: {
 172          /**
 173           * The ID of the Moodle Course being edited.
 174           *
 175           * @attribute courseid
 176           * @default 0
 177           * @type Number
 178           */
 179          courseid: {
 180              'value': 0
 181          },
 182  
 183          /**
 184           * The Moodle course format.
 185           *
 186           * @attribute format
 187           * @default 'topics'
 188           * @type String
 189           */
 190          quizid: {
 191              'value': 0
 192          },
 193          /**
 194           * The URL to use when submitting requests.
 195           * @attribute ajaxurl
 196           * @default null
 197           * @type String
 198           */
 199          ajaxurl: {
 200              'value': null
 201          },
 202          /**
 203           * Any additional configuration passed when creating the instance.
 204           *
 205           * @attribute config
 206           * @default {}
 207           * @type Object
 208           */
 209          config: {
 210              'value': {}
 211          }
 212      }
 213  }
 214  );
 215  /**
 216   * Resource and activity toolbox class.
 217   *
 218   * This class is responsible for managing AJAX interactions with activities and resources
 219   * when viewing a quiz in editing mode.
 220   *
 221   * @module mod_quiz-resource-toolbox
 222   * @namespace M.mod_quiz.resource_toolbox
 223   */
 224  
 225  /**
 226   * Resource and activity toolbox class.
 227   *
 228   * This is a class extending TOOLBOX containing code specific to resources
 229   *
 230   * This class is responsible for managing AJAX interactions with activities and resources
 231   * when viewing a quiz in editing mode.
 232   *
 233   * @class resources
 234   * @constructor
 235   * @extends M.course.toolboxes.toolbox
 236   */
 237  var RESOURCETOOLBOX = function() {
 238      RESOURCETOOLBOX.superclass.constructor.apply(this, arguments);
 239  };
 240  
 241  Y.extend(RESOURCETOOLBOX, TOOLBOX, {
 242      /**
 243       * An Array of events added when editing a max mark field.
 244       * These should all be detached when editing is complete.
 245       *
 246       * @property editmaxmarkevents
 247       * @protected
 248       * @type Array
 249       * @protected
 250       */
 251      editmaxmarkevents: [],
 252  
 253      /**
 254       *
 255       */
 256      NODE_PAGE: 1,
 257      NODE_SLOT: 2,
 258      NODE_JOIN: 3,
 259  
 260      /**
 261       * Initialize the resource toolbox
 262       *
 263       * For each activity the commands are updated and a reference to the activity is attached.
 264       * This way it doesn't matter where the commands are going to called from they have a reference to the
 265       * activity that they relate to.
 266       * This is essential as some of the actions are displayed in an actionmenu which removes them from the
 267       * page flow.
 268       *
 269       * This function also creates a single event delegate to manage all AJAX actions for all activities on
 270       * the page.
 271       *
 272       * @method initializer
 273       * @protected
 274       */
 275      initializer: function() {
 276          M.mod_quiz.quizbase.register_module(this);
 277          BODY.delegate('key', this.handle_data_action, 'down:enter', SELECTOR.ACTIVITYACTION, this);
 278          Y.delegate('click', this.handle_data_action, BODY, SELECTOR.ACTIVITYACTION, this);
 279      },
 280  
 281      /**
 282       * Handles the delegation event. When this is fired someone has triggered an action.
 283       *
 284       * Note not all actions will result in an AJAX enhancement.
 285       *
 286       * @protected
 287       * @method handle_data_action
 288       * @param {EventFacade} ev The event that was triggered.
 289       * @returns {boolean}
 290       */
 291      handle_data_action: function(ev) {
 292          // We need to get the anchor element that triggered this event.
 293          var node = ev.target;
 294          if (!node.test('a')) {
 295              node = node.ancestor(SELECTOR.ACTIVITYACTION);
 296          }
 297  
 298          // From the anchor we can get both the activity (added during initialisation) and the action being
 299          // performed (added by the UI as a data attribute).
 300          var action = node.getData('action'),
 301              activity = node.ancestor(SELECTOR.ACTIVITYLI);
 302  
 303          if (!node.test('a') || !action || !activity) {
 304              // It wasn't a valid action node.
 305              return;
 306          }
 307  
 308          // Switch based upon the action and do the desired thing.
 309          switch (action) {
 310              case 'editmaxmark':
 311                  // The user wishes to edit the maxmark of the resource.
 312                  this.edit_maxmark(ev, node, activity, action);
 313                  break;
 314              case 'delete':
 315                  // The user is deleting the activity.
 316                  this.delete_with_confirmation(ev, node, activity, action);
 317                  break;
 318              case 'addpagebreak':
 319              case 'removepagebreak':
 320                  // The user is adding or removing a page break.
 321                  this.update_page_break(ev, node, activity, action);
 322                  break;
 323              default:
 324                  // Nothing to do here!
 325                  break;
 326          }
 327      },
 328  
 329      /**
 330       * Add a loading icon to the specified activity.
 331       *
 332       * The icon is added within the action area.
 333       *
 334       * @method add_spinner
 335       * @param {Node} activity The activity to add a loading icon to
 336       * @return {Node|null} The newly created icon, or null if the action area was not found.
 337       */
 338      add_spinner: function(activity) {
 339          var actionarea = activity.one(SELECTOR.ACTIONAREA);
 340          if (actionarea) {
 341              return M.util.add_spinner(Y, actionarea);
 342          }
 343          return null;
 344      },
 345  
 346      /**
 347       * Deletes the given activity or resource after confirmation.
 348       *
 349       * @protected
 350       * @method delete_with_confirmation
 351       * @param {EventFacade} ev The event that was fired.
 352       * @param {Node} button The button that triggered this action.
 353       * @param {Node} activity The activity node that this action will be performed on.
 354       * @chainable
 355       */
 356      delete_with_confirmation: function(ev, button, activity) {
 357          // Prevent the default button action.
 358          ev.preventDefault();
 359  
 360          // Get the element we're working on.
 361          var element   = activity,
 362              // Create confirm string (different if element has or does not have name)
 363              confirmstring = '',
 364              qtypename = M.util.get_string('pluginname',
 365                          'qtype_' + element.getAttribute('class').match(/qtype_([^\s]*)/)[1]);
 366          confirmstring = M.util.get_string('confirmremovequestion', 'quiz', qtypename);
 367  
 368          // Create the confirmation dialogue.
 369          var confirm = new M.core.confirm({
 370              question: confirmstring,
 371              modal: true
 372          });
 373  
 374          // If it is confirmed.
 375          confirm.on('complete-yes', function() {
 376  
 377              var spinner = this.add_spinner(element);
 378              var data = {
 379                  'class': 'resource',
 380                  'action': 'DELETE',
 381                  'id': Y.Moodle.mod_quiz.util.slot.getId(element)
 382              };
 383              this.send_request(data, spinner, function(response) {
 384                  if (response.deleted) {
 385                      // Actually remove the element.
 386                      Y.Moodle.mod_quiz.util.slot.remove(element);
 387                      this.reorganise_edit_page();
 388                      if (M.core.actionmenu && M.core.actionmenu.instance) {
 389                          M.core.actionmenu.instance.hideMenu();
 390                      }
 391                  } else {
 392                      window.location.reload(true);
 393                  }
 394              });
 395  
 396          }, this);
 397  
 398          return this;
 399      },
 400  
 401  
 402      /**
 403       * Edit the maxmark for the resource
 404       *
 405       * @protected
 406       * @method edit_maxmark
 407       * @param {EventFacade} ev The event that was fired.
 408       * @param {Node} button The button that triggered this action.
 409       * @param {Node} activity The activity node that this action will be performed on.
 410       * @param {String} action The action that has been requested.
 411       * @return Boolean
 412       */
 413      edit_maxmark : function(ev, button, activity) {
 414          // Get the element we're working on
 415          var activityid = Y.Moodle.mod_quiz.util.slot.getId(activity),
 416              instancemaxmark  = activity.one(SELECTOR.INSTANCEMAXMARK),
 417              instance = activity.one(SELECTOR.ACTIVITYINSTANCE),
 418              currentmaxmark = instancemaxmark.get('firstChild'),
 419              oldmaxmark = currentmaxmark.get('data'),
 420              maxmarktext = oldmaxmark,
 421              thisevent,
 422              anchor = instancemaxmark,// Grab the anchor so that we can swap it with the edit form.
 423              data = {
 424                  'class'   : 'resource',
 425                  'field'   : 'getmaxmark',
 426                  'id'      : activityid
 427              };
 428  
 429          // Prevent the default actions.
 430          ev.preventDefault();
 431  
 432          this.send_request(data, null, function(response) {
 433              if (M.core.actionmenu && M.core.actionmenu.instance) {
 434                  M.core.actionmenu.instance.hideMenu();
 435              }
 436  
 437              // Try to retrieve the existing string from the server.
 438              if (response.instancemaxmark) {
 439                  maxmarktext = response.instancemaxmark;
 440              }
 441  
 442              // Create the editor and submit button.
 443              var editform = Y.Node.create('<form action="#" />');
 444              var editinstructions = Y.Node.create('<span class="' + CSS.EDITINSTRUCTIONS + '" id="id_editinstructions" />')
 445                  .set('innerHTML', M.util.get_string('edittitleinstructions', 'moodle'));
 446              var editor = Y.Node.create('<input name="maxmark" type="text" class="' + CSS.TITLEEDITOR + '" />').setAttrs({
 447                  'value' : maxmarktext,
 448                  'autocomplete' : 'off',
 449                  'aria-describedby' : 'id_editinstructions',
 450                  'maxLength' : '12',
 451                  'size' : parseInt(this.get('config').questiondecimalpoints, 10) + 2
 452              });
 453  
 454              // Clear the existing content and put the editor in.
 455              editform.appendChild(editor);
 456              editform.setData('anchor', anchor);
 457              instance.insert(editinstructions, 'before');
 458              anchor.replace(editform);
 459  
 460              // Force the editing instruction to match the mod-indent position.
 461              var padside = 'left';
 462              if (right_to_left()) {
 463                  padside = 'right';
 464              }
 465  
 466              // We hide various components whilst editing:
 467              activity.addClass(CSS.EDITINGMAXMARK);
 468  
 469              // Focus and select the editor text.
 470              editor.focus().select();
 471  
 472              // Cancel the edit if we lose focus or the escape key is pressed.
 473              thisevent = editor.on('blur', this.edit_maxmark_cancel, this, activity, false);
 474              this.editmaxmarkevents.push(thisevent);
 475              thisevent = editor.on('key', this.edit_maxmark_cancel, 'esc', this, activity, true);
 476              this.editmaxmarkevents.push(thisevent);
 477  
 478              // Handle form submission.
 479              thisevent = editform.on('submit', this.edit_maxmark_submit, this, activity, oldmaxmark);
 480              this.editmaxmarkevents.push(thisevent);
 481          });
 482      },
 483  
 484      /**
 485       * Handles the submit event when editing the activity or resources maxmark.
 486       *
 487       * @protected
 488       * @method edit_maxmark_submit
 489       * @param {EventFacade} ev The event that triggered this.
 490       * @param {Node} activity The activity whose maxmark we are altering.
 491       * @param {String} originalmaxmark The original maxmark the activity or resource had.
 492       */
 493      edit_maxmark_submit : function(ev, activity, originalmaxmark) {
 494          // We don't actually want to submit anything.
 495          ev.preventDefault();
 496          var newmaxmark = Y.Lang.trim(activity.one(SELECTOR.ACTIVITYFORM + ' ' + SELECTOR.ACTIVITYMAXMARK).get('value'));
 497          var spinner = this.add_spinner(activity);
 498          this.edit_maxmark_clear(activity);
 499          activity.one(SELECTOR.INSTANCEMAXMARK).setContent(newmaxmark);
 500          if (newmaxmark !== null && newmaxmark !== "" && newmaxmark !== originalmaxmark) {
 501              var data = {
 502                  'class'   : 'resource',
 503                  'field'   : 'updatemaxmark',
 504                  'maxmark'   : newmaxmark,
 505                  'id'      : Y.Moodle.mod_quiz.util.slot.getId(activity)
 506              };
 507              this.send_request(data, spinner, function(response) {
 508                  if (response.instancemaxmark) {
 509                      activity.one(SELECTOR.INSTANCEMAXMARK).setContent(response.instancemaxmark);
 510                  }
 511              });
 512          }
 513      },
 514  
 515      /**
 516       * Handles the cancel event when editing the activity or resources maxmark.
 517       *
 518       * @protected
 519       * @method edit_maxmark_cancel
 520       * @param {EventFacade} ev The event that triggered this.
 521       * @param {Node} activity The activity whose maxmark we are altering.
 522       * @param {Boolean} preventdefault If true we should prevent the default action from occuring.
 523       */
 524      edit_maxmark_cancel : function(ev, activity, preventdefault) {
 525          if (preventdefault) {
 526              ev.preventDefault();
 527          }
 528          this.edit_maxmark_clear(activity);
 529      },
 530  
 531      /**
 532       * Handles clearing the editing UI and returning things to the original state they were in.
 533       *
 534       * @protected
 535       * @method edit_maxmark_clear
 536       * @param {Node} activity  The activity whose maxmark we were altering.
 537       */
 538      edit_maxmark_clear : function(activity) {
 539          // Detach all listen events to prevent duplicate triggers
 540          new Y.EventHandle(this.editmaxmarkevents).detach();
 541  
 542          var editform = activity.one(SELECTOR.ACTIVITYFORM),
 543              instructions = activity.one('#id_editinstructions');
 544          if (editform) {
 545              editform.replace(editform.getData('anchor'));
 546          }
 547          if (instructions) {
 548              instructions.remove();
 549          }
 550  
 551          // Remove the editing class again to revert the display.
 552          activity.removeClass(CSS.EDITINGMAXMARK);
 553  
 554          // Refocus the link which was clicked originally so the user can continue using keyboard nav.
 555          Y.later(100, this, function() {
 556              activity.one(SELECTOR.EDITMAXMARK).focus();
 557          });
 558  
 559          // This hack is to keep Behat happy until they release a version of
 560          // MinkSelenium2Driver that fixes
 561          // https://github.com/Behat/MinkSelenium2Driver/issues/80.
 562          if (!Y.one('input[name=maxmark')) {
 563              Y.one('body').append('<input type="text" name="maxmark" style="display: none">');
 564          }
 565      },
 566  
 567      /**
 568       * Joins or separates the given slot with the page of the previous slot. Reorders the pages of
 569       * the other slots
 570       *
 571       * @protected
 572       * @method update_page_break
 573       * @param {EventFacade} ev The event that was fired.
 574       * @param {Node} button The button that triggered this action.
 575       * @param {Node} activity The activity node that this action will be performed on.
 576       * @chainable
 577       */
 578      update_page_break: function(ev, button, activity, action) {
 579          // Prevent the default button action
 580          ev.preventDefault();
 581  
 582          nextactivity = activity.next('li.activity.slot');
 583          var spinner = this.add_spinner(nextactivity),
 584              slotid = 0;
 585          var value = action === 'removepagebreak' ? 1 : 2;
 586  
 587          var data = {
 588              'class': 'resource',
 589              'field': 'updatepagebreak',
 590              'id':    slotid,
 591              'value': value
 592          };
 593  
 594          slotid = Y.Moodle.mod_quiz.util.slot.getId(nextactivity);
 595          if (slotid) {
 596              data.id = Number(slotid);
 597          }
 598          this.send_request(data, spinner, function(response) {
 599              if (response.slots) {
 600                  if (action === 'addpagebreak') {
 601                      Y.Moodle.mod_quiz.util.page.add(activity);
 602                  } else {
 603                      var page = activity.next(Y.Moodle.mod_quiz.util.page.SELECTORS.PAGE);
 604                      Y.Moodle.mod_quiz.util.page.remove(page, true);
 605                  }
 606                  this.reorganise_edit_page();
 607              } else {
 608                  window.location.reload(true);
 609              }
 610          });
 611  
 612          return this;
 613      },
 614  
 615      /**
 616       * Reorganise the UI after every edit action.
 617       *
 618       * @protected
 619       * @method reorganise_edit_page
 620       */
 621      reorganise_edit_page: function() {
 622          Y.Moodle.mod_quiz.util.slot.reorderSlots();
 623          Y.Moodle.mod_quiz.util.slot.reorderPageBreaks();
 624          Y.Moodle.mod_quiz.util.page.reorderPages();
 625      },
 626  
 627      NAME : 'mod_quiz-resource-toolbox',
 628      ATTRS : {
 629          courseid : {
 630              'value' : 0
 631          },
 632          quizid : {
 633              'value' : 0
 634          }
 635      }
 636  });
 637  
 638  M.mod_quiz.resource_toolbox = null;
 639  M.mod_quiz.init_resource_toolbox = function(config) {
 640      M.mod_quiz.resource_toolbox = new RESOURCETOOLBOX(config);
 641      return M.mod_quiz.resource_toolbox;
 642  };
 643  /**
 644   * Resource and activity toolbox class.
 645   *
 646   * This class is responsible for managing AJAX interactions with activities and resources
 647   * when viewing a course in editing mode.
 648   *
 649   * @module moodle-mod_quiz-toolboxes
 650   * @namespace M.mod_quiz.toolboxes
 651   */
 652  
 653  /**
 654   * Section toolbox class.
 655   *
 656   * This class is responsible for managing AJAX interactions with sections
 657   * when viewing a course in editing mode.
 658   *
 659   * @class section
 660   * @constructor
 661   * @extends M.mod_quiz.toolboxes.toolbox
 662   */
 663  var SECTIONTOOLBOX = function() {
 664      SECTIONTOOLBOX.superclass.constructor.apply(this, arguments);
 665  };
 666  
 667  Y.extend(SECTIONTOOLBOX, TOOLBOX, {
 668      /**
 669       * Initialize the section toolboxes module.
 670       *
 671       * Updates all span.commands with relevant handlers and other required changes.
 672       *
 673       * @method initializer
 674       * @protected
 675       */
 676      initializer : function() {
 677          M.mod_quiz.quizbase.register_module(this);
 678  
 679          // Section Highlighting.
 680          Y.delegate('click', this.toggle_highlight, SELECTOR.PAGECONTENT, SELECTOR.SECTIONLI + ' ' + SELECTOR.HIGHLIGHT, this);
 681  
 682          // Section Visibility.
 683          Y.delegate('click', this.toggle_hide_section, SELECTOR.PAGECONTENT, SELECTOR.SECTIONLI + ' ' + SELECTOR.SHOWHIDE, this);
 684      },
 685  
 686      toggle_hide_section : function(e) {
 687          // Prevent the default button action.
 688          e.preventDefault();
 689  
 690          // Get the section we're working on.
 691          var section = e.target.ancestor(M.mod_quiz.format.get_section_selector(Y)),
 692              button = e.target.ancestor('a', true),
 693              hideicon = button.one('img'),
 694  
 695          // The value to submit
 696              value,
 697  
 698          // The text for strings and images. Also determines the icon to display.
 699              action,
 700              nextaction;
 701  
 702          if (!section.hasClass(CSS.SECTIONHIDDENCLASS)) {
 703              section.addClass(CSS.SECTIONHIDDENCLASS);
 704              value = 0;
 705              action = 'hide';
 706              nextaction = 'show';
 707          } else {
 708              section.removeClass(CSS.SECTIONHIDDENCLASS);
 709              value = 1;
 710              action = 'show';
 711              nextaction = 'hide';
 712          }
 713  
 714          var newstring = M.util.get_string(nextaction + 'fromothers', 'format_' + this.get('format'));
 715          hideicon.setAttrs({
 716              'alt' : newstring,
 717              'src'   : M.util.image_url('i/' + nextaction)
 718          });
 719          button.set('title', newstring);
 720  
 721          // Change the highlight status
 722          var data = {
 723              'class' : 'section',
 724              'field' : 'visible',
 725              'id'    : Y.Moodle.core_course.util.section.getId(section.ancestor(M.mod_quiz.edit.get_section_wrapper(Y), true)),
 726              'value' : value
 727          };
 728  
 729          var lightbox = M.util.add_lightbox(Y, section);
 730          lightbox.show();
 731  
 732          this.send_request(data, lightbox, function(response) {
 733              var activities = section.all(SELECTOR.ACTIVITYLI);
 734              activities.each(function(node) {
 735                  var button;
 736                  if (node.one(SELECTOR.SHOW)) {
 737                      button = node.one(SELECTOR.SHOW);
 738                  } else {
 739                      button = node.one(SELECTOR.HIDE);
 740                  }
 741                  var activityid = Y.Moodle.mod_quiz.util.slot.getId(node);
 742  
 743                  // NOTE: resourcestotoggle is returned as a string instead
 744                  // of a Number so we must cast our activityid to a String.
 745                  if (Y.Array.indexOf(response.resourcestotoggle, "" + activityid) !== -1) {
 746                      M.mod_quiz.resource_toolbox.handle_resource_dim(button, node, action);
 747                  }
 748              }, this);
 749          });
 750      },
 751  
 752      /**
 753       * Toggle highlighting the current section.
 754       *
 755       * @method toggle_highlight
 756       * @param {EventFacade} e
 757       */
 758      toggle_highlight : function(e) {
 759          // Prevent the default button action.
 760          e.preventDefault();
 761  
 762          // Get the section we're working on.
 763          var section = e.target.ancestor(M.mod_quiz.edit.get_section_selector(Y));
 764          var button = e.target.ancestor('a', true);
 765          var buttonicon = button.one('img');
 766  
 767          // Determine whether the marker is currently set.
 768          var togglestatus = section.hasClass('current');
 769          var value = 0;
 770  
 771          // Set the current highlighted item text.
 772          var old_string = M.util.get_string('markthistopic', 'moodle');
 773          Y.one(SELECTOR.PAGECONTENT)
 774              .all(M.mod_quiz.edit.get_section_selector(Y) + '.current ' + SELECTOR.HIGHLIGHT)
 775              .set('title', old_string);
 776          Y.one(SELECTOR.PAGECONTENT)
 777              .all(M.mod_quiz.edit.get_section_selector(Y) + '.current ' + SELECTOR.HIGHLIGHT + ' img')
 778              .set('alt', old_string)
 779              .set('src', M.util.image_url('i/marker'));
 780  
 781          // Remove the highlighting from all sections.
 782          Y.one(SELECTOR.PAGECONTENT).all(M.mod_quiz.edit.get_section_selector(Y))
 783              .removeClass('current');
 784  
 785          // Then add it if required to the selected section.
 786          if (!togglestatus) {
 787              section.addClass('current');
 788              value = Y.Moodle.core_course.util.section.getId(section.ancestor(M.mod_quiz.edit.get_section_wrapper(Y), true));
 789              var new_string = M.util.get_string('markedthistopic', 'moodle');
 790              button
 791                  .set('title', new_string);
 792              buttonicon
 793                  .set('alt', new_string)
 794                  .set('src', M.util.image_url('i/marked'));
 795          }
 796  
 797          // Change the highlight status.
 798          var data = {
 799              'class' : 'course',
 800              'field' : 'marker',
 801              'value' : value
 802          };
 803          var lightbox = M.util.add_lightbox(Y, section);
 804          lightbox.show();
 805          this.send_request(data, lightbox);
 806      }
 807  },  {
 808      NAME : 'mod_quiz-section-toolbox',
 809      ATTRS : {
 810          courseid : {
 811              'value' : 0
 812          },
 813          quizid : {
 814              'value' : 0
 815          },
 816          format : {
 817              'value' : 'topics'
 818          }
 819      }
 820  });
 821  
 822  M.mod_quiz.init_section_toolbox = function(config) {
 823      return new SECTIONTOOLBOX(config);
 824  };
 825  
 826  
 827  }, '@VERSION@', {
 828      "requires": [
 829          "base",
 830          "node",
 831          "event",
 832          "event-key",
 833          "io",
 834          "moodle-mod_quiz-quizbase",
 835          "moodle-mod_quiz-util-slot",
 836          "moodle-core-notification-ajaxexception"
 837      ]
 838  });


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