[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/quiz/yui/src/toolboxes/js/ -> section.js (source)

   1  /* global TOOLBOX, BODY, SELECTOR */
   2  
   3  /**
   4   * Section toolbox class.
   5   *
   6   * This class is responsible for managing AJAX interactions with sections
   7   * when adding, editing, removing section headings.
   8   *
   9   * @module moodle-mod_quiz-toolboxes
  10   * @namespace M.mod_quiz.toolboxes
  11   */
  12  
  13  /**
  14   * Section toolbox class.
  15   *
  16   * This class is responsible for managing AJAX interactions with sections
  17   * when adding, editing, removing section headings when editing a quiz.
  18   *
  19   * @class section
  20   * @constructor
  21   * @extends M.mod_quiz.toolboxes.toolbox
  22   */
  23  var SECTIONTOOLBOX = function() {
  24      SECTIONTOOLBOX.superclass.constructor.apply(this, arguments);
  25  };
  26  
  27  Y.extend(SECTIONTOOLBOX, TOOLBOX, {
  28      /**
  29       * An Array of events added when editing a max mark field.
  30       * These should all be detached when editing is complete.
  31       *
  32       * @property editsectionevents
  33       * @protected
  34       * @type Array
  35       * @protected
  36       */
  37      editsectionevents: [],
  38  
  39      /**
  40       * Initialize the section toolboxes module.
  41       *
  42       * Updates all span.commands with relevant handlers and other required changes.
  43       *
  44       * @method initializer
  45       * @protected
  46       */
  47      initializer: function() {
  48          M.mod_quiz.quizbase.register_module(this);
  49  
  50          BODY.delegate('key', this.handle_data_action, 'down:enter', SELECTOR.ACTIVITYACTION, this);
  51          Y.delegate('click', this.handle_data_action, BODY, SELECTOR.ACTIVITYACTION, this);
  52          Y.delegate('change', this.handle_data_action, BODY, SELECTOR.EDITSHUFFLEQUESTIONSACTION, this);
  53      },
  54  
  55      /**
  56       * Handles the delegation event. When this is fired someone has triggered an action.
  57       *
  58       * Note not all actions will result in an AJAX enhancement.
  59       *
  60       * @protected
  61       * @method handle_data_action
  62       * @param {EventFacade} ev The event that was triggered.
  63       * @returns {boolean}
  64       */
  65      handle_data_action: function(ev) {
  66          // We need to get the anchor element that triggered this event.
  67          var node = ev.target;
  68          if (!node.test('a') && !node.test('input[data-action]')) {
  69              node = node.ancestor(SELECTOR.ACTIVITYACTION);
  70          }
  71  
  72          // From the anchor we can get both the activity (added during initialisation) and the action being
  73          // performed (added by the UI as a data attribute).
  74          var action = node.getData('action'),
  75              activity = node.ancestor(SELECTOR.ACTIVITYLI);
  76  
  77          if ((!node.test('a') && !node.test('input[data-action]')) || !action || !activity) {
  78              // It wasn't a valid action node.
  79              return;
  80          }
  81  
  82          // Switch based upon the action and do the desired thing.
  83          switch (action) {
  84              case 'edit_section_title':
  85                  // The user wishes to edit the section headings.
  86                  this.edit_section_title(ev, node, activity, action);
  87                  break;
  88              case 'shuffle_questions':
  89                  // The user wishes to edit the shuffle questions of the section (resource).
  90                  this.edit_shuffle_questions(ev, node, activity, action);
  91                  break;
  92              case 'deletesection':
  93                  // The user is deleting the activity.
  94                  this.delete_section_with_confirmation(ev, node, activity, action);
  95                  break;
  96              default:
  97                  // Nothing to do here!
  98                  break;
  99          }
 100      },
 101  
 102      /**
 103       * Deletes the given section heading after confirmation.
 104       *
 105       * @protected
 106       * @method delete_section_with_confirmation
 107       * @param {EventFacade} ev The event that was fired.
 108       * @param {Node} button The button that triggered this action.
 109       * @param {Node} activity The activity node that this action will be performed on.
 110       * @chainable
 111       */
 112      delete_section_with_confirmation: function(ev, button, activity) {
 113          // Prevent the default button action.
 114          ev.preventDefault();
 115  
 116          // Create the confirmation dialogue.
 117          var confirm = new M.core.confirm({
 118              question: M.util.get_string('confirmremovesectionheading', 'quiz', activity.get('aria-label')),
 119              modal: true
 120          });
 121  
 122          // If it is confirmed.
 123          confirm.on('complete-yes', function() {
 124  
 125              var spinner = M.util.add_spinner(Y, activity.one(SELECTOR.ACTIONAREA));
 126              var data = {
 127                  'class':  'section',
 128                  'action': 'DELETE',
 129                  'id':     activity.get('id').replace('section-', '')
 130              };
 131              this.send_request(data, spinner, function(response) {
 132                  if (response.deleted) {
 133                      window.location.reload(true);
 134                  }
 135              });
 136  
 137          }, this);
 138      },
 139  
 140      /**
 141       * Edit the edit section title for the section
 142       *
 143       * @protected
 144       * @method edit_section_title
 145       * @param {EventFacade} ev The event that was fired.
 146       * @param {Node} button The button that triggered this action.
 147       * @param {Node} activity The activity node that this action will be performed on.
 148       * @param {String} action The action that has been requested.
 149       * @return Boolean
 150       */
 151      edit_section_title: function(ev, button, activity) {
 152          // Get the element we're working on
 153          var activityid = activity.get('id').replace('section-', ''),
 154              instancesection = activity.one(SELECTOR.INSTANCESECTION),
 155              thisevent,
 156              anchor = instancesection, // Grab the anchor so that we can swap it with the edit form.
 157              data = {
 158                  'class': 'section',
 159                  'field': 'getsectiontitle',
 160                  'id':    activityid
 161              };
 162  
 163          // Prevent the default actions.
 164          ev.preventDefault();
 165  
 166          this.send_request(data, null, function(response) {
 167              // Try to retrieve the existing string from the server.
 168              var oldtext = response.instancesection;
 169  
 170              // Create the editor and submit button.
 171              var editform = Y.Node.create('<form action="#" />');
 172              var editinstructions = Y.Node.create('<span class="' + CSS.EDITINSTRUCTIONS + '" id="id_editinstructions" />')
 173                  .set('innerHTML', M.util.get_string('edittitleinstructions', 'moodle'));
 174              var editor = Y.Node.create('<input name="section" type="text" />').setAttrs({
 175                  'value': oldtext,
 176                  'autocomplete': 'off',
 177                  'aria-describedby': 'id_editinstructions',
 178                  'maxLength': '255' // This is the maxlength in DB.
 179              });
 180  
 181              // Clear the existing content and put the editor in.
 182              editform.appendChild(editor);
 183              editform.setData('anchor', anchor);
 184              instancesection.insert(editinstructions, 'before');
 185              anchor.replace(editform);
 186  
 187              // Focus and select the editor text.
 188              editor.focus().select();
 189              // Cancel the edit if we lose focus or the escape key is pressed.
 190              thisevent = editor.on('blur', this.edit_section_title_cancel, this, activity, false);
 191              this.editsectionevents.push(thisevent);
 192              thisevent = editor.on('key', this.edit_section_title_cancel, 'esc', this, activity, true);
 193              this.editsectionevents.push(thisevent);
 194              // Handle form submission.
 195              thisevent = editform.on('submit', this.edit_section_title_submit, this, activity, oldtext);
 196              this.editsectionevents.push(thisevent);
 197          });
 198      },
 199  
 200      /**
 201       * Handles the submit event when editing section heading.
 202       *
 203       * @protected
 204       * @method edit_section_title_submiy
 205       * @param {EventFacade} ev The event that triggered this.
 206       * @param {Node} activity The activity whose maxmark we are altering.
 207       * @param {String} oldtext The original maxmark the activity or resource had.
 208       */
 209      edit_section_title_submit: function(ev, activity, oldtext) {
 210           // We don't actually want to submit anything.
 211          ev.preventDefault();
 212          var newtext = Y.Lang.trim(activity.one(SELECTOR.SECTIONFORM + ' ' + SELECTOR.SECTIONINPUT).get('value'));
 213          var spinner = M.util.add_spinner(Y, activity.one(SELECTOR.INSTANCESECTIONAREA));
 214          this.edit_section_title_clear(activity);
 215          if (newtext !== null && newtext !== oldtext) {
 216              activity.one(SELECTOR.INSTANCESECTION).setContent(newtext);
 217              var data = {
 218                  'class':      'section',
 219                  'field':      'updatesectiontitle',
 220                  'newheading': newtext,
 221                  'id':         activity.get('id').replace('section-', '')
 222              };
 223              this.send_request(data, spinner, function(response) {
 224                  if (response) {
 225                      activity.one(SELECTOR.INSTANCESECTION).setContent(response.instancesection);
 226                      activity.one(SELECTOR.EDITSECTIONICON).set('title',
 227                              M.util.get_string('sectionheadingedit', 'quiz', response.instancesection));
 228                      activity.one(SELECTOR.EDITSECTIONICON).set('alt',
 229                              M.util.get_string('sectionheadingedit', 'quiz', response.instancesection));
 230                      var deleteicon = activity.one(SELECTOR.DELETESECTIONICON);
 231                      if (deleteicon) {
 232                          deleteicon.set('title', M.util.get_string('sectionheadingremove', 'quiz', response.instancesection));
 233                          deleteicon.set('alt', M.util.get_string('sectionheadingremove', 'quiz', response.instancesection));
 234                      }
 235                  }
 236              });
 237          }
 238      },
 239  
 240      /**
 241       * Handles the cancel event when editing the activity or resources maxmark.
 242       *
 243       * @protected
 244       * @method edit_maxmark_cancel
 245       * @param {EventFacade} ev The event that triggered this.
 246       * @param {Node} activity The activity whose maxmark we are altering.
 247       * @param {Boolean} preventdefault If true we should prevent the default action from occuring.
 248       */
 249      edit_section_title_cancel: function(ev, activity, preventdefault) {
 250          if (preventdefault) {
 251              ev.preventDefault();
 252          }
 253          this.edit_section_title_clear(activity);
 254      },
 255  
 256      /**
 257       * Handles clearing the editing UI and returning things to the original state they were in.
 258       *
 259       * @protected
 260       * @method edit_maxmark_clear
 261       * @param {Node} activity  The activity whose maxmark we were altering.
 262       */
 263      edit_section_title_clear: function(activity) {
 264          // Detach all listen events to prevent duplicate triggers
 265          new Y.EventHandle(this.editsectionevents).detach();
 266  
 267          var editform = activity.one(SELECTOR.SECTIONFORM),
 268              instructions = activity.one('#id_editinstructions');
 269          if (editform) {
 270              editform.replace(editform.getData('anchor'));
 271          }
 272          if (instructions) {
 273              instructions.remove();
 274          }
 275  
 276          // Refocus the link which was clicked originally so the user can continue using keyboard nav.
 277          Y.later(100, this, function() {
 278              activity.one(SELECTOR.EDITSECTION).focus();
 279          });
 280  
 281          // This hack is to keep Behat happy until they release a version of
 282          // MinkSelenium2Driver that fixes
 283          // https://github.com/Behat/MinkSelenium2Driver/issues/80.
 284          if (!Y.one('input[name=section]')) {
 285              Y.one('body').append('<input type="text" name="section" style="display: none">');
 286          }
 287      },
 288  
 289      /**
 290       * Edit the edit shuffle questions for the section
 291       *
 292       * @protected
 293       * @method edit_shuffle_questions
 294       * @param {EventFacade} ev The event that was fired.
 295       * @param {Node} button The button that triggered this action.
 296       * @param {Node} activity The activity node that this action will be performed on.
 297       * @param {String} action The action that has been requested.
 298       * @return Boolean
 299       */
 300      edit_shuffle_questions: function(ev, button, activity) {
 301          var newvalue;
 302          if (activity.one(SELECTOR.EDITSHUFFLEQUESTIONSACTION).get('checked')) {
 303              newvalue = 1;
 304          } else {
 305              newvalue = 0;
 306          }
 307  
 308          // Get the element we're working on
 309          var data = {
 310              'class': 'section',
 311              'field': 'updateshufflequestions',
 312              'id': activity.get('id').replace('section-', ''),
 313              'newshuffle': newvalue
 314          };
 315  
 316          // Prevent the default actions.
 317          ev.preventDefault();
 318  
 319          // Send request.
 320          var spinner = M.util.add_spinner(Y, activity.one(SELECTOR.EDITSHUFFLEAREA));
 321          this.send_request(data, spinner);
 322      }
 323  
 324  }, {
 325      NAME: 'mod_quiz-section-toolbox',
 326      ATTRS: {
 327          courseid: {
 328              'value': 0
 329          },
 330          quizid: {
 331              'value': 0
 332          }
 333      }
 334  });
 335  
 336  M.mod_quiz.init_section_toolbox = function(config) {
 337      return new SECTIONTOOLBOX(config);
 338  };


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