Source Code

for file /controls/HSlider.js

// HSlider.js
// Javascript Behaviour for the HSlider Control
// Copyright (c) by Matthias Hertel, http://www.mathertel.de
// This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
// ----- 
// 17.09.2005 PropHSlider was created by Matthias Hertel
// 25.08.2007 HSlider was created from PropHSlider
// 18.12.2007 Simplifications and documentation.
// 06.01.2008 documentation and simplifications

jcl.HSliderBehavior = {
  /// <summary>This control implements is a horizontal moveable rectangle that acts as a slider.
  /// It can be attached to an OpenAjax event and acts as a subscriber and publisher.</summary>
  /// <example>A page that uses this control ist available at:<br />
  /// <a href="http://www.mathertel.de/AJAXEngine/S03_AJAXControls/ConnectionsTestPage.aspx">
  /// http://www.mathertel.de/AJAXEngine/S03_AJAXControls/ConnectionsTestPage.aspx</a></example>

  _knob: null, /// <summary>Reference to the movable knob obj.</summary>
  _lastValue: -1, /// <summary>last published value to avoid doublicate events.</summary>
  _x: 0, /// <summary>Offset between mouse and the knob.</summary>
  _maxright: 0, /// <summary>rightmost position of the knob.</summary>
  _xOffset: 0, /// <summary>x-offset of the region the knob is allowed to be moved.</summary>

  minvalue: 0, /// <summary>The value that is reached on the leftmost position of the knob.</summary>
  maxvalue: 100, /// <summary>The value that is reached on the rightmost position of the knob.</summary>
  unit: 1, /// <summary>The unit of the oublished values. All values can be divided by this value without any reminder
  /// if the value is determined by using the HSlider.</summary>

  eventname: "", /// <summary>The local or complete event name that is used for publishing OpenAjax events.</summary>

  init: function () {
    /// <summary>Initialze the JavaScript control.</summary>
    this._removeTextNodes(this);

    this.eventname = jcl.BuildFullEventname(this);

    if (this.eventname) {
      OpenAjax.hub.subscribe(this.eventname, this._handleEvent, this);
    } // if

    // find the moveable knob
    this._knob = jcl.getElementsByClassName(this, "knob")[0];
    this._removeTextNodes(this._knob.parentNode);

    this._maxright = this.offsetWidth - 32 - this._knob.offsetWidth;

    this.minvalue = parseInt(this.minvalue);
    this.maxvalue = parseInt(this.maxvalue);
    this.unit = parseInt(this.unit);
  }, // init


  // --- events

  onmousedown: function (evt) {
    /// <summary>Handle the event when the mouse button is pressed.</summary>
    evt = evt || window.event;
    var t = evt.target || evt.srcElement;
    var left = this._lastValue;

    if (t.className == "knob") {
      this.MoveStart(evt);

    } else if (t.className == "minus") {
      left = parseInt(left) - this.unit;

    } else if (t.className == "plus") {
      left = parseInt(left) + this.unit;
    } // if

    if (left != this._lastValue) {
      if ((this.eventname != null) && (this.eventname != "")) {
        OpenAjax.hub.publish(this.eventname, left);
      } // if
      this._lastValue = left;
    } // if
  }, // onmousedown


  _onmousemove: function (evt) {
    /// <summary>Handle the mouse button move event. This handler will be attached to the document level.</summary>
    evt = evt || window.event;
    jcl.currentMoving.MoveIt(evt);
  }, // onmousemove


  _onmouseup: function (evt) {
    /// <summary>Handle the mouse button up event. This handler will be attached to the document level.</summary>
    evt = evt || window.event;
    jcl.currentMoving.MoveEnd(evt);
  }, // onmouseup


  // --- methods

  MoveStart: function (evt) {
    /// <summary>Start sliding the knob.</summary>
    this._xOffset = 0;
    var obj = this._knob.offsetParent;
    while (obj != null) {
      this._xOffset += obj.offsetLeft;
      obj = obj.offsetParent;
    } // while

    // calculate mousepointer-knob delta
    this._x = evt.clientX - (this._knob.offsetLeft + this._xOffset);

    jcl.currentMoving = this; // make it globally evailable when mouse is leaving this object.
    jcl.AttachEvent(document, "onmousemove", this._onmousemove);
    jcl.AttachEvent(document, "onmouseup", this._onmouseup);
    // cancel selecting anything
    evt.cancelBubble = true;
    evt.returnValue = false;
  }, // MoveStart


  MoveIt: function (evt) {
    /// <summary>Move the knob element and eventually publish a new event.</summary>
    var left = evt.clientX - this._x - this._xOffset;
    left = Math.min(this._maxright, Math.max(0, left));
    this._knob.style.left = left + "px";

    left = Math.round(left * (this.maxvalue - this.minvalue) / this._maxright + this.minvalue);
    left = Math.round(left / parseInt(this.unit)) * parseInt(this.unit);

    if (left != this._lastValue) {
      if ((this.eventname != null) && (this.eventname != "")) {
        OpenAjax.hub.publish(this.eventname, left);
      } // if

    } // if

    this._lastValue = left;
    // cancel selecting anything
    evt.cancelBubble = true;
    evt.returnValue = false;
  }, // MoveIt


  MoveEnd: function () {
    /// <summary>Handle the end of a moving gesture.</summary>
    if (this._knob != null) {
      jcl.DetachEvent(document, "onmousemove", this._onmousemove);
      jcl.DetachEvent(document, "onmouseup", this._onmouseup);
      jcl.currentMoving = null;
    } // if
  }, // MoveEnd


  // --- OpenAjax event handler ---

  _handleEvent: function (eventName, eventData) {
    /// <summary>Handle OpenAjax events.</summary>
    var knob = this._knob;
    if ((knob != null) && (this._lastValue != eventData)) {
      this._lastValue = eventData;
      eventData = eventData - this.minvalue;
      eventData = Math.round(eventData * this._maxright / (this.maxvalue - this.minvalue));
      eventData = Math.min(this._maxright, Math.max(0, eventData));
      knob.style.left = eventData + "px";
    } // if
  }, // _handleEvent


  _removeTextNodes: function (n) {
    /// <summary>remove all textnodes from the control to avoid unwanted spaces.</summary>
    var obj = n.firstChild;
    while (obj != null) {
      var nextObj = obj.nextSibling;
      if (obj.nodeType == 3)
        obj.parentNode.removeChild(obj);
      obj = nextObj;
    } // while
  } // _removeTextNodes

}; // jcl.HSliderBehavior


This page is part of the http://www.mathertel.de/ web site.

For updates and discussions see http://ajaxaspects.blogspot.com/.