
        JSlider JavaScript Library

        Copyright 2006, James Melanson
                        james_melanson@yahoo.ca
        
                        JSlider V1.02       2007.01.05

        All Rights Reserved.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

        What this means is:

          1.) If you are creating free software that is distributed for free,
              you can use this library for free.

          2.) If you are going to use this library in an application you will
              be selling OR are creating the application for a Commercial
              application OR are creating the application for which you are
              receiving compensation (money, product or employment), then 
              you must purchase a Commercial License for this library for
              US$25. Contact me at the email above for more details.
        
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>


  CONTENTS OF README FILE:
  
  1.) Overview
  2.) Implementation
      i    What files to use.
      ii   Linking to the files.
      iii  Instantiating the slider object
            a.) Instantiating multiple slider objects
      iv   Loading the Slider Object.
      v    Specifying the slider values and movements
            a.) Minimum / Maximum Value (Value Range)
            b.) Pixels Per Unit
            c.) Unit Increments
            d.) Track Length
      vi   Forcing the slider value/position
      vii  Defining the look of the track/path
            a.) Track properties
            b.) Orientation
            c.) Path properties
      viii Defining the look of the knob
      ix   Rollover effects
      x    Rollover exclusions
      xi   Using the value of the slider
            a.) Auto-reporting the current value of the slider position
            b.) Auto-notifying another javascript function
            c.) Query the current value of the slider position
      xii  Locking & Un-Locking the slider
  3.) Full Property & Method List
  4.) Create Slider Utility
  5.) Samples of instantion, property assignment and working sliders
  6.) Debugging
  7.) Support


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  OVERVIEW

  JSlider is a JavaScript library to simplify the implementation of visual "sliders"
  on a web page. There are many uses for this from games to financial calculations.

  Creating sliders from scratch are a lengthy and time consuming process requiring
  programming skill and hand coded HTML skill the average web master does not possess or
  want to invest the time in. As well, until now, web page sliders have typically come
  as either Java Applets of Flash inserts. HTML Sliders have been quirky and iffy at
  best.

  That has all changed with the release of this library.

  This library was created so you can have an HTML/JavaScript slider up and running on
  your page in a matter of minutes as opposed to days or weeks. By taking an object
  oriented approach, all you need to do is set a few properties. You do not need to
  know any JavaScript programming and you do not need to know how to hand code HTML, CSS, etc.

  To see what the sliders look like and how they operate, open the file
  "slider_samples.html" in your web browser of choice.

  This Library has been written to work in IE, Opera, Firefox and Netscape. I have
  no access to an Apple to test it so feedback would be appreciated.


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>


  IMPLEMENTATION - WHAT FILES TO USE.

  The files that you need to implement this with your web page are:

  jslider_ieo.js
  jslider_drag.js

  If you are developing locally, on your desktop, simply save the files to the same
  project folder as the page you are implementing them on.

  For live implementation, FTP the files in ASCII mode (not Binary) to the web server.

  The browsers that these libraries support are:

  Opera 7+
  IE 5.5+ (Possibly some builds of IE5.0)
  Firefox 1.5+
  Netscape 8.0 (Possibly earlier versions as well)

  The library was developed in Opera and then ported to work in the other browsers.

  Known Issues:

    --UnHide feature does not seem to work on Netscape but does on the other three.

    --Some people have asked why the knob stops moving if the mouse slips off it.
      Well... Duhhhhh.... this is not an issue, it was designed that way.



<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  IMPLEMENTATION - LINKING TO THE FILES.

  The slider library file has been written to support the four browsers above. There
  are no browser specific files.

  The code below shows you how to link to the files. Remember that this code MUST
  come before any other references to the slider object you will be creating.

  Inside the <head></head> tags of the web page you are implementing the slider on,
  copy and past the following code inside the snippet blocks:

  [-- Start Snippet --]

<script language="JavaScript" src="jslider_drag.js"></script>
<script language="JavaScript" src="jslider_ieo.js"></script>

  [--  End Snippet --]


  If you are calling the library files from a different folder, make sure you change the "src"
  attribute to a relative path or full URL.

  **It would be preferable that you paste the above code BEFORE ANY OTHER IN-LINE JAVASCRIPT.


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>


  IMPLEMENTATION - INSTANTIATING THE SLIDER OBJECT

  After implementing the above, we now move on to instantiating (creating) the slider object.

  The following line of code is what we use to create the slider object:

                    var objHandle = new JSlider('objHandle');

  You MUST pass one argument to the new object call and that MUST be the same name as the handle
  you assigned to the object. Here are a few examples:

                    var slider = new JSlider('slider');
                    var colorslider = new JSlider('colorslider');
                    var slider2 = new JSlider('slider2');

  This is necessary because JavaScript does not have a method of reading the name of the caller that was
  reliable in all the browsers we tested. If you do not do this, you will get errors when you try and
  load the slider.

  The above code should appear inside your <head></head> tags within JavaScript tags. In any case,
  this code MUST appear in the physical page BEFORE you attempt to load the slider.


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>


  IMPLEMENTATION - INSTANTIATING MULTIPLE SLIDER OBJECTS

  This JavaScript library takes an OOP-ish approach to the Slider creation and management.
  The benefit of this to you is that you can have multiple sliders on one page and have
  them operate independantly of one another.

  For each of the sliders, you can specify a completely separate set of properties and access
  their methods individually.

  To have more than one slider on the page, simply instantiate each new slider with a
  different handle name. For example, if I was creating a page where the user could
  view different colours by manipulating a slider for the Red value, a slider for the
  Green value and a slider for the Blue value (RGB, get it?) then I would instantiate
  the objects inside JavaScript tags inside the <head></head> tags of the page like this:


<script language="JavaScript1.2">
<!--
var R_slider = new JSlider('R_slider');
var G_slider = new JSlider('G_slider');
var B_slider = new JSlider('B_slider');
//-->
</script>


  I would now set properties and access methods individusally for each slider simply by
  refering to the handle for the slider in question (R_slider, G_slider, B_slider are the
  object handles).

  Having instantiated the objects, I would then load the sliders down in the page, after
  the opening BODY tag, like this:


<div id="holder" style="position:absolute;top:100px;left:100px;">
<script language="JavaScript1.2">
<!--
R_slider.slider();
//-->
</script>
</div>

<div id="holder" style="position:absolute;top:100px;left:140px;">
<script language="JavaScript1.2">
<!--
G_slider.slider();
//-->
</script>
</div>

<div id="holder" style="position:absolute;top:100px;left:180px;">
<script language="JavaScript1.2">
<!--
B_slider.slider();
//-->
</script>
</div>


  This would layout three sliders, appearing beside each other, because the default
  orientation for sliders is vertical and the DIV tags describe the positioning for them.


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>


  IMPLEMENTATION - INSTANTIATING THE SLIDER OBJECT - LOADING THE SLIDER OBJECT

  Now it is time to place the code on your page that will actually cause the slider to appear.

  This call to load the slider MUST appear between the <body></body> tags and it MUST be contained
  within <DIV></DIV> tags.

  [-- Start Snippet --]

<div id="holder" style="position:absolute;top:100px;left:100px;">
<script language="JavaScript1.2">
<!--
objHandle.slider();
//-->
</script>
</div>

  [--  End  Snippet --]

  Note that this division has CSS positioning attributes. You can change the positioning to
  relative and drop the top and left values and it will flow with the page content. However,
  I strongly recommend you play around with the "top" and "left" values and find the correct
  placement for your slider.

  After adding the code we have talked about in the above three sections and saving your HTML
  file, all you have to do is call it in your browser to see the slider with it's default
  settings.

  VERY IMPORTANT: IT IS RECOMMENDED THAT YOU PLACE THIS METHOD AT THE BOTTOM OF YOUR HTML PAGE
                  SO THAT IT COMES AFTER ANY HTML ELEMENTS THAT IT MAY NEED TO REFERENCE. IT
                  MUST COME BEFORE THE CLOSING BODY TAG.

  At this time, have a look at "JSlider.png" to see important points about the
  layout of the slider that you will need to understand for the following sections.

<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>


  IMPLEMENTATION - SPECIFYING THE SLIDER VALUES AND MOVEMENTS

                   **There are five parts in this section:
                         a.) Overview
                         b.) Minimum / Maximum Value (Value Range)
                         c.) Pixels Per Unit
                         d.) Unit Increments
                         e.) Track Length

  SECTION A: Overview

  The first version of this slider object library simply used the size of the track, in pixels, to determine
  the value that the slider was returning. However, in experimentation and live useage, it was found
  that this was simply not acceptable. The reason was that mouse movements on different systems combined
  with the way different browsers captured those movements were providing inconsistent results. Typically,
  it was found to be impossible to reach minimum and maximum values and value represenation along the
  path was inconsistent from mouse movement to mouse movement.

  Because of this, a great deal of time was invested examining various options. The current method of
  implementation was found to be the most simplistic implementation method that returned accurate
  results in 100% of my tests. As well, the code to the actual tracking and current value calculation
  was able to be reduced by almost 50% which gave a smoother travel to the slider knob and a faster
  response to mouse movements. The vertical slider memory issue in the first version is no longer
  a factor in this implementation.

  The current implementation requires you to make three extra settings and spend a few minutes reading
  and understanding the methodology behind it. The current method gives precision results from the slider
  movement that you can rely on time after time. To facilitate this, I also developed the "Create Slider
  Utility" that gives you a GUI-ish method of creating copy and paste code to get your slider(s) up and
  running.



  SECTION B: Minimum / Maximum Value (Value Range)

  If we have a slider, we obviously want to be able to capture information from it. Therefore
  when we create it, we must have an idea in mind of a range of values that the slider
  can capture values between.

  The default range of the slider is 0 - 100 (zero to one hundred).

  To change the maximum or upper range of the slider, simply assign that value to the
  objects maximum value property:

      objHandle.trackMaxValue = 200;

  The "units" your value represents is irrelevant to the slider object. You can format the
  return value to match your own particualr "units" once the value of the slider has been
  read.

  You can also change this minimum value to suit your needs by assigning the value to the
  objects minimum value property:

      objHandle.trackMinValue = 50;

  **NOTE: At this time the sliders do not support a negative minimum value. This support
          will be added in a later version.

  **NOTE: The value range of the slider will have an impact on the sliders size, as we will
          see in the rest of this section.




  SECTION C: Pixels Per Unit

  In the initial version of this slider, as stated, each pixel of movement was used to calculate a
  unit increment in the value range. However, this did not work due to differences in browsers,
  user screen resolutions and mouse tracking. Therefore, in the current version of the library
  we will specify a value that states how many pixels of movement make up one increment unit in
  the sliders value range.

  It is recommended, based on testing, that you do not go below three (3) pixels for this value.
  While the slider will still move with this property set to one (1), your results will be
  inconsistent and unreliable.

  This Pixels Per Unit value is expressed as an integer, do NOT include the "px" at the end. Here
  is a sample of how you set this value:


        objHandle.pixelsPerUnit = 4;


  **NOTE: The default value for this property is three (3). Therefore, if you are not setting the
          property to a different value, you do not need to include it when creating the object.




  SECTION D: Unit Increments

  The unitIncrements and the unitIncrementsValue are the two properties that now give the slider
  it's precision in returned results.

  There are three kinds of unitIncrements that you can have. They are:

                                              "integer"
                                              "tenths"
                                              "hundredths"

  When you specify a unitIncrements, you must also specify a corresponding unitIncrementsValue. The
  following is your guide to this pairing of settings:

        If the unitIncrements is set to "integer", then the unitIncrementsValue is set to any
        integer (whole number) value from 1 to infinity. i.e.:
                       objHandle.unitIncrements = 'integer';
                       objHandle.unitIncrementsValue = 5;

        If the unitIncrements is set to "tenths", then the unitIncrementsValue is set to any
        one decimal place value greater than zero and less than one. The valid settings would
        therefore be .1, .2, .3, .4, .5, .6, .7, .8, .9. However, due to the practical use
        of the slider, the values you will most commonly use will be .1, .2 and .5. Here is
        an example of the call:
                       objHandle.unitIncrements = 'tenths';
                       objHandle.unitIncrementsValue = .2;

        If the unitIncrements is set to "hundredths", then the unitIncrementsValue is set to
        any two decimal place value greater than zero and less than one. The valid settings
        would be there range .01, .02, .03, .04, .05 ... .96, .97, .98, .99. However, due to
        the practical use of the slider, the values you will most commonly use will be
        .01, .02, .05, .15, .25. Here is an example of the call:
                       objHandle.unitIncrements = 'hundredths';
                       objHandle.unitIncrementsValue = .25;


        ******** IMPORTANT: REMEMBER THAT IF YOU CAN DO IT CHEAPER AS FAR AS PROCESSING
                            GOES, CHEAPER IS BETTER. REMEMBER THAT:


         objHandle.unitIncrements = 'hundredths';    IS THE SAME AS    objHandle.unitIncrements = 'tenths';
         objHandle.unitIncrementsValue = .10;                          objHandle.unitIncrementsValue = .1;
        
         objHandle.unitIncrements = 'hundredths';    IS THE SAME AS    objHandle.unitIncrements = 'tenths';
         objHandle.unitIncrementsValue = .20;                          objHandle.unitIncrementsValue = .2;
        
         objHandle.unitIncrements = 'hundredths';    IS THE SAME AS    objHandle.unitIncrements = 'tenths';
         objHandle.unitIncrementsValue = .50;                          objHandle.unitIncrementsValue = .5;
        
         etc., etc., etc..





  SECTION E: Track Length

  To ensure that the slider permits finite return of precision results, the length of the track of the slider
  in both horizontal and vertical orientation is controlled by a precise formula involving the use of four of
  the above five properties. You can use this formula when desiging your slider to help determine how big it
  will appear on the page OR you can use the "Create Slider Utility" to let you visually see how your changes
  appear on-the-fly. The formula that determines the size of the slider is:

        (((trackMaxValue - trackMinValue) / unitIncrementsValue) x pixelsPerUnit) + (pixelsPerUnit x 2)

  You MUST be aware that in the above formula, the division is rounded up. For example, if the trackMaxValue
  minus the trackMinvalue divided by the unitIncrementsValue returned a result of 1.33333 then it would be
  rounded up to '2'.

  For example, if my trackMaxValue was ten and my trackMinvalue was zero, my unitIncrementsValue was .1 and my
  pixelsPerUnit were five, then the formula to calculate the length of the track would be:

     (((10 - 0) / .1) x 5) + (5 x 2)

     ~or~

     ((10 / .1) x 5) + 10

     ~or~

      (100 x 5) + 10

     So the track length would be 510 pixels.


  Again, you don't need to know the track length to create the slider, however, you can determine it. If you use
  the "Create Slider Utility" then you will instantly see the size changes that you apply through manipulating
  these slider object properties.


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  IMPLEMENTATION - FORCING THE SLIDER VALUE/POSITION

  All sliders automatically load with the slider set to the minimum value of the slider.

  Depending on your use of the slider, you may want it to load on the page at a value
  other than the minimum value. As well, you may want to dynamically trigger the slider
  to move to a specific position depending on other user activity on the page.

  This is done be calling the following method:

        objHandle.valueSet([Unit Value To Set]);

            Unit Value To Set: There are five types of values you can set.

                               a.) You can specify an integer value that falls within the
                                   sliders value range for sliders that have unitIncrements
                                   set to 'integer'.

                               b.) You can specify a floating point value that falls within
                                   the sliders value range for sliders that have unitIncrements
                                   set to 'tenths' or 'hundredths'. This floating point number
                                   must be >= 1.0

                                   Any value LESS then one (1) is read by the library as a
                                   percentage value.

                               c.) You can specify a percentage of the value range by passing
                                   the argument as a floating point number between .01 and
                                   .99.

                               c.) You can set a value of 'min' to force the slider to it's
                                   minimum value position.

                               d.) You can set a value of 'max' to force the slider to it's
                                   maximum value position.

            Here are some example calls to this method:


            objHandle.valueSet(23);     //Integer

            objHandle.valueSet(24.75);  //Floating Point Number

            objHandle.valueSet(.5);     //Set to 50% of value range

            objHandle.valueSet('min');  //Forces to slider minimum value position

            objHandle.valueSet('max');  //Forces slider to maximum value position


  **NOTE: YOU MUST ONLY CALL THIS METHOD AFTER YOU HAVE CALLED THE METHOD slider() TO LOAD
          THE SLIDER. IF YOU CALL IT BEFORE THIS METHOD HAS LOADED THEN YOU WILL RECEIVE
          A JAVASCRIPT ERROR THAT MAY PREVENT THE SLIDER FROM APPEARING ON THE PAGE.



<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  IMPLEMENTATION - DEFINING THE LOOK OF THE TRACK/PATH

  *Please refer to JSlider.png to understand the following.

  From the above image, you can see that there are really three things you should concern
  yourself with when assigning the properties that describe the look of the slider object:

  The TRACK is the dark center portion that the Knob centers itself over.

  The PATH is the coloured area surrounding the TRACK.

  The KNOB is the actual slider that moves along the track.

  TRACK:
    There are two properties that you can set for the track. These are:

      Track Width:  This is not specific to the orientation of the slider. That is, Track Width
                    will always refer to the NARROW axis of the slider. Enter this in a pixels
                    value but WITHOUT the "px" at the end. Enter only an integer value, not a
                    string value. The default value is '3':

                    objHandle.trackWidth = 4;    //This value must NOT be enclosed in quotes

      Track Color:  This is the color of the track itself (not the surrounding path). This can
                    be specified as a Hex value or as a "word" value. The default value
                    is '#000000' :

                    objHandle.trackColor = '#000000';  //This value MUST be enclosed in quotes
                    or
                    objHandle.trackColor = 'Black';    //This value MUST be enclosed in quotes


  ORIENTATION:
    Once the track is defined, we must not forget to tell the object which direction to orient itself.
    The two options are 'vertical' and 'horizontal'. The default orientation is 'vertical'. Simply
    assign a true value to the horizontal property to change the orientation:

                    objHandle.horizontal = 1;


  PATH:

    The path is the coloured area that surrounds the track of the slider. This is, actually, a border
    element to the track element. That gives some flexibility in it's design without worrying about it
    being blown apart from the track itself.

    Path Color:  This is the color that surrounds the track. This can be specified as a Hex value or
                 as a "word" value. The default value is '#FFFCAD' :

                    objHandle.pathColor = '#FF0000'; //This value MUST be enclosed in quotes

    Path Width:  This is how wide the path is on any ONE side of the track. Enter this as an integer
                 expressing a value in pixels. Do NOT include the "px" at the end. Enter only an integer
                 value, not a string value. The default value is '5':

                    objHandle.pathWidth = 6;         //This value must NOT be enclosed in quotes

    Path Style:  This can be any of the normal CSS border styles that can be applied to an HTML
                 element (solid, none, outset, inset, ridge, etc.). Make sure you enclose the value
                 you assign to this property in quotes. The default value is 'solid';

                    objHandle.pathStyle = 'outset';


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  IMPLEMENTATION - DEFINING THE LOOK OF THE KNOB

  *Please refer to JSlider.png to understand the following.

   The KNOB has may properties that you an set to determine it's look and behaviour. To keep it
   all sane we will break it down into four parts:  Sizing, Colouring, Border, Text


  SIZING:
    The x-axis and y-axis require definition. That is, the WIDTH and HEIGHT. These values are
    not specific to the orientation of the slider object. The WIDTH will always be on the x-axis
    as you look at the screen and the HEIGHT will always be on the y-axis as you look at the
    screen no matter what orientation you choose. The default value for both is 20:

                    objHandle.knobWidth = 50;
                    objHandle.knobHeight = 35;

  COLOURING:
     There are three colour aspects for the knob but one of them we will save until the section on
     text. The primary colour consideration is, well, the colour of the knob! There is an option for
     a rollover colour change. This will be covered in the next section. The colour can be specified
     as a Hex value or as a "word" value. The default value is '#F5F5F5':

                    objHandle.knobBGColor = '#CDCDCD';

  BORDER:
     The knob itself can have a border. It is recommended because it visually tricks the eye into
     giving the knob a three dimensional appearance.

     Knob Border Color:  This is the color that surrounds the knob. This can be specified as a Hex
                         value or as a "word" value. The default value is '#A9A9A9' :

                         objHandle.knobBorderColour = '#FF0000'; //This value MUST be enclosed in quotes

     Knob Border Width:  This is how wide the border is on any ONE side of the knob. Enter this as an integer
                         expressing a value in pixels. Do NOT include the "px" at the end. Enter only an
                         integer value, not a string value. The default value is '3':

                         objHandle.knobBorderWidth = 5;         //This value must NOT be enclosed in quotes

     Knob Border Style:  This can be any of the normal CSS border styles that can be applied to an HTML
                         element (solid, none, outset, inset, ridge, etc.). Make sure you enclose the value
                         you assign to this property in quotes. The default value is 'outset';

                         objHandle.knobBorderStyle = 'ridge';


  TEXT:
     You do not need to add text to the Knob. You can have it plain without text. However, adding text
     to the slider knob is quite easy. Keep in mind that the font-size and amount of text may force the
     knob to change it's size dynamically which WILL have an affect on the calculation of the sliders
     value as it is moved. If you are going to add text, make sure you create and test the knob so that it
     is big enough to hold the text BEFORE you add the text. To place text on the knob, simply assign the
     text to the following object property:

                    objHandle.knobText = 'Slide Me!';

     Font Family:  You can specify the font family to be used for the text (default is Tahoma,Sans-Serif):

                    objHandle.knobFontFamily = 'Verdana,Helvetica';


     Font Size;    You can specify the font size to be used for the text (default is 9px)
                   The value is expressed as an integer, do not include the "px":

                    objHandle.knobFontSize = 12;


     Font Colour:  You can specify the colour to be used for the text as a hex or word value (default is #FF0000):

                    objHandle.knobFontColor = '#0000FF';


     Bold Text:    To make the text bold, set the knobs font weight property:

                    objHandle.knobFontWeight = 'bold';


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  IMPLEMENTATION - ROLLOVER EFFECTS

  The following properties have corresponding Rollover (mouseover) properties:

                   trackColor

                   pathColor
                   pathStyle
  
                   knobBGColor
                   knobBorderColor
                   knobBorderStyle

                   knobText
                   knobFontFamily
                   knobFontColor


  The corresponding properties are set in the same way and with the same restrictions as the
  normal state properties. Simply at the word "Rollover" to the property in question. If you
  specify a normal state property but do not specify a Rollover property, the Rollover property
  will inherit it's value from the normal state property:

                   trackColorRollover

                   pathColorRollover
                   pathStyleRollover

                   knobBGColorRollover
                   knobBorderColorRollover
                   knobBorderStyleRollover

                   knobTextRollover          //BE CAREFUL! INCREASING AMOUNT OF TEXT MAY CHANGE KNOBS WIDTH
                   knobFontFamilyRollover                  AND THUS AFFECT THE RETURN VALUES OF THE SLIDER
                   knobFontColorRollover
                   knobFontCSSRollover

<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  IMPLEMENTATION - ROLLOVER EXCLUSIONS

  The following properties DO NOT have a Rollover (mouseover) property available:

                   (Orientation - horizontal or vertical)
                   trackWidth

                   pathWidth

                   knobWidth
                   knobHeight
                   knobBorderWidth

                   knobFontSize
                   knobFontWeight


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  IMPLEMENTATION - USING THE VALUE OF THE SLIDER - 
                   AUTO-REPORTING THE CURRENT VALUE OF THE SLIDER POSITION


  The slider object provides an easy method of automatically returning the value of the
  slider AS IT MOVES. The reporting method is called for every unit of movement within
  the value range.

  This is useful if you want to display the current value of the slider to the user as
  the slider is moved. The valueReport() method will simply update an HTML element
  with the new value for each movement.

  There are three arguments given to this method:

                   objHandle.valueReport('[Element ID]','[Element Type]','[Current Value Format]');

                   an example would be:

                   objHandle.valueReport('showValueField','innerHTML','integer');


  Element ID:   This method uses JavaScripts getElementById() method to access the update
                element. So in the element you want updated with the current value of the
                slider, make sure you use an "id" tag and set this arguments value to the
                identical value of that "id" tag.

  Element Type: There are two types of elements you will be updating. A form field and a
                non-form field. If it is a form field (i.e. text box), then set the value
                of the element type to "value" (case sensitive). If you are updating
                something else, then set the element type to "innerHTML".

  Current Value Format: This method allows you to specify the format of the value that is
                returned in this method (format does NOT affect the value() method, see
                below).

                You can specify one or more formats to be applied to the return value:

                   integer        : Will return the slider value as an integer. That is,
                                    will return the slider value minus any decimal places.

                   decimal x      : Will return the slider value as a floating point number
                                    to "x" decimal places. If the decimal places are LESS
                                    than "x", no padding occurs.

                   padding x      : Will return the value of the slider padded to "x" decimal
                                    places. It will pad the decimals with zero's. If there
                                    are MORE than "x" decimals, it will not shorten the value.

                   paddingLeft x  : This will pad the integer portion of a return value (left
                                    of the decimal place) with zero's to "x" places. This
                                    padding is with zero's. If the integer portion is longer
                                    than "x" places, the integer will not be shortened.

                Examples:

                   objHandle.valueReport('showValueField','innerHTML','decimal 2');
                        :would return a value of 235.3    as 235.30
                        :would return a value of 235.4367 as 235.44 (Yes it rounds up)

                   objHandle.valueReport('showValueField','innerHTML','padding 4');
                        :would return a value of 235.3      as 235.3000
                        :would return a value of 235.699999 as 235.699999

                   objHandle.valueReport('showValueField','innerHTML','integer');
                        :would return a value of 235.37867  as 235
                        :would return a value of 235        as 235

                   objHandle.valueReport('showValueField','innerHTML','paddingLeft 3');
                        :would return a value of 5.69   as 005.69
                        :would return a value of 235.3  as 235.3

                It is important to be aware that you can combine the value formatting options
                in the one statement. The most obvious combination is to conver the slider
                value to a Currency format. A currency format always has TWO decimal places.
                If there is only one decimal place, a zero is added. If there is more than
                two decimal places, the decimals are rounded up to two places. To format the
                slider value as a Currency format, use the decimal and padding combined
                together like this:

                   objHandle.valueReport('showValueField','innerHTML','decimal 2;padding 2;');
                        :would return a value of 5.69    as 5.69
                        :would return a value of 5.6     as 5.60
                        :would return a value of 5.68832 as 5.69

                As you are combining format descriptions, keep in mind that they are evaluated
                left to right. So, if you were to specify "decimal 2;padding 2;integer" then
                you would only get whole numbers and never see a decimal place because the
                final format evaluated is the "integer" which would remove any decimal places.


                **NOTE: If you specify the unitIncrements as "tenths", you will by default
                        have a return value to one decimal place. If you specify the
                        unitIncrements as "hundredths", you will by default have a return
                        value to two decimal places. It is recommended you create your slider
                        and get it running on your web page BEFORE you apply any further
                        return value formatting using the above method.



<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  IMPLEMENTATION - USING THE VALUE OF THE SLIDER - 
                   AUTO NOTIFYING ANOTHER JAVASCRIPT FUNCTION

  Some have said this is one of the most powerful features of the slider object. This is
  the fact that the slider will automatically notify an external JavaScript function
  (a function/method that is NOT part of the object) with the current value of the slider.

  This means you can write your own code and with a few additional lines, the slider will
  automatically update that function without your code specifically querying the object.

  There is a down side to this though. The down side is that this notification fires for
  every pixel of movement of the slider knob. Keep this in mind when you are writing your
  own code. If you have complex code that takes a long time to process, it will cause the
  slider to stutter in it's movement. I guess the best benchmark is your own. Write your
  code, hook it up and test it out.

  There are two things you must do to use the automatic function notification. First is
  that you must turn this reporting feature ON. This is done with a call to the
  valueNotify() method of the slider object:

                   objHandle.valueNotify();

  Alternatively, you can dynamically turn this off and on. To turn the notification OFF
  make a call to this method:

                   objHandle.valueNotifyStop();

  The second thing you must do is creat an external anonymous object that encapsulates your
  code to execute against the slider value that is passed to it. Copy and paste the following
  into the JavaScript tags in the <head></head> tags of your web page:

      [--- Start Snippet ---]
    
      var JSlider_CaptureChange = new Object();
      JSlider_CaptureChange.notify = function() { 
          ...... Your Nifty Code Goes Here ......
      };
    
      [---  End  Snippet ---]

  Now you just replace "...... Your Nifty Code Goes Here ......" BETWEEN THE CURLY BRACES with
  your own processing code. There are THREE arguments passed to this function. They are accessed
  with JavaScripts internal "arguments" array like this:

          arguments[0] Returns the current calculated value of the slider.
          arguments[1] Returns the NAME of the object handle, not the handle itself.
          arguments[2] Returns the slider object handle.


      [--- Start Snippet ---]
    
      var JSlider_CaptureChange = new Object();
      JSlider_CaptureChange.notify = function() {
        if(arguments[0] > someValueHere) {
          document.getElementById('myFieldToShowValue').value = arguments[0];
          window.alert('Slider '+arguments[1]+' has passed the threshold value. Resetting slider');
          arguments[2].valueSet(0);
        }
      };
    
      [---  End  Snippet ---]

  Not very exciting, is it? Au contraire!! The code above receives the new value of slider, the reason
  we put a slider there in the first place. By using the second element, the objects name, we can write
  code to do other stuff based on which slider is reporting (if you have single OR multiple sliders on
  a page). Finally, the object handle being returned means that we can dynamically do stuff TO the slider
  itself using the slider objects properties and methods.

  You can write any code you want between the curly braces. The RECOMMENDED method of doing this
  is to write your own function elsewhere in the <head></head> tags and then have this anonymous
  anonymous objects method call that function and pass the slider value to it.

  Here is the RECOMMENDED and MOST EFFICIENT method of handling the valueNotify option:


      [--- Start Snippet ---]

      function myNiftyFunction(sValue,sName,sHandle) {
        if(sValue > someValueHere) {
          document.getElementById('myFieldToShowValue').value = sValue;
          window.alert('Slider '+sName+' has passed the threshold value. Resetting slider');
          sHandle.valueSet(0);
        }
      }

      var JSlider_CaptureChange = new Object();
      JSlider_CaptureChange.notify = function() { 
          myNiftyFunction(arguments[0],arguments[1],arguments[2]);
      };
    
      [---  End  Snippet ---]


  At any time you can query the slider object to see whether or not it is automatically
  notifying your user defined code with the current slider value. To query the object
  use this method:

  var booleanValue = objHandle.valueNotifyState();

  The method will return a TRUE value if it IS updating automatically. It will return
  a FALSE value if it is NOT updating automatically.


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  IMPLEMENTATION - USING THE VALUE OF THE SLIDER - 
                   QUERY THE CURRENT VALUE OF THE SLIDER POSITION

  A very simple method for accessing the current value of the slider on the track is:

                    var somevar = objHandle.value();   //All sorts of horid surprises await you
                                                       //if you try to use objHandle.value
                                                       //Don't forget the parenthesis!

  Calling this method simply returns the current value, as calculated between the minimum
  and maximum track ranges that you set with the appropriate properties after you
  instantiated the object.

  You can even use this method within other functions of your own. For example:

  function myNiftyTrick () {
    var sliderSays = objHandle.value();
    ..... do something nifty with the variable sliderSays .....
  }

  Just make sure you have loaded the slider BEFORE you try accessing it's current value  ;-))


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  IMPLEMENTATION - LOCKING & UN-LOCKING THE SLIDER

  One feature requested was the ability to dynamically lock and un-lock the slider. This
  would allow the designer to specify that the slider could only be used if certain
  conditions were met by the user.

  Locking and unlocking the slider is done by calls to the required method and can be
  called at any time before or after the object is loaded.

  To lock a slider, prevent it from being moved, call the lock() method:

        objHandle.lock();

  To un-lock a slider, allowing it to be moved again, call the unlock() method:

        objHandle.unlock();

  You can dynamically test the lock condition at any time. The following method
  will return a true value (boolean) if the slider is un-locked and can be moved.
  It will return a false (boolean) value if the slider is locked and can not be
  moved:

        objHandle.unlocked()

  An example of it's use could be:

  if(objHandle.unlocked()) {
    window.alert('You must first DO SOMETHING PERTINENT before you can move the slider');
  }

  **NOTE: The lock() method will NOT prevent you from dynamically setting the slider
          value/position using the valueSet() method discussed above.

  **NOTE: When a slider is locked, there are no rollover effects.


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  FULL PROPERTY & METHOD LIST


  [PROPERTIES - NORMAL "UP" STATE]

  PROPERTY                   Default Value           Notes

  objhandle.horizontal       false
  objhandle.vertical         true

  objhandle.trackWidth       3                       Always the short axis, regardless of orientation
  objhandle.trackColor       #000000                 HEX value OR word value, i.e.: Red

  objhandle.pathWidth        5                       Applied to all sides of the track
  objhandle.pathColor        #FFFCAD                 HEX value OR word value, i.e.: Red
  objhandle.pathStyle        solid                   Options are: none,dotted,dashed,solid,double,groove,ridge,inset,outset
                                                       **There is an option called "hidden". If you use hidden, the border
                                                       will not be seen but the pathWidth value will still have an effect on
                                                       positioning calculations.
  
  objhandle.knobBGColor      #F5F5F5                 HEX value OR word value, i.e.: Red
  objhandle.knobWidth        20                      Specify a value in pixels, expressed as an integer with NO px at the end
  objhandle.knobHeight       20                      Specify a value in pixels, expressed as an integer with NO px at the end
  objhandle.knobBorderWidth  3                       Expressed as an integer
  objhandle.knobBorderColor  #A9A9A9                 HEX value OR word value, i.e.: Red
  objhandle.knobBorderStyle outset                   Typical CSS representation
  objhandle.knobText
  objhandle.knobFontFamily   Tahoma,sans-serif
  objhandle.knobFontSize     9pt                     Specify in any acceptable CSS format:  px, pt, em
  objhandle.knobFontColor    #FF0000                 HEX value OR word value, i.e.: Red
  objhandle.knobFontWeight   normal                  Options are:  normal, bold
  objhandle.knobFontCSS                              Any combination of CSS entities and values. Currently only works
                                                     in Opera but the next version will correct this.

  [PROPERTIES - ROLLOVER STATE]

  PROPERTY                          Default Value           Notes

  objhandle.trackColorRollover                              Inherits from objHandle.trackColor
  objhandle.pathColorRollover       #FFFCAD                 If set to a null value, will inherit from objHandle.pathColor
  objhandle.pathStyleRollover                               Inherits from objHandle.trackStyle
  objhandle.knobBGColorRollover     #CDCDCD                 If set to a null value, will inherit from objHandle.knobBGColor
  objhandle.knobBorderColorRollover #A9A9A9                 HEX value OR word value, i.e.: Red
  objhandle.knobBorderStyleRollover outset                  Typical CSS representation
  objhandle.knobTextRollover
  objhandle.knobFontFamilyRollover  Tahoma,sans-serif
  objhandle.knobFontColorRollover   #FF0000
  objhandle.knobFontCSSRollover                             Any combination of CSS entities and values. Currently only works
                                                            in Opera but the next version will correct this.

  [PROPERTIES - TRACK SETTINGS]

  PROPERTY                   Default Value    Notes

  objhandle.trackMinValue    0                This is the minimum value the track represents, usually zero.
  objhandle.trackMaxValue    100              This is the maximum value the track represents, defaults to 100.
  objHandle.pixelsPerUnit    3                This is the number of pixels in one unit of increment
  objHandle.unitIncrements   'integer'        Values can be 'integer', 'tenths', 'hundredths'
  objHandle.unitIncrementsValue               *** REFER TO THE APPROPRIATE SECTION ABOVE ***



  [METHODS]

  METHOD                ARGUMENTS               EXAMPLE

  objHandle.slider      None                    objHandle.slider();
                        This is the method you must call to load the slider to be displayed on
                        the web page. If you have instantiated multiple slider objects, each
                        object must call this method to be created.

  objHandle.valueSet    'min','max',[integer]   objHandle.valueSet('max');
                                                objHandle.valueSet('min');
                                                objHandle.valueSet(someVariable);
                                                objHandle.valueSet(50);
                        This method will cause the slider to take up position on the track relative
                        to the value passed. Using an argument of 'min' will set the slider to
                        the trackMinValue which is the left end of a horizontal slider or the
                        bottom of a vertical slider. All sliders load with a 'min' setting applied
                        until this method is called.

  objHandle.valueReport [ElementID],            objHandle.valueReport('showLevel','value','integer');
                        [ElementType],          objHandle.valueReport('showCost','innerHTML','decimal 2;padding 2;');
                        [Passed Value Format]   
                                                **For Currency format, use "decimal 2;padding 2;"

  objHandle.value       None                    var sliderSays = objHandle.value();

  objHandle.sliderHide  None                    if(someCondition) { objHandle.sliderHide() }
                        This method was created to allow you to hide a slider until you are ready for it to
                        appear OR remove a slider from view until other conditions are met that make it proper
                        to show it.

  objHandle.sliderUnhide     None               if(someOtherCondition) { objHandle.sliderUnhide() }
                             The corresponding action of the method above. This will return the slider to view.

  objHandle.valueNotify      None               objHandle.valueNotify();
                             Turns on automatic passing of the current slider value to a user defined subroutine.
                             Please read the section in this file in detail regarding use of this method.

  objHandle.valueNotifyStop  None               objHandle.valueNotifyStop();
                             Corresponding OFF switch for the automatic passing of the current slider value.

  objHandle.valueNotifyState None               if( objHandle.valueNotifyState() ) { ... do something ... }
                             Returns a value of TRUE or FALSE to indicate whether user defined code is being
                             automatically updated by the slider object.


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  CREATE SLIDER UTILITY


  The object oriented approach to slider creation takes all the guesswork and programming
  out of your hands. You simply need to call a few methods and set a few properties. Still,
  given the number of properties and methods available, this could get a bit confusing.

  To further make this a valuable and EASY TO USE library, I have created a functional tool
  that you can use for an even faster GUI-ish approach to defining your slider.

  In the zip file is an HTML document called "create_slider.html". Simply open this up in
  your browser and follow the cues to inut the settings and specifications to generate
  your slider.

  NOTE: While the sliders themselves work in Opera, IE, Firefox and Netscape, this utility
        file has coding that requires you use either Opera or IE for the utility page.


  NAME THE SLIDER:
    When you first call the page in your browser, you are presented with a box to enter a
    name for the slider. Because all slider objects require a handle AND because you can
    have more than one slider on a page, enter any name you want and your code will be
    generated with the properly named handle in place where it is required.

    Once you have entered a name (avoid non alpha-numeric characters), click the button
    that corresponds to the orientation you want for this particular slider (horizontal
    or vertical).

  KNOB CONTROLS: 
    The Knob Controls section is where you set the sizing, colour, look and Rollover effects
    for the slider knob.

  TRACK CONTROLS:
    The track controls section is where you set the sizing, colour, look and Rollover effects
    for the track the slider rests on and the path that surrounds it.

  COMPUTING INSTRUCTIONS:
    This is where you specify the items (discussed further above) that describe how the
    slider interprets units of movements and ultimately, the sliders size.

  After you have made modifiations within ANY of these sections, make sure you click on the
  button titled "Modify Knob", "Modify Track" or "Modify Functionality & Code".

  After you have the slider looking, behaving and computing the way you want it to, make
  sure you scroll down to the "Copy & Past Code Window". All the changes you have made will
  be reflectd in this code. You can then simply copy and paste it into the appropriate areas
  of the HTML document you are creating.

  If at anytime you want to start over again, click the "Refresh" button of your browser.

  If you want to copy and paste code from the actual document, use one of the example files
  to copy and paste code from. The "create_slider.html" document has a lot of conditional
  and jury-rigged functionality that will not be appropriate for your own application of
  the slider object.


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>



  SAMPLES OF INSTANTION, PROPERTY ASSIGNMENT AND WORKING SLIDERS

  Extract all the files from this archive and store them in the same folder on your computer.

  Using your browser open any of the following files in the browser of your choice:

  example_single_slider.html

  example_mutli_sliders.html

  example_slider_value_notify.html

  example_slider_designs.html

  create_slider.html

  After seeing how they work, you can then view the source code to examine the
  object instantiation, property settings and method useage.


<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  DEBUGGING

  This object library has been tested extensively in Opera 9.0, IE6.0, Firefox 1.5 and
  Netscape 8.0. If you call your page and encounter problems with the slider appearing
  or the sliders operation, then the following suggestions will help you find the
  problem.

  >> Check all methods that are called. All methods MUST end in parenthesis whether or not
     arguments are passed to it. For example:

     var something = objHandle.value;

     This will not crash the JavaScript but it will return a string of code rather than
     the slider value. Write the method objHandle.value() and all will be well in the world.

  >> Arguments improperly assigned for their native type. What this means is that if you
     are passing an argument as an integer, you can just type the value. If you are passing
     an argument that is a string, you must enclose that in quotes. If you are passing an
     argument as a variable, you must NOT enclose it in quotes. Here are some examples:

     objHandle.valueSet(min);   //This is VERY bad. JavaScript will crash in the page.
     objHandle.valueSet('min'); //Martha says, "This is a very good thing"
     objHandle.valueSet('50');  //Workable, but not ideal
     objHandle.valueSet(50);    //Martha just launched a new magazine with your name! (Good)

     var valueFromSomewhere = 125;
     objHandle.valueSet('valueFromSomewhere'); //This is VERY bad. Javascript might crash but
                                                 either way, the slider object will just look
                                                 at your funny and not do anything useful.

     var valueFromSomewhere = 125;
     objHandle.valueSet(valueFromSomewhere);   // You Da Man!

  >> Properties improperly assigned for the values native type. You will only assign two of
     JavaScripts native types. They will be either "number" or "string". If you are assigning
     a NUMBER, you must NOT enclose it in quotes. If you are assigning a STRING then you MUST
     enclose it in quotes.

     Basically, if the value are assigning contains only digits (0 to 9) then it is a number.
     ANYTHING ELSE is a string. Here are some Rush Limbaugh approved examples:

     objHandle.knobBGColor = Red;           BAD - JavaScript crashes in the page.
     objHandle.knobBGColor = 'Red';         Good

     objHandle.knobBGColor = #FF0000;       BAD - JavaScript crashes in the page.
     objHandle.knobBGColor = '#FF0000';     Good

     var someColour = 'Red';
     objHandle.knobBGColor = 'someColour';  Not so good - JavaScript does not crash, colour does not change to Red.

     var someColour = 'Red';
     objHandle.knobBGColor = someColour;    Good

     objHandle.knobWidth = '50';            Not so bad.
     objHandle.knobWidth = 50;              Best.

     var this_sliders_width = 50;
     objHandle.knobWidth = 'this_sliders_width';    Bad - Javascript will not crash, not quite sure what the knob will do.

     var this_sliders_width = 50;
     objHandle.knobWidth = this_sliders_width;      Perfect


  >> Typos are easy. If you have assigned a property or argument correctly according to it's native type
     then your next check should be that you have typed all property and method names correctly. It's 
     easy to overlook. What I recommend (and this works) is to start at the bottom of the list of properties
     you have typed and work you way upwards, reading each property name backwards (from right to left). This
     will help make typo's jump out at you.

  >> Wrong object handle used. When you have more than one slider object on a page. It is quite easy to
     use the wrong object handle when setting a property or calling a method. Check your object handle name
     for the correct name AND for typo's while you are checkign your spelling on the properties and methods.

  >> Browser Version. If you are using Internet Explorer 5.0, that is probably the cause of the problems.
     Update your version of IE and try again.

  >> Locating the slider() method. If all else fails, make sure you put this call to load the slider object
     at the very bottom of your HTML page, just BEFORE the closing </body> tag.



<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

  SUPPORT

  If you have run some debugging, are not using Internet Explorer 5.0 and have a headache
  from beating your head on the wall, you can contact me for assistance. I will require
  that you send me the page you are using the slider object on as well as any other
  CSS or JS files needed for the page (unless you link to them with a full URL in the
  page).

  Once I have rectified the problem, I will notify you. Payment of $40 per hour (one hour
  minimum ) is required before the solution will be released. In almost all cases, the
  solution will be within that hour.

  If I am not able to find a solution for what you are encountering then you will be
  notified and YOU WILL NOT OWE ME ANYTHING. I do not accept any payment unless I can
  provide a working solution.

  Payment of the commercial application fee entitles you to e-mail support in getting
  your first slider set up and loaded on your page.

  PLEASE CONTACT ME AT:      james_melanson@yahoo.ca

  Feature Requests:

  If your support issue is because a feature does not exist that you need, I will not
  support that issue. There are several features I plan to implement in future
  versions, however, they are not available at this time. You can contact me to see
  if that feature is available yet, I'm always happy to answer an email.

  Upcoming Features List:

              -Inverted value range on vertical sliders (Min value at the top end of the Y-axis)

              -Reverse value range on horizontal sliders (Min value range at the right end of the X-axis)

              -Negative value support. Right now assignign a negative min value is the same as assigning ZERO.

              -Two slider knobs on one track that automatically re-position each other.

              -Knob Lock. The ability for a user to lock a knob so it doesn't accidentally get moved.

              ***If you have a feature you would like to see added, let me know!



<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>

