[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yui/build/moodle-core-formchangechecker/ -> moodle-core-formchangechecker.js (source)

   1  YUI.add('moodle-core-formchangechecker', function (Y, NAME) {
   2  
   3  /**
   4   * A utility to check for form changes before navigating away from a page.
   5   *
   6   * @module moodle-core-formchangechecker
   7   */
   8  
   9  /**
  10   * A utility to check for form changes before navigating away from a page.
  11   *
  12   * @class M.core.formchangechecker
  13   * @constructor
  14   */
  15  
  16  var FORMCHANGECHECKERNAME = 'core-formchangechecker',
  17  
  18      FORMCHANGECHECKER = function() {
  19          FORMCHANGECHECKER.superclass.constructor.apply(this, arguments);
  20      };
  21  
  22  Y.extend(FORMCHANGECHECKER, Y.Base, {
  23  
  24          // The delegated listeners we need to detach after the initial value has been stored once
  25          initialvaluelisteners: [],
  26  
  27          /**
  28           * Initialize the module
  29           *
  30           * @method initializer
  31           */
  32          initializer: function() {
  33              var formid = 'form#' + this.get('formid'),
  34                  currentform = Y.one(formid);
  35  
  36              if (!currentform) {
  37                  // If the form was not found, then we can't check for changes.
  38                  return;
  39              }
  40  
  41              // Add a listener here for an editor restore event.
  42              Y.on(M.core.event.EDITOR_CONTENT_RESTORED, M.core_formchangechecker.reset_form_dirty_state, this);
  43  
  44              // Add change events to the form elements
  45              currentform.delegate('change', M.core_formchangechecker.set_form_changed, 'input', this);
  46              currentform.delegate('change', M.core_formchangechecker.set_form_changed, 'textarea', this);
  47              currentform.delegate('change', M.core_formchangechecker.set_form_changed, 'select', this);
  48  
  49              // Add a focus event to check for changes which are made without triggering a change event
  50              this.initialvaluelisteners.push(currentform.delegate('focus', this.store_initial_value, 'input', this));
  51              this.initialvaluelisteners.push(currentform.delegate('focus', this.store_initial_value, 'textarea', this));
  52              this.initialvaluelisteners.push(currentform.delegate('focus', this.store_initial_value, 'select', this));
  53  
  54              // We need any submit buttons on the form to set the submitted flag
  55              Y.one(formid).on('submit', M.core_formchangechecker.set_form_submitted, this);
  56  
  57              // YUI doesn't support onbeforeunload properly so we must use the DOM to set the onbeforeunload. As
  58              // a result, the has_changed must stay in the DOM too
  59              window.onbeforeunload = M.core_formchangechecker.report_form_dirty_state;
  60          },
  61  
  62          /**
  63           * Store the initial value of the currently focussed element
  64           *
  65           * If an element has been focussed and changed but not yet blurred, the on change
  66           * event won't be fired. We need to store it's initial value to compare it in the
  67           * get_form_dirty_state function later.
  68           *
  69           * @method store_initial_value
  70           * @param {EventFacade} e
  71           */
  72          store_initial_value: function(e) {
  73              var thisevent;
  74              if (e.target.hasClass('ignoredirty')) {
  75                  // Don't warn on elements with the ignoredirty class
  76                  return;
  77              }
  78              if (M.core_formchangechecker.get_form_dirty_state()) {
  79                  // Detach all listen events to prevent duplicate initial value setting
  80                  while (this.initialvaluelisteners.length) {
  81                      thisevent = this.initialvaluelisteners.shift();
  82                      thisevent.detach();
  83                  }
  84  
  85                  return;
  86              }
  87  
  88              // Make a note of the current element so that it can be interrogated and
  89              // compared in the get_form_dirty_state function
  90              M.core_formchangechecker.stateinformation.focused_element = {
  91                  element: e.target,
  92                  initial_value: e.target.get('value')
  93              };
  94          }
  95      },
  96      {
  97          NAME: FORMCHANGECHECKERNAME,
  98          ATTRS: {
  99              formid: {
 100                  'value': ''
 101              }
 102          }
 103      }
 104  );
 105  
 106  M.core_formchangechecker = M.core_formchangechecker || {};
 107  
 108  // We might have multiple instances of the form change protector
 109  M.core_formchangechecker.instances = M.core_formchangechecker.instances || [];
 110  M.core_formchangechecker.init = function(config) {
 111      var formchangechecker = new FORMCHANGECHECKER(config);
 112      M.core_formchangechecker.instances.push(formchangechecker);
 113      return formchangechecker;
 114  };
 115  
 116  // Store state information
 117  M.core_formchangechecker.stateinformation = [];
 118  
 119  /*
 120   * Set the form changed state to true
 121   */
 122  M.core_formchangechecker.set_form_changed = function(e) {
 123      if (e && e.target && e.target.hasClass('ignoredirty')) {
 124          // Don't warn on elements with the ignoredirty class
 125          return;
 126      }
 127      M.core_formchangechecker.stateinformation.formchanged = 1;
 128  
 129      // Once the form has been marked as dirty, we no longer need to keep track of form elements
 130      // which haven't yet blurred
 131      delete M.core_formchangechecker.stateinformation.focused_element;
 132  };
 133  
 134  /*
 135   * Set the form submitted state to true
 136   */
 137  M.core_formchangechecker.set_form_submitted = function() {
 138      M.core_formchangechecker.stateinformation.formsubmitted = 1;
 139  };
 140  
 141  /*
 142   * Attempt to determine whether the form has been modified in any way and
 143   * is thus 'dirty'
 144   *
 145   * @return Integer 1 is the form is dirty; 0 if not
 146   */
 147  M.core_formchangechecker.get_form_dirty_state = function() {
 148      var state = M.core_formchangechecker.stateinformation,
 149          editor;
 150  
 151      // If the form was submitted, then return a non-dirty state
 152      if (state.formsubmitted) {
 153          return 0;
 154      }
 155  
 156      // If any fields have been marked dirty, return a dirty state
 157      if (state.formchanged) {
 158          return 1;
 159      }
 160  
 161      // If a field has been focused and changed, but still has focus then the browser won't fire the
 162      // onChange event. We check for this eventuality here
 163      if (state.focused_element) {
 164          if (state.focused_element.element.get('value') !== state.focused_element.initial_value) {
 165              return 1;
 166          }
 167      }
 168  
 169      // Handle TinyMCE editor instances
 170      // We can't add a listener in the initializer as the editors may not have been created by that point
 171      // so we do so here instead
 172      if (typeof window.tinyMCE !== 'undefined') {
 173          for (editor in window.tinyMCE.editors) {
 174              if (window.tinyMCE.editors[editor].isDirty()) {
 175                  return 1;
 176              }
 177          }
 178      }
 179  
 180      // If we reached here, then the form hasn't met any of the dirty conditions
 181      return 0;
 182  };
 183  
 184  /*
 185   * Reset the form state
 186   */
 187  M.core_formchangechecker.reset_form_dirty_state = function() {
 188      M.core_formchangechecker.stateinformation.formsubmitted = false;
 189      M.core_formchangechecker.stateinformation.formchanged = false;
 190  };
 191  
 192  /*
 193   * Return a suitable message if changes have been made to a form
 194   */
 195  M.core_formchangechecker.report_form_dirty_state = function(e) {
 196      if (!M.core_formchangechecker.get_form_dirty_state()) {
 197          // the form is not dirty, so don't display any message
 198          return;
 199      }
 200  
 201      // This is the error message that we'll show to browsers which support it
 202      var warningmessage = M.util.get_string('changesmadereallygoaway', 'moodle');
 203  
 204      if (M.cfg.behatsiterunning) {
 205          // If the behat site is running we don't want browser alerts.
 206          return;
 207      }
 208  
 209      // Most browsers are happy with the returnValue being set on the event
 210      // But some browsers do not consistently pass the event
 211      if (e) {
 212          e.returnValue = warningmessage;
 213      }
 214  
 215      // But some require it to be returned instead
 216      return warningmessage;
 217  };
 218  
 219  
 220  }, '@VERSION@', {"requires": ["base", "event-focus", "moodle-core-event"]});


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