Tuesday, February 5, 2013 4:52 PM

Re-adding setOptions() to prototype

Author: matthias - Last modified: Tuesday, February 5, 2013 4:52 PM

en prototype  scriptaculous  javascript  fixlet code

If you - like me - have to deal with legacy code of web applications that runs for years at customers' satisfaction but suddenly causes problems as soon as newer browser versions (that e.g. lack of some DOM compatibility modes) are used... and if you're making extensive use of scriptaculous and/or prototype - like I once did - read on.

This one is quite special but eventually the problem description and solution is helpful to anyone.

Problem description

There may exist legacy JS code in the wild that wants to make use of prototype library versions >= 1.7.0 (e.g. in combination with scriptaculous >= 1.9.0 for IE compatibility reasons in conjunction with scriptaculous' dragdrop.js) but fails to behave correctly because custom code extends prototype classes and relies on the old setOptions() method originally provided by Ajax.Base.prototype.

So, if you recently upgraded from prototype 1.5.x or scriptaculous 1.7.x to a later version and experience problems with your application: Instead of refactoring the old code, this one may help out as a quick fix.

Code

Fork this code on GitHub

/**
 *  prototype-setoptions.fixlet.js
 *  
 *  Author:
 *     Matthias Lienau <matthias@mlienau.de>
 *
 *  Licensed under the MIT license:
 *    http://www.opensource.org/licenses/mit-license.php
 */
(function($) { 

  function getVersion(verString) {
    var v = verString.replace(/_.*|\./g, '');
    v = parseInt(v + '0'.times(4 - v.length));
    return verString.indexOf('_') > -1 ? v - 1 : v;
  }

  if ((typeof Prototype == 'undefined') || 
      (getVersion(Prototype.Version) <= getVersion('1.6.0'))) {
    throw('"prototype-setoptions-fixlet.js" only applicable for Prototype JavaScript framework >= 1.7.0. Skipping fixlet code.'); 
  }

  console.info('"prototype-setoptions-fixlet.js" detected Prototype version ' + Prototype.Version + '. Applying fixlet code.');

  Object.extend(Ajax.Base.prototype, {
    setOptions: function(options) {
      this.options = {
        method: 'post', 
        asynchronous: true, 
        contentType: 'application/x-www-form-urlencoded',
        encoding: 'UTF-8', 
        parameters: '', 
        evalJSON: true, 
        evalJS: true
      };  
      Object.extend(this.options, options || {});
    }
  });

})();

Usage

Just load the js as a "drop-in" additionally to loading prototype.js, for example:

<script src="/yourjsfolder/prototype-1.7.1.js" type="text/javascript" />
<script src="/yourjsfolder/prototype-setoptions-fixlet.js" type="text/javascript" />

Hope that's helpful - feel free to contact me on any questions.

Comment / Share »