JavaScript DHTML/Ajax Layer/Accordion Panel

Материал из Web эксперт
Перейти к: навигация, поиск

Accordion with color transition example

   
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript">
<!--
//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
var Class = function(properties){
  var klass = function(){
    for (var p in this){
      if (this[p]) this[p]._proto_ = this;
    }
    if (arguments[0] != "noinit" && this.initialize) return this.initialize.apply(this, arguments);
  };
  klass.extend = this.extend;
  klass.implement = this.implement;
  klass.prototype = properties;
  return klass;
};
Class.empty = function(){};
Class.create = function(properties){
  return new Class(properties);
};
Class.prototype = {
  extend: function(properties){
    var pr0t0typ3 = new this("noinit");
    for (var property in properties){
      var previous = pr0t0typ3[property];
      var current = properties[property];
      if (previous && previous != current) current = previous.parentize(current) || current;
      pr0t0typ3[property] = current;
    }
    return new Class(pr0t0typ3);
  },
  implement: function(properties){
    for (var property in properties) this.prototype[property] = properties[property];
  }
};
Object.extend = function(){
  var args = arguments;
  if (args[1]) args = [args[0], args[1]];
  else args = [this, args[0]];
  for (var property in args[1]) args[0][property] = args[1][property];
  return args[0];
};
Object.Native = function(){
  for (var i = 0; i < arguments.length; i++) arguments[i].extend = Class.prototype.implement;
};
new Object.Native(Function, Array, String, Number);
Function.extend({
  parentize: function(current){
    var previous = this;
    return function(){
      this.parent = previous;
      return current.apply(this, arguments);
    };
  }
});
Function.extend({
  pass: function(args, bind){
    var fn = this;
    if ($type(args) != "array") args = [args];
    return function(){
      return fn.apply(bind || fn._proto_ || fn, args);
    };
  },
  bind: function(bind){
    var fn = this;
    return function(){
      return fn.apply(bind, arguments);
    };
  },
  
  bindAsEventListener: function(bind){
    var fn = this;
    return function(event){
      fn.call(bind, event || window.event);
      return false;
    };
  },
  delay: function(ms, bind){
    return setTimeout(this.bind(bind || this._proto_ || this), ms);
  },
  periodical: function(ms, bind){
    return setInterval(this.bind(bind || this._proto_ || this), ms);
  }
});
function $clear(timer){
  clearTimeout(timer);
  clearInterval(timer);
  return null;
};
function $type(obj){
  if (!obj) return false;
  var type = false;
  if (obj instanceof Function) type = "function";
  else if (obj.nodeName){
    if (obj.nodeType == 3 && !/\S/.test(obj.nodeValue)) type = "textnode";
    else if (obj.nodeType == 1) type = "element";
  }
  else if (obj instanceof Array) type = "array";
  else if (typeof obj == "object") type = "object";
  else if (typeof obj == "string") type = "string";
  else if (typeof obj == "number" && isFinite(obj)) type = "number";
  return type;
};
var Chain = new Class({
  chain: function(fn){
    this.chains = this.chains || [];
    this.chains.push(fn);
    return this;
  },
  callChain: function(){
    if (this.chains && this.chains.length) this.chains.splice(0, 1)[0].delay(10, this);
  },
  clearChain: function(){
    this.chains = [];
  }
});
if (!Array.prototype.forEach){
  Array.prototype.forEach = function(fn, bind){
    for(var i = 0; i < this.length ; i++) fn.call(bind, this[i], i);
  };
}
Array.extend({
  each: Array.prototype.forEach,
  copy: function(){
    var newArray = [];
    for (var i = 0; i < this.length; i++) newArray.push(this[i]);
    return newArray;
  },
  remove: function(item){
    for (var i = 0; i < this.length; i++){
      if (this[i] == item) this.splice(i, 1);
    }
    return this;
  },
  test: function(item){
    for (var i = 0; i < this.length; i++){
      if (this[i] == item) return true;
    };
    return false;
  },
  extend: function(newArray){
    for (var i = 0; i < newArray.length; i++) this.push(newArray[i]);
    return this;
  },
  associate: function(keys){
    var newArray = [];
    for (var i =0; i < this.length; i++) newArray[keys[i]] = this[i];
    return newArray;
  }
});
function $A(array){
  return Array.prototype.copy.call(array);
};
String.extend({
  test: function(regex, params){
    return this.match(new RegExp(regex, params));
  },
  toInt: function(){
    return parseInt(this);
  },
  camelCase: function(){
    return this.replace(/-\D/gi, function(match){
      return match.charAt(match.length - 1).toUpperCase();
    });
  },
  capitalize: function(){
    return this.toLowerCase().replace(/\b[a-z]/g, function(match){
      return match.toUpperCase();
    });
  },
  trim: function(){
    return this.replace(/^\s*|\s*$/g, "");
  },
  clean: function(){
    return this.replace(/\s\s/g, " ").trim();
  },
  rgbToHex: function(array){
    var rgb = this.test("([\\d]{1,3})", "g");
    if (rgb[3] == 0) return "transparent";
    var hex = [];
    for (var i = 0; i < 3; i++){
      var bit = (rgb[i]-0).toString(16);
      hex.push(bit.length == 1 ? "0"+bit : bit);
    }
    var hexText = "#"+hex.join("");
    if (array) return hex;
    else return hexText;
  },
  hexToRgb: function(array){
    var hex = this.test("^[#]{0,1}([\\w]{1,2})([\\w]{1,2})([\\w]{1,2})$");
    var rgb = [];
    for (var i = 1; i < hex.length; i++){
      if (hex[i].length == 1) hex[i] += hex[i];
      rgb.push(parseInt(hex[i], 16));
    }
    var rgbText = "rgb("+rgb.join(",")+")";
    if (array) return rgb;
    else return rgbText;
  }
});
Number.extend({
  toInt: function(){
    return this;
  }
});
var Element = new Class({
  initialize: function(el){
    if ($type(el) == "string") el = document.createElement(el);
    return $(el);
  },
  inject: function(el, where){
    el = $(el) || new Element(el);
    switch(where){
      case "before": $(el.parentNode).insertBefore(this, el); break;
      case "after": {
          if (!el.getNext()) $(el.parentNode).appendChild(this);
          else $(el.parentNode).insertBefore(this, el.getNext());
      } break;
      case "inside": el.appendChild(this); break;
    }
    return this;
  },
  injectBefore: function(el){
    return this.inject(el, "before");
  },
  injectAfter: function(el){
    return this.inject(el, "after");
  },
  injectInside: function(el){
    return this.inject(el, "inside");
  },
  adopt: function(el){
    this.appendChild($(el) || new Element(el));
    return this;
  },
  remove: function(){
    this.parentNode.removeChild(this);
  },
  clone: function(contents){
    return $(this.cloneNode(contents || true));
  },
  replaceWith: function(el){
    var el = $(el) || new Element(el);
    this.parentNode.replaceChild(el, this);
    return el;
  },
  appendText: function(text){
    if (this.getTag() == "style" && window.ActiveXObject) this.styleSheet.cssText = text;
    else this.appendChild(document.createTextNode(text));
    return this;
  },
  hasClass: function(className){
    return !!this.className.test("\\b"+className+"\\b");
  },
  addClass: function(className){
    if (!this.hasClass(className)) this.className = (this.className+" "+className.trim()).clean();
    return this;
  },
  removeClass: function(className){
    if (this.hasClass(className)) this.className = this.className.replace(className.trim(), "").clean();
    return this;
  },
  toggleClass: function(className){
    if (this.hasClass(className)) return this.removeClass(className);
    else return this.addClass(className);
  },
  setStyle: function(property, value){
    if (property == "opacity") this.setOpacity(parseFloat(value));
    else this.style[property.camelCase()] = value;
    return this;
  },
  setStyles: function(source){
    if ($type(source) == "object") {
      for (var property in source) this.setStyle(property, source[property]);
    } else if ($type(source) == "string") {
      if (window.ActiveXObject) this.cssText = source;
      else this.setAttribute("style", source);
    }
    return this;
  },
  setOpacity: function(opacity){
    if (opacity == 0){
      if(this.style.visibility != "hidden") this.style.visibility = "hidden";
    } else {
      if(this.style.visibility != "visible") this.style.visibility = "visible";
    }
    if (window.ActiveXObject) this.style.filter = "alpha(opacity=" + opacity*100 + ")";
    this.style.opacity = opacity;
    return this;
  },
  getStyle: function(property){
    var proPerty = property.camelCase();
    var style = this.style[proPerty] || false;
    if (!style) {
      if (document.defaultView) style = document.defaultView.getComputedStyle(this,null).getPropertyValue(property);
      else if (this.currentStyle) style = this.currentStyle[proPerty];
    }
    if (style && ["color", "backgroundColor", "borderColor"].test(proPerty) && style.test("rgb")) style = style.rgbToHex();
    return style;
  },
  addEvent: function(action, fn){
    this[action+fn] = fn.bind(this);
    if (this.addEventListener) this.addEventListener(action, fn, false);
    else this.attachEvent("on"+action, this[action+fn]);
    var el = this;
    if (this != window) Unload.functions.push(function(){
      el.removeEvent(action, fn);
      el[action+fn] = null;
    });
    return this;
  },
  removeEvent: function(action, fn){
    if (this.removeEventListener) this.removeEventListener(action, fn, false);
    else this.detachEvent("on"+action, this[action+fn]);
    return this;
  },
  getBrother: function(what){
    var el = this[what+"Sibling"];
    while ($type(el) == "textnode") el = el[what+"Sibling"];
    return $(el);
  },
  getPrevious: function(){
    return this.getBrother("previous");
  },
  getNext: function(){
    return this.getBrother("next");
  },
  getFirst: function(){
    var el = this.firstChild;
    while ($type(el) == "textnode") el = el.nextSibling;
    return $(el);
  },
  getLast: function(){
    var el = this.lastChild;
    while ($type(el) == "textnode")
    el = el.previousSibling;
    return $(el);
  },
  setProperty: function(property, value){
    var el = false;
    switch(property){
      case "class": this.className = value; break;
      case "style": this.setStyles(value); break;
      case "name": if (window.ActiveXObject && this.getTag() == "input"){
        el = $(document.createElement("<input name=""+value+"" />"));
        $A(this.attributes).each(function(attribute){
          if (attribute.name != "name") el.setProperty(attribute.name, attribute.value);
        
        });
        if (this.parentNode) this.replaceWith(el);
      };
      default: this.setAttribute(property, value);
    }
    return el || this;
  },
  setProperties: function(source){
    for (var property in source) this.setProperty(property, source[property]);
    return this;
  },
  setHTML: function(html){
    this.innerHTML = html;
    return this;
  },
  getProperty: function(property){
    return this.getAttribute(property);
  },
  getTag: function(){
    return this.tagName.toLowerCase();
  },
  getOffset: function(what){
    what = what.capitalize();
    var el = this;
    var offset = 0;
    do {
      offset += el["offset"+what] || 0;
      el = el.offsetParent;
    } while (el);
    return offset;
  },
  getTop: function(){
    return this.getOffset("top");
  },
  getLeft: function(){
    return this.getOffset("left");
  },
  getValue: function(){
    var value = false;
    switch(this.getTag()){
      case "select": value = this.getElementsByTagName("option")[this.selectedIndex].value; break;
      case "input": if ( (this.checked && ["checkbox", "radio"].test(this.type)) || (["hidden", "text", "password"].test(this.type)) ) 
        value = this.value; break;
      case "textarea": value = this.value;
    }
    return value;
  }
});
new Object.Native(Element);
Element.extend({
  hasClassName: Element.prototype.hasClass,
  addClassName: Element.prototype.addClass,
  removeClassName: Element.prototype.removeClass,
  toggleClassName: Element.prototype.toggleClass
});
function $Element(el, method, args){
  if ($type(args) != "array") args = [args];
  return Element.prototype[method].apply(el, args);
};
function $(el){
  if ($type(el) == "string") el = document.getElementById(el);
  if ($type(el) == "element"){
    if (!el.extend){
      Unload.elements.push(el);
      el.extend = Object.extend;
      el.extend(Element.prototype);
    }
    return el;
  } else return false;
};
window.addEvent = document.addEvent = Element.prototype.addEvent;
window.removeEvent = document.removeEvent = Element.prototype.removeEvent;
var Unload = {
  elements: [], functions: [], vars: [],
  unload: function(){
    Unload.functions.each(function(fn){
      fn();
    });
  
    window.removeEvent("unload", window.removeFunction);
  
    Unload.elements.each(function(el){
      for(var p in Element.prototype){
        window[p] = null;
        document[p] = null;
        el[p] = null;
      }
      el.extend = null;
    });
  }
};
window.removeFunction = Unload.unload;
window.addEvent("unload", window.removeFunction);
var Fx = fx = {};
Fx.Base = new Class({
  setOptions: function(options){
    this.options = Object.extend({
      onStart: Class.empty,
      onComplete: Class.empty,
      transition: Fx.Transitions.sineInOut,
      duration: 500,
      unit: "px",
      wait: true,
      fps: 50
    }, options || {});
  },
  step: function(){
    var time = new Date().getTime();
    if (time < this.time + this.options.duration){
      this.cTime = time - this.time;
      this.setNow();
    } else {
      this.options.onComplete.pass(this.element, this).delay(10);
      this.clearTimer();
      this.callChain();
      this.now = this.to;
    }
    this.increase();
  },
  set: function(to){
    this.now = to;
    this.increase();
    return this;
  },
  setNow: function(){
    this.now = this.rupute(this.from, this.to);
  },
  compute: function(from, to){
    return this.options.transition(this.cTime, from, (to - from), this.options.duration);
  },
  custom: function(from, to){
    if (!this.options.wait) this.clearTimer();
    if (this.timer) return;
    this.options.onStart.pass(this.element, this).delay(10);
    this.from = from;
    this.to = to;
    this.time = new Date().getTime();
    this.timer = this.step.periodical(Math.round(1000/this.options.fps), this);
    return this;
  },
  clearTimer: function(){
    this.timer = $clear(this.timer);
    return this;
  },
  setStyle: function(element, property, value){
    element.setStyle(property, value + this.options.unit);
  }
});
Fx.Base.implement(new Chain);
Fx.Style = Fx.Base.extend({
  initialize: function(el, property, options){
    this.element = $(el);
    this.setOptions(options);
    this.property = property.camelCase();
  },
  hide: function(){
    return this.set(0);
  },
  goTo: function(val){
    return this.custom(this.now || 0, val);
  },
  increase: function(){
    this.setStyle(this.element, this.property, this.now);
  }
});
Fx.Styles = Fx.Base.extend({
  initialize: function(el, options){
    this.element = $(el);
    this.setOptions(options);
    this.now = {};
  },
  setNow: function(){
    for (var p in this.from) this.now[p] = this.rupute(this.from[p], this.to[p]);
  },
  custom: function(objFromTo){
    if (this.timer && this.options.wait) return;
    var from = {};
    var to = {};
    for (var p in objFromTo){
      from[p] = objFromTo[p][0];
      to[p] = objFromTo[p][1];
    }
    return this.parent(from, to);
  },
  increase: function(){
    for (var p in this.now) this.setStyle(this.element, p, this.now[p]);
  }
});
Element.extend({
  effect: function(property, options){
    return new Fx.Style(this, property, options);
  },
  effects: function(options){
    return new Fx.Styles(this, options);
  }
});
Fx.Transitions = {
  linear: function(t, b, c, d){
    return c*t/d + b;
  },
  sineInOut: function(t, b, c, d){
    return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
  }
};
function $S(){
  var els = [];
  $A(arguments).each(function(sel){
    if ($type(sel) == "string") els.extend(document.getElementsBySelector(sel));
    else if ($type(sel) == "element") els.push($(sel));
  });
  return $Elements(els);
};
var $$ = $S;
function $E(selector, filter){
  return ($(filter) || document).getElement(selector);
};
function $ES(selector, filter){
  return ($(filter) || document).getElementsBySelector(selector);
};
function $Elements(elements){
  return Object.extend(elements, new Elements);
};
Element.extend({
  getElements: function(selector){
    var filters = [];
    selector.clean().split(" ").each(function(sel, i){
      var bits = sel.test("^(\\w*|\\*)(?:#(\\w+)|\\.(\\w+))?(?:\\[["\"]?(\\w+)["\"]?([\\*\\^\\$]?=)["\"]?(\\w*)["\"]?\\])?$");
      if (!bits) return;
      if (!bits[1]) bits[1] = "*";
      var param = bits.remove(bits[0]).associate(["tag", "id", "class", "attribute", "operator", "value"]);
      if (i == 0){
        if (param["id"]){
          var el = this.getElementById(param["id"]);
          if (!el || (param["tag"] != "*" && $(el).getTag() != param["tag"])) return false;
          filters = [el];
        } else {
          filters = $A(this.getElementsByTagName(param["tag"]));
        }
      } else {
        if (param["id"]) filters = $Elements(filters).filterById(param["id"]);
        filters = $Elements(filters).filterByTagName(param["tag"]);
      }
      if (param["class"]) filters = $Elements(filters).filterByClassName(param["class"]);
      if (param["attribute"]) filters = $Elements(filters).filterByAttribute(param["attribute"], param["value"], param["operator"]);
    }, this);
    filters.each(function(el){
      $(el);
    });
    return $Elements(filters);
  },
  getElement: function(selector){
    return this.getElementsBySelector(selector)[0];
  },
  getElementsBySelector: function(selector){
    var els = [];
    selector.split(",").each(function(sel){
      els.extend(this.getElements(sel));
    }, this);
    return $Elements(els);
  }
});
document.extend = Object.extend;
document.extend({
  getElementsByClassName: function(className){
    return document.getElements("."+className);
  },
  getElement: Element.prototype.getElement,
  getElements: Element.prototype.getElements,
  getElementsBySelector: Element.prototype.getElementsBySelector
});
var Elements = new Class({
  action: function(actions){
    this.each(function(el){
      el = $(el);
      if (actions.initialize) actions.initialize.apply(el);
      for(var action in actions){
        var evt = false;
        if (action.test("^on[\\w]{1,}")) el[action] = actions[action];
        else if (evt = action.test("([\\w-]{1,})event$")) el.addEvent(evt[1], actions[action]);
      }
    });
  },
  //internal methods
  filterById: function(id){
    var found = [];
    this.each(function(el){
      if (el.id == id) found.push(el);
    });
    return found;
  },
  filterByClassName: function(className){
    var found = [];
    this.each(function(el){
      if ($Element(el, "hasClass", className)) found.push(el);
    });
    return found;
  },
  filterByTagName: function(tagName){
    var found = [];
    this.each(function(el){
      found.extend($A(el.getElementsByTagName(tagName)));
    });
    return found;
  },
  filterByAttribute: function(name, value, operator){
    var found = [];
    this.each(function(el){
      var att = el.getAttribute(name);
      if(!att) return;
      if (!operator) return found.push(el);
    
      switch(operator){
        case "*=": if (att.test(value)) found.push(el); break;
        case "=": if (att == value) found.push(el); break;
        case "^=": if (att.test("^"+value)) found.push(el); break;
        case "$=": if (att.test(value+"$")) found.push(el);
      }
    });
    return found;
  }
});
new Object.Native(Elements);
var Ajax = ajax = new Class({
  setOptions: function(options){
    this.options = {
      method: "post",
      postBody: null,
      async: true,
      onComplete: Class.empty,
      onStateChange: Class.empty,
      update: null,
      evalScripts: false
    };
    Object.extend(this.options, options || {});
  },
  initialize: function(url, options){
    this.setOptions(options);
    this.url = url;
    this.transport = this.getTransport();
  },
  request: function(){
    this.transport.open(this.options.method, this.url, this.options.async);
    this.transport.onreadystatechange = this.onStateChange.bind(this);
    if (this.options.method == "post"){
      this.transport.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      if (this.transport.overrideMimeType) this.transport.setRequestHeader("Connection", "close");
    }
    switch($type(this.options.postBody)){
      case "element": this.options.postBody = $(this.options.postBody).toQueryString(); break;
      case "object": this.options.postBody = Object.toQueryString(this.options.postBody);
    }
    if($type(this.options.postBody) == "string") this.transport.send(this.options.postBody);
    else this.transport.send(null);
    return this;
  },
  onStateChange: function(){
    this.options.onStateChange.delay(10, this);
    if (this.transport.readyState == 4 && this.transport.status == 200){
      if (this.options.update) $(this.options.update).setHTML(this.transport.responseText);
      this.options.onComplete.pass([this.transport.responseText, this.transport.responseXML], this).delay(20);
      if (this.options.evalScripts) this.evalScripts.delay(30, this);
      this.transport.onreadystatechange = Class.empty;
      this.callChain();
    }
  },
  evalScripts: function(){
    if(scripts = this.transport.responseText.match(/<script[^>]*?>[\S\s]*?<\/script>/g)){
      scripts.each(function(script){
        eval(script.replace(/^<script[^>]*?>/, "").replace(/<\/script>$/, ""));
      });
    }
  },
  getTransport: function(){
    if (window.XMLHttpRequest) return new XMLHttpRequest();
    else if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");
  }
});
Ajax.implement(new Chain);
Object.toQueryString = function(source){
  var queryString = [];
  for (var property in source) queryString.push(encodeURIComponent(property)+"="+encodeURIComponent(source[property]));
  return queryString.join("&");
};
Element.extend({
  send: function(options){
    options = Object.extend(options, {postBody: this.toQueryString(), method: "post"});
    return new Ajax(this.getProperty("action"), options).request();
  },
  toQueryString: function(){
    var queryString = [];
    $A(this.getElementsByTagName("*")).each(function(el){
      var name = $(el).name;
      var value = el.getValue();
      if (value && name) queryString.push(encodeURIComponent(name)+"="+encodeURIComponent(value));
    });
    return queryString.join("&");
  }
});
var Drag = {};
Drag.Base = new Class({
  setOptions: function(options){
    this.options = Object.extend({
      handle: false,
      unit: "px", 
      onStart: Class.empty, 
      onComplete: Class.empty, 
      onDrag: Class.empty,
      xMax: false,
      xMin: false,
      yMax: false,
      yMin: false
    }, options || {});
  },
  initialize: function(el, xModifier, yModifier, options){
    this.setOptions(options);
    this.element = $(el);
    this.handle = $(this.options.handle) || this.element;
    if (xModifier) this.xp = xModifier.camelCase();
    if (yModifier) this.yp = yModifier.camelCase();
    this.handle.onmousedown = this.start.bind(this);
  },
  start: function(evt){
    evt = evt || window.event;
    this.startX = evt.clientX;
    this.startY = evt.clientY;
  
    this.handleX = this.startX - this.handle.getLeft();
    this.handleY = this.startY - this.handle.getTop();
  
    this.set(evt);
    this.options.onStart.pass(this.element, this).delay(10);
    document.onmousemove = this.drag.bind(this);
    document.onmouseup = this.end.bind(this);
    return false;
  },
  addStyles: function(x, y){
    if (this.xp){
      var stylex = this.element.getStyle(this.xp).toInt();
  
      var movex = function(val){
        this.element.setStyle(this.xp, val+this.options.unit);
      }.bind(this);
  
      if (this.options.xMax && stylex >= this.options.xMax){
        if (this.clientX <= this.handleX+this.handle.getLeft()) movex(stylex+x);
        if (stylex > this.options.xMax) movex(this.options.xMax);
      } else if(this.options.xMin && stylex <= this.options.xMin){
        if (this.clientX >= this.handleX+this.handle.getLeft()) movex(stylex+x);
        if (stylex < this.options.xMin) movex(this.options.xMin);
      } else movex(stylex+x);
    }
    if (this.yp){
      var styley = this.element.getStyle(this.yp).toInt();
      var movey = function(val){
        this.element.setStyle(this.yp, val+this.options.unit);
      }.bind(this);
      if (this.options.yMax && styley >= this.options.yMax){
        if (this.clientY <= this.handleY+this.handle.getTop()) movey(styley+y);
        if (styley > this.options.yMax) movey(this.options.yMax);
      } else if(this.options.yMin && styley <= this.options.yMin){
        if (this.clientY >= this.handleY+this.handle.getTop()) movey(styley+y);
        if (styley < this.options.yMin) movey(this.options.yMin);
      } else movey(styley+y);
    }
  },
  drag: function(evt){
    evt = evt || window.event;
    this.clientX = evt.clientX;
    this.clientY = evt.clientY;
    this.options.onDrag.pass(this.element, this).delay(5);
    this.addStyles((this.clientX-this.lastMouseX), (this.clientY-this.lastMouseY));
    this.set(evt);
    return false;
  },
  set: function(evt){
    this.lastMouseX = evt.clientX;
    this.lastMouseY = evt.clientY;
    return false;
  },
  end: function(){
    document.onmousemove = null;
    document.onmouseup = null;
    this.options.onComplete.pass(this.element, this).delay(10);
  }
});
Drag.Move = Drag.Base.extend({
  extendOptions: function(options){
    this.options = Object.extend(this.options || {}, Object.extend({
      onSnap: Class.empty,
      droppables: [],
      snapDistance: 8,
      snap: true,
      xModifier: "left",
      yModifier: "top",
      container: false
    }, options || {}));
  },
  initialize: function(el, options){
    this.extendOptions(options);
    this.container = $(this.options.container);
    this.parent(el, this.options.xModifier, this.options.yModifier, this.options);
  },
  start: function(evt){
    if (this.options.container) {
      var cont = $(this.options.container).getPosition();
      Object.extend(this.options, {
        xMax: cont.right-this.element.offsetWidth,
        xMin: cont.left,
        yMax: cont.bottom-this.element.offsetHeight,
        yMin: cont.top
      });
    }
    this.parent(evt);
    if (this.options.snap) document.onmousemove = this.checkAndDrag.bind(this);
    return false;
  },
  drag: function(evt){
    this.parent(evt);
    this.options.droppables.each(function(drop){
      if (this.checkAgainst(drop)){
        if (drop.onOver && !drop.dropping) drop.onOver.pass([this.element, this], drop).delay(10);
        drop.dropping = true;
      } else {
        if (drop.onLeave && drop.dropping) drop.onLeave.pass([this.element, this], drop).delay(10);
        drop.dropping = false;
      }
    }, this);
    return false;
  },
  checkAndDrag: function(evt){
    evt = evt || window.event;
    var distance = Math.round(Math.sqrt(Math.pow(evt.clientX - this.startX, 2)+Math.pow(evt.clientY - this.startY, 2)));
    if (distance > this.options.snapDistance){
      this.set(evt);
      this.options.onSnap.pass(this.element, this).delay(10);
      document.onmousemove = this.drag.bind(this);
      this.addStyles(-(this.startX-evt.clientX), -(this.startY-evt.clientY));
    }
    return false;
  },
  checkAgainst: function(el){
    x = this.clientX+Window.getScrollLeft();
    y = this.clientY+Window.getScrollTop();
    var el = $(el).getPosition();
    return (x > el.left && x < el.right && y < el.bottom && y > el.top);
  },
  end: function(){
    this.parent();
    this.options.droppables.each(function(drop){
      if (drop.onDrop && this.checkAgainst(drop)) drop.onDrop.pass([this.element, this], drop).delay(10);
    }, this);
  }
});
Element.extend({
  makeDraggable: function(options){
    return new Drag.Move(this, options);
  },
  makeResizable: function(options){
    return new Drag.Base(this, "width", "height", options);
  },
  getPosition: function(){
    var obj = {};
    obj.width = this.offsetWidth;
    obj.height = this.offsetHeight;
    obj.left = this.getLeft();
    obj.top = this.getTop();
    obj.right = obj.left + obj.width;
    obj.bottom = obj.top + obj.height;
    return obj;
  }
});
var Window = {
  disableImageCache: function(){
    if (window.ActiveXObject) document.execCommand("BackgroundImageCache", false, true);
  },
  extend: Object.extend,
  getWidth: function(){
    return window.innerWidth || document.documentElement.clientWidth || 0;
  },
  getHeight: function(){
    return window.innerHeight || document.documentElement.clientHeight || 0;
  },
  getScrollHeight: function(){
    return document.documentElement.scrollHeight;
  },
  getScrollWidth: function(){
    return document.documentElement.scrollWidth;
  },
  getScrollTop: function(){
    return document.documentElement.scrollTop || window.pageYOffset || 0;
  },
  getScrollLeft: function(){
    return document.documentElement.scrollLeft || window.pageXOffset || 0;
  },
  onDomReady: function(init){
    var state = document.readyState;
    if (state && document.childNodes && !document.all && !navigator.taintEnabled){ //khtml
      if (state.test(/loaded|complete/)) return init();
      else return Window.onDomReady.pass(init).delay(100);
    } else if (state && window.ActiveXObject){ //ie
      var script = $("_ie_ready_");
      if (!script) document.write("<script id="_ie_ready_" defer="true" src="://"></script>");
      $("_ie_ready_").addEvent("readystatechange", function(){
        if (this.readyState == "complete") init();
      });
      return;
    } else { //others
      var myInit = function() {
        if (arguments.callee.done) return;
        arguments.callee.done = true;
        init();
      };
      window.addEvent("load", myInit);
      document.addEvent("DOMContentLoaded", myInit);
    }
  }
};
var Cookie = {
  set: function(key, value, duration){
    var date = new Date();
    date.setTime(date.getTime()+((duration || 365)*86400000));
    document.cookie = key+"="+value+"; expires="+date.toGMTString()+"; path=/";
  },
  get: function(key){
    var myValue, myVal;
    document.cookie.split(";").each(function(cookie){
      if(myVal = cookie.trim().test(key+"=(.*)")) myValue = myVal[1];
    });
    return myValue;
  },
  remove: function(key){
    this.set(key, "", -1);
  }
};
var Json = {
  toString: function(el){
    var string = [];
  
    var isArray = function(array){
      var string = [];
      array.each(function(ar){
        string.push(Json.toString(ar));
      });
      return string.join(",");
    };
  
    var isObject = function(object){
      var string = [];
      for (var property in object) string.push("""+property+"":"+Json.toString(object[property]));
      return string.join(",");
    };
  
    switch($type(obj)){
      case "number": string.push(obj); break;
      case "string": string.push("""+obj+"""); break;
      case "function": string.push(obj); break;
      case "object": string.push("{"+isObject(obj)+"}"); break;
      case "array": string.push("["+isArray(obj)+"]");
    }
  
    return string.join(",");
  },
  evaluate: function(str){
    return eval("(" + str + ")");
  }
};
var Sortables = new Class({
  setOptions: function(options) {
    this.options = {
      handles: false,
      fxDuration: 250,
      fxTransition: Fx.Transitions.sineInOut,
      maxOpacity: 0.5,
      onComplete: Class.empty,
      onStart: Class.empty,
      contain: false
    };
    Object.extend(this.options, options || {});
  },
  initialize: function(elements, options){
    this.setOptions(options);
    this.options.handles = this.options.handles || elements;
    var trash = new Element("div").injectInside($(document.body));
    $A(elements).each(function(el, i){
      var copy = $(el).clone().setStyles({
        "position": "absolute",
        "opacity": "0",
        "display": "none"
      }).injectInside(trash);
      var elEffect = el.effect("opacity", {
        duration: this.options.fxDuration,
        wait: false,
        transition: this.options.fxTransition
      }).set(1);
      var copyEffects = copy.effects({
        duration: this.options.fxDuration,
        wait: false,
        transition: this.options.fxTransition,
        onComplete: function(){
          copy.setStyle("display", "none");
        }
      });
      var yMax = false;
      var yMin = false;
      if (this.options.contain){
        yMax = $(el.parentNode).getTop()+el.parentNode.offsetHeight-el.offsetHeight;
        yMin = el.parentNode.getTop();
      }
      var dragger = new Drag.Move(copy, {
        handle: this.options.handles[i],
        yMax: yMax,
        yMin: yMin,
        xModifier: false,
        onStart: function(){
          this.options.onStart.bind(this).delay(10);
          copy.setHTML(el.innerHTML).setStyles({
            "display": "block",
            "opacity": this.options.maxOpacity,
            "top": el.getTop()+"px",
            "left": el.getLeft()+"px"
          });
          elEffect.custom(elEffect.now, this.options.maxOpacity);
        }.bind(this),
        onComplete: function(){
          this.options.onComplete.bind(this).delay(10);
          copyEffects.custom({
            "opacity": [this.options.maxOpacity, 0],
            "top": [copy.getTop(), el.getTop()]
          });
          elEffect.custom(elEffect.now, 1);
        }.bind(this),
        onDrag: function(){
          if (el.getPrevious() && copy.getTop() < (el.getPrevious().getTop())) el.injectBefore(el.getPrevious());
          else if (el.getNext() && copy.getTop() > (el.getNext().getTop())) el.injectAfter(el.getNext());
        }
      });
    }, this);
  }
});
Fx.Scroll = Fx.Base.extend({
  initialize: function(el, options) {
    this.element = $(el);
    this.setOptions(options);
  },
  down: function(){
    return this.custom(this.element.scrollTop, this.element.scrollHeight-this.element.offsetHeight);
  },
  up: function(){
    return this.custom(this.element.scrollTop, 0);
  },
  increase: function(){
    this.element.scrollTop = this.now;
  }
});
Fx.Slide = Fx.Base.extend({
  initialize: function(el, options){
    this.element = $(el);
    this.wrapper = new Element("div").injectAfter(this.element).setStyle("overflow", "hidden").adopt(this.element);
    this.setOptions(options);
    if (!this.options.mode) this.options.mode = "vertical";
    this.now = [];
  },
  setNow: function(){
    [0,1].each(function(i){
      this.now[i] = this.rupute(this.from[i], this.to[i]);
    }, this);
  },
  vertical: function(){
    this.margin = "top";
    this.layout = "height";
    this.startPosition = [this.element.scrollHeight, "0"];
    this.endPosition = ["0", -this.element.scrollHeight];
    return this;
  },
  horizontal: function(){
    this.margin = "left";
    this.layout = "width";
    this.startPosition = [this.element.scrollWidth, "0"];
    this.endPosition = ["0", -this.element.scrollWidth];
    return this;
  },
  hide: function(){
    this[this.options.mode]();
    this.wrapper.setStyle(this.layout, "0");
    this.element.setStyle("margin-"+this.margin, -this.element["scroll"+this.layout.capitalize()]+this.options.unit);
    return this;
  },
  show: function(){
    this[this.options.mode]();
    this.wrapper.setStyle(this.layout, this.element["scroll"+this.layout.capitalize()]+this.options.unit);
    this.element.setStyle("margin-"+this.margin, "0");
    return this;
  },
  toggle: function(mode){
    this[this.options.mode]();
    if (this.wrapper["offset"+this.layout.capitalize()] > 0) return this.custom(this.startPosition, this.endPosition);
    else return this.custom(this.endPosition, this.startPosition);
  },
  increase: function(){  
    this.wrapper.setStyle(this.layout, this.now[0]+this.options.unit);
    this.element.setStyle("margin-"+this.margin, this.now[1]+this.options.unit);
  }
});
Fx.Color = Fx.Base.extend({
  initialize: function(el, property, options){
    this.element = $(el);
    this.setOptions(options);
    this.property = property;
    this.now = [];
  },
  custom: function(from, to){
    return this.parent(from.hexToRgb(true), to.hexToRgb(true));
  },
  setNow: function(){
    [0,1,2].each(function(i){
      this.now[i] = Math.round(this.rupute(this.from[i], this.to[i]));
    }, this);
  },
  increase: function(){
    this.element.setStyle(this.property, "rgb("+this.now[0]+","+this.now[1]+","+this.now[2]+")");
  },
  fromColor: function(color){
    return this.custom(color, this.element.getStyle(this.property));
  },
  toColor: function(color){
    return this.custom(this.element.getStyle(this.property), color);
  }
});
Fx.Height = Fx.Style.extend({
  initialize: function(el, options){
    this.parent(el, "height", options);
    this.element.setStyle("overflow", "hidden");
  },
  toggle: function(){
    if (this.element.offsetHeight > 0) return this.custom(this.element.offsetHeight, 0);
    else return this.custom(0, this.element.scrollHeight);
  },
  show: function(){
    return this.set(this.element.scrollHeight);
  }
});
Fx.Width = Fx.Style.extend({
  initialize: function(el, options){
    this.parent(el, "width", options);
    this.element.setStyle("overflow", "hidden");
    this.iniWidth = this.element.offsetWidth;
  },
  toggle: function(){
    if (this.element.offsetWidth > 0) return this.custom(this.element.offsetWidth, 0);
    else return this.custom(0, this.iniWidth);
  },
  show: function(){
    return this.set(this.iniWidth);
  }
});
Fx.Opacity = Fx.Style.extend({
  initialize: function(el, options){
    this.parent(el, "opacity", options);
    this.now = 1;
  },
  toggle: function(){
    if (this.now > 0) return this.custom(1, 0);
    else return this.custom(0, 1);
  },
  show: function(){
    return this.set(1);
  }
});
Fx.Transitions = {
  linear: function(t, b, c, d){
    return c*t/d + b;
  },
  quadIn: function(t, b, c, d){
    return c*(t/=d)*t + b;
  },
  quadOut: function(t, b, c, d){
    return -c *(t/=d)*(t-2) + b;
  },
  quadInOut: function(t, b, c, d){
    if ((t/=d/2) < 1) return c/2*t*t + b;
    return -c/2 * ((--t)*(t-2) - 1) + b;
  },
  cubicIn: function(t, b, c, d){
    return c*(t/=d)*t*t + b;
  },
  cubicOut: function(t, b, c, d){
    return c*((t=t/d-1)*t*t + 1) + b;
  },
  cubicInOut: function(t, b, c, d){
    if ((t/=d/2) < 1) return c/2*t*t*t + b;
    return c/2*((t-=2)*t*t + 2) + b;
  },
  quartIn: function(t, b, c, d){
    return c*(t/=d)*t*t*t + b;
  },
  quartOut: function(t, b, c, d){
    return -c * ((t=t/d-1)*t*t*t - 1) + b;
  },
  quartInOut: function(t, b, c, d){
    if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
    return -c/2 * ((t-=2)*t*t*t - 2) + b;
  },
  quintIn: function(t, b, c, d){
    return c*(t/=d)*t*t*t*t + b;
  },
  quintOut: function(t, b, c, d){
    return c*((t=t/d-1)*t*t*t*t + 1) + b;
  },
  quintInOut: function(t, b, c, d){
    if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
    return c/2*((t-=2)*t*t*t*t + 2) + b;
  },
  sineIn: function(t, b, c, d){
    return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
  },
  sineOut: function(t, b, c, d){
    return c * Math.sin(t/d * (Math.PI/2)) + b;
  },
  sineInOut: function(t, b, c, d){
    return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
  },
  expoIn: function(t, b, c, d){
    return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
  },
  expoOut: function(t, b, c, d){
    return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
  },
  expoInOut: function(t, b, c, d){
    if (t==0) return b;
    if (t==d) return b+c;
    if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
    return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
  },
  circIn: function(t, b, c, d){
    return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
  },
  circOut: function(t, b, c, d){
    return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
  },
  circInOut: function(t, b, c, d){
    if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
    return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
  },
  elasticIn: function(t, b, c, d, a, p){
    if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3; if (!a) a = 1;
    if (a < Math.abs(c)){ a=c; var s=p/4; }
    else var s = p/(2*Math.PI) * Math.asin(c/a);
    return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
  },
  elasticOut: function(t, b, c, d, a, p){
    if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3; if (!a) a = 1;
    if (a < Math.abs(c)){ a=c; var s=p/4; }
    else var s = p/(2*Math.PI) * Math.asin(c/a);
    return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
  },
  elasticInOut: function(t, b, c, d, a, p){
    if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5); if (!a) a = 1;
    if (a < Math.abs(c)){ a=c; var s=p/4; }
    else var s = p/(2*Math.PI) * Math.asin(c/a);
    if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
    return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
  },
  backIn: function(t, b, c, d, s){
    if (!s) s = 1.70158;
    return c*(t/=d)*t*((s+1)*t - s) + b;
  },
  backOut: function(t, b, c, d, s){
    if (!s) s = 1.70158;
    return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
  },
  backInOut: function(t, b, c, d, s){
    if (!s) s = 1.70158;
    if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
    return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
  },
  bounceIn: function(t, b, c, d){
    return c - Fx.Transitions.bounceOut (d-t, 0, c, d) + b;
  },
  bounceOut: function(t, b, c, d){
    if ((t/=d) < (1/2.75)){
      return c*(7.5625*t*t) + b;
    } else if (t < (2/2.75)){
      return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
    } else if (t < (2.5/2.75)){
      return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
    } else {
      return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
    }
  },
  bounceInOut: function(t, b, c, d){
    if (t < d/2) return Fx.Transitions.bounceIn(t*2, 0, c, d) * .5 + b;
    return Fx.Transitions.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
  }
};
var Tips = new Class({
  setOptions: function(options){
    this.options = {
      transitionStart: Fx.Transitions.sineInOut,
      transitionEnd: Fx.Transitions.sineInOut,
      maxTitleChars: 30,
      fxDuration: 150,
      maxOpacity: 1,
      timeOut: 100,
      className: "tooltip"
    }
    Object.extend(this.options, options || {});
  },
  initialize: function(elements, options){
    this.elements = elements;
    this.setOptions(options);
    this.toolTip = new Element("div").addClassName(this.options.className).setStyle("position", "absolute").injectInside(document.body);
    this.toolTitle = new Element("H4").injectInside(this.toolTip);
    this.toolText = new Element("p").injectInside(this.toolTip);
    this.fx = new fx.Style(this.toolTip, "opacity", {duration: this.options.fxDuration, wait: false}).hide();
    $A(elements).each(function(el){
      $(el).myText = el.title || false;
      if (el.myText) el.removeAttribute("title");
      if (el.href){
        if (el.href.test("http://")) el.myTitle = el.href.replace("http://", "");
        if (el.href.length > this.options.maxTitleChars) el.myTitle = el.href.substr(0,this.options.maxTitleChars-3)+"...";
      }
      if (el.myText && el.myText.test("::")){
        var dual = el.myText.split("::");
        el.myTitle = dual[0].trim();
        el.myText = dual[1].trim();
      } 
      el.onmouseover = function(){
        this.show(el);
        return false;
      }.bind(this);
      el.onmousemove = this.locate.bindAsEventListener(this);
      el.onmouseout = function(){
        this.timer = $clear(this.timer);
        this.disappear();
      }.bind(this);
    }, this);
  },
  show: function(el){
    this.toolTitle.innerHTML = el.myTitle;
    this.toolText.innerHTML = el.myText;
    this.timer = $clear(this.timer);
    this.fx.options.transition = this.options.transitionStart;
    this.timer = this.appear.delay(this.options.timeOut, this);
  },
  appear: function(){
    this.fx.custom(this.fx.now, this.options.maxOpacity);
  },
  locate: function(evt){
    var doc = document.documentElement;
    this.toolTip.setStyles({"top": evt.clientY + doc.scrollTop + 15 + "px", "left": evt.clientX + doc.scrollLeft - 30 + "px"});
  },
  disappear: function(){
    this.fx.options.transition = this.options.transitionEnd;
    this.fx.custom(this.fx.now, 0);
  }
});
Fx.Elements = Fx.Base.extend({
  initialize: function(elements, options){
    this.elements = [];
    elements.each(function(el){
      this.elements.push($(el));
    }, this);
    this.setOptions(options);
    this.now = {};
  },
  setNow: function(){
    for (var i in this.from){
      var iFrom = this.from[i];
      var iTo = this.to[i];
      var iNow = this.now[i] = {};
      for (var p in iFrom) iNow[p] = this.rupute(iFrom[p], iTo[p]);
    }
  },
  custom: function(objObjs){
    if (this.timer && this.options.wait) return;
    var from = {};
    var to = {};
    for (var i in objObjs){
      var iProps = objObjs[i];
      var iFrom = from[i] = {};
      var iTo = to[i] = {};
      for (var prop in iProps){
        iFrom[prop] = iProps[prop][0];
        iTo[prop] = iProps[prop][1];
      }
    }
    return this.parent(from, to);
  },
  increase: function(){
    for (var i in this.now){
      var iNow = this.now[i];
      for (var p in iNow) this.setStyle(this.elements[i.toInt()], p, iNow[p]);
    }
  }
});
Fx.Accordion = Fx.Elements.extend({
  extendOptions: function(options){
    Object.extend(this.options, Object.extend({
      start: "open-first",
      fixedHeight: false,
      fixedWidth: false,
      alwaysHide: false,
      wait: false,
      onActive: Class.empty,
      onBackground: Class.empty,
      height: true,
      opacity: true,
      width: false
    }, options || {}));
  },
  initialize: function(togglers, elements, options){
    this.parent(elements, options);
    this.extendOptions(options);
    this.previousClick = "nan";
    togglers.each(function(tog, i){
      $(tog).addEvent("click", function(){this.showThisHideOpen(i)}.bind(this));
    }, this);
    this.togglers = togglers;
    this.h = {}; this.w = {}; this.o = {};
    this.elements.each(function(el, i){
      this.now[i] = {};
      $(el).setStyles({"height": 0, "overflow": "hidden"});
    }, this);
    switch(this.options.start){
      case "first-open": this.elements[0].setStyle("height", this.elements[0].scrollHeight+this.options.unit); break;
      case "open-first": this.showThisHideOpen(0); break;
    }
  },
  hideThis: function(i){
    if (this.options.height) this.h = {"height": [this.elements[i].offsetHeight, 0]};
    if (this.options.width) this.w = {"width": [this.elements[i].offsetWidth, 0]};
    if (this.options.opacity) this.o = {"opacity": [this.now[i]["opacity"] || 1, 0]};
  },
  showThis: function(i){
    if (this.options.height) this.h = {"height": [this.elements[i].offsetHeight, this.options.fixedHeight || this.elements[i].scrollHeight]};
    if (this.options.width) this.w = {"width": [this.elements[i].offsetWidth, this.options.fixedWidth || this.elements[i].scrollWidth]};
    if (this.options.opacity) this.o = {"opacity": [this.now[i]["opacity"] || 0, 1]};
  },
  showThisHideOpen: function(iToShow){
    if (iToShow != this.previousClick || this.options.alwaysHide){
      this.previousClick = iToShow;
      var objObjs = {};
      var err = false;
      var madeInactive = false;
      this.elements.each(function(el, i){
        this.now[i] = this.now[i] || {};
        if (i != iToShow){
          this.hideThis(i);
        } else if (this.options.alwaysHide){
          if (el.offsetHeight == el.scrollHeight){
            this.hideThis(i);
            madeInactive = true;
          } else if (el.offsetHeight == 0){
            this.showThis(i);
          } else {
            err = true;
          }
        } else if (this.options.wait && this.timer){
          this.previousClick = "nan";
          err = true;
        } else {
          this.showThis(i);
        }
        objObjs[i] = Object.extend(this.h, Object.extend(this.o, this.w));
      }, this);
      if (err) return;
      if (!madeInactive) this.options.onActive.call(this, this.togglers[iToShow], iToShow);
      this.togglers.each(function(tog, i){
        if (i != iToShow || madeInactive) this.options.onBackground.call(this, tog, i);
      }, this);
      return this.custom(objObjs);
    }
  }
});
-->
</script>
<script type="text/javascript">
var accordion;
var accordionTogglers;
var accordionContents;
window.onload = function() {
  accordionTogglers = document.getElementsByClassName("accToggler");
  
  accordionTogglers.each(function(toggler){
    //remember the original color
    toggler.origColor = toggler.getStyle("background-color");
    //set the effect
    toggler.fx = new Fx.Color(toggler, "background-color");
  });
  
  accordionContents = document.getElementsByClassName("accContent");
    
  accordion = new Fx.Accordion(accordionTogglers, accordionContents,{
    //when an element is opened change the background color to blue
    onActive: function(toggler){
      toggler.fx.toColor("#6899CE");
    },
    onBackground: function(toggler){
      //change the background color to the original (green) 
      //color when another toggler is pressed
      toggler.setStyle("background-color", toggler.origColor);
    }    
  });
}
</script>
<style type="text/css">
*{padding:0px; margin:0px;}
body{font-size:11px; font-family:"Lucida Grande", Arial, sans-serif; color:#6d6d6d;}
.accToggler{
  margin: 3px auto;
  padding: 3px;
  width: 400px;
  background: #acc95f;
  color: #f4f4f4;
  border: 1px solid #fff;
  cursor: pointer;
}
.accContent{
  margin: 0px auto;
  width: 400px;
}
a, a:visited{
font-family:"Lucida Grande", Arial, sans-serif; color:#6d6d6d;
}
</style>
<title>Accordion with color transition example - solutoire.ru</title>
</head>
<body>
<h1 style="text-align:center">Accordion with color transition example - solutoire.ru</h1>
<p style="width: 400px; margin:10px auto">
See the "Javascript used in this example" tab for the options used in this example.
</p>
<p class="accToggler">Click me!</p>
  <p class="accContent">
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In eu elit. Sed consequat neque et sapien. In hac habitasse platea dictumst. In hac habitasse platea 
    dictumst. Donec justo dui, aliquam ac, feugiat nec, malesuada ac, enim. Etiam consequat nulla eget metus malesuada tincidunt. Ut ultrices nonummy metus. 
    Pellentesque pharetra neque eu urna. In nec ligula. Curabitur purus ligula, consectetuer id, auctor et, gravida pretium, est. Aenean vitae neque. Integer dolor 
    enim, ultricies semper, ullamcorper at, mollis at, mauris.
  </p>
  <p class="accToggler">Click me!</p>
  <p class="accContent">
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In eu elit. Sed consequat neque et sapien. In hac habitasse platea dictumst. In hac habitasse platea 
    dictumst. Donec justo dui, aliquam ac, feugiat nec, malesuada ac, enim. Etiam consequat nulla eget metus malesuada tincidunt. Ut ultrices nonummy metus. 
    Pellentesque pharetra neque eu urna. In nec ligula. Curabitur purus ligula, consectetuer id, auctor et, gravida pretium, est. Aenean vitae neque. Integer dolor 
    enim, ultricies semper, ullamcorper at, mollis at, mauris.
  </p>
  <p class="accToggler">Javascript used in this example</p>
  <p class="accContent">
    <code>
    var accordion;<br />
var accordionTogglers;<br />
var accordionContents;<br /><br />
window.onload = function() {<br /><br />
  accordionTogglers = document.getElementsByClassName("accToggler");<br /><br />
  
  accordionTogglers.each(function(toggler){<br />
    //remember the original color<br />
    toggler.origColor = toggler.getStyle("background-color");<br />
    //set the effect<br />
    toggler.fx = new Fx.Color(toggler, "background-color");<br />
  });<br /><br />
    
  accordionContents = document.getElementsByClassName("accContent");<br /><br />
  accordion = new Fx.Accordion(accordionTogglers, <br />
    accordionContents,{<br />
    //when an element is opened change the<br />
    //background color to blue<br />
    onActive: function(toggler){<br />
      toggler.fx.toColor("#6899CE");<br />
    },<br />
    onBackground: function(toggler){<br />
      //change the background color to the original (green)<br /> 
      //color when another toggler is pressed<br />
      toggler.setStyle("background-color", toggler.origColor);<br />
    }<br />
  });<br />    
}
    </code>
  </p>
  <p class="accToggler">CSS used in this example</p>
  <p class="accContent">
  <code>
.accToggler{<br />
  margin: 3px auto;<br />
  padding: 3px;<br />
  width: 400px;<br />
  background: #acc95f;<br />
  color: #f4f4f4;<br />
  border: 1px solid #fff;<br />
  cursor: pointer;<br />
}<br /><br />
.accContent{<br />
  margin: 0px auto;<br />
  width: 400px;<br />
}<code>
  </p>
  <p style="width: 400px; margin:10px auto;text-align:center">
  &copy;2006 <b><a href="http://www.solutoire.ru/">solutoire.ru</a></b>
</p>
</body>
</html>



Another accordion panel

<A href="http://www.wbex.ru/Code/JavaScriptDownload/accordion1.zip">accordion1.zip( 46 k)</a>

1. <A href="/Code/JavaScript/Ajax-Layer/Accordionwithcolortransitionexample.htm">Accordion with color transition example</a>