JavaScript Slider Weight Control

By Robbe D. Morris

Printer Friendly Version

Robbe Morris
Robbe & Melisa Morris
  Download Source Code
Recently, I was asked to create a custom slider control for a web based research tool accessed by visitors using Internet Explorer 5.5 and above.  The control needed to be 100% client side in order to support custom UI characteristics not included in this code sample.  This particular control also needed to support two types of slider math options: Percent Range and Score (1-9) Range.  The percentage math option should automatically redistribute weights to the other slider bars.  The Score math option should not.


In order to make the slider more user friendly, I've added the ability to lock slider bars to keep them from being moved by the selection of other slider bars.  This feature also needed to automatically adjust the weight redistribution calculations to not include locked items.
The demonstration below shows both math options.  Simply click the desired link below the slider to view the four test groups I've put together for you.
The slider is made up of 4 JavaScript files: SliderWeights.js, SliderDraw.js, SliderGlobals.js, and SliderMath.js.  The slider UI works on a relatively simple premise.  A master SliderArray which contains individual arrays for each slider bar.  At a minimum, the slider bar arrays will contain a unique key, element name, weight, display boolean, and math option.  If necessary, elements can be added to the slider bar array without breaking the existing slider code.  The following is a break down of these files and how they are used:
 
1SliderGlobals.js: contains the global variable definitions for the Slider.  Settings such as slider bar color, button color, button down color, slider size, etc...are defined here.
2SliderDraw.js: contains the code necessary to redraw the slider based on the display boolean value for each slider bar.  I've included a test JavaScript file called SliderTest.js that shows how to change the display boolean value of certain slider bars dynamically based on user selection.  This test file is not needed in your implementation of the slider.  SliderDraw.js requires that the HTML page that holds the slider control contain two DIV tags: SliderHiddenElements and SliderTable.  SliderHiddenElements contains hidden INPUT tags to store the weights from the slider for posting the values back to the web server.  SliderTable contains the HTML for the slider itself within it's .innerHTML property.
3SliderWeights.js: contains the code to adjust the weights and slider widths as well as the event registrations.  The displayed weight is rounded to one decimal point.  However, the actual weight without rounding is stored in the array elements and hidden form elements.
4SliderMath.js: contains the code to calculate slider width based on weight, weight based on slider width, redistribute weights, and number rounding.
As part of the demo, I've also put together Default.htm as a sample HTML page that demonstrates how to build the master SliderArray along with the two required DIV tag references: SliderHiddenElements and SliderTable.  Take notice of the BODY onLoad event as well as the test links.  They'll show you how to redraw the slider based on user selection.
This source code has been made available for your use in both commercial and non-commercial applications free of charge.  However, you are not free to repackage the source code and sell it as an individual user control or part of a package of user controls.
 
Default.htm
   
<HTML>
   <HEAD>
    <META HTTP-EQUIV='Pragma' CONTENT='no-cache'>
    <META HTTP-EQUIV='Expires' CONTENT='0'>
    <META http-equiv='Cache-Control' content='no-cache'>
    <TITLE>NullSkull.com Slider Control By Robbe D. Morris</TITLE>

<script language=JavaScript src=SliderGlobals.js></script>
<script language=JavaScript src=SliderDraw.js></script>
<script language=JavaScript src=SliderWeights.js></script>
<script language=JavaScript src=SliderMath.js></script>
<script language=JavaScript src=SliderTest.js></script>


<script language=JavaScript>

         //  Element array constants used to identify positions in the array

        
       var idxSliderDisplayKey=0;
       var idxSliderDisplayName=1;
       var idxSliderDisplay=2;
       var idxSliderDisplayWeight=3;
         var idxSliderMathType=4
      

         var SliderArrays = new Array();

         SliderArrays[0] = new Array ('1000','Element 0',false,'15.7',SliderMathTypePercent); 
         SliderArrays[1] = new Array ('1001','Element 1',false,'20.0',SliderMathTypePercent);                        
         SliderArrays[2] = new Array ('1002','Element 2',false,'19.4',SliderMathTypePercent); 
         SliderArrays[3] = new Array ('1003','Element 3',false,'5.2',SliderMathTypePercent); 
         SliderArrays[4] = new Array ('1004','Element 4',false,'20.5',SliderMathTypePercent); 
         SliderArrays[5] = new Array ('1005','Element 5',false,'8.7',SliderMathTypePercent); 
         SliderArrays[6] = new Array ('1006','Element 6',false,'10.2',SliderMathTypePercent); 
         SliderArrays[7] = new Array ('1007','Element 7',false,'4.0',SliderMathTypeScore); 
         SliderArrays[8] = new Array ('1008','Element 8',false,'7.0',SliderMathTypeScore); 
         SliderArrays[9] = new Array ('1009','Element 9',false,'5.0',SliderMathTypeScore); 
         SliderArrays[10] = new Array ('1010','Element 10',false,'3.4',SliderMathTypeScore); 
         SliderArrays[11] = new Array ('1011','Element 11',false,'10.0',SliderMathTypePercent); 
         SliderArrays[12] = new Array ('1012','Element 12',false,'10.0',SliderMathTypePercent); 
         SliderArrays[13] = new Array ('1013','Element 13',false,'10.0',SliderMathTypePercent); 
         SliderArrays[14] = new Array ('1014','Element 14',false,'10.0',SliderMathTypePercent); 
         SliderArrays[15] = new Array ('1015','Element 15',false,'10.0',SliderMathTypePercent); 
         SliderArrays[16] = new Array ('1016','Element 16',false,'10.0',SliderMathTypePercent); 
         SliderArrays[17] = new Array ('1017','Element 17',false,'10.0',SliderMathTypePercent); 
         SliderArrays[18] = new Array ('1018','Element 18',false,'10.0',SliderMathTypePercent); 
         SliderArrays[19] = new Array ('1019','Element 19',false,'10.0',SliderMathTypePercent); 
         SliderArrays[20] = new Array ('1020','Element 20',false,'10.0',SliderMathTypePercent); 
         SliderArrays[21] = new Array ('1021','Element 21',false,'2.5',SliderMathTypeScore); 
         SliderArrays[22] = new Array ('1022','Element 22',false,'2.5',SliderMathTypeScore); 
         SliderArrays[23] = new Array ('1023','Element 23',false,'2.5',SliderMathTypeScore); 
         SliderArrays[24] = new Array ('1024','Element 24',false,'2.5',SliderMathTypeScore); 
         SliderArrays[25] = new Array ('1025','Element 25',false,'2.5',SliderMathTypeScore); 
         SliderArrays[26] = new Array ('1026','Element 26',false,'9.0',SliderMathTypeScore); 
         SliderArrays[27] = new Array ('1027','Element 27',false,'2.5',SliderMathTypeScore); 
         SliderArrays[28] = new Array ('1028','Element 28',false,'2.5',SliderMathTypeScore); 
         SliderArrays[29] = new Array ('1029','Element 29',false,'2.5',SliderMathTypeScore); 
         SliderArrays[30] = new Array ('1030','Element 30',false,'2.5',SliderMathTypeScore); 

</script>
   
<style>
.BodyHeader { font-family:verdana,arial,helvetica;sans-serif;color:#000000;
              font-size:16px;font-weight:normal;text-decoration:none;
              font-style:normal; }
.BodyHeader2 { font-family:verdana,arial,helvetica;sans-serif; color:#000000;
               font-size:10px;font-weight:normal;text-decoration:none; 
               font-style:normal; }
.BodyLink {    font-family:verdana,arial,helvetica;sans-serif; color:#5D7BBA;
               font-size:10px;font-weight:normal;text-decoration:underline;
               font-style:normal; }
</style>

  </HEAD>

<BODY onload="SliderWriteInputs();SliderTest(1);" >
 
 <table border="0" align="center">
   <tr><td align="center" class=BodyHeader>NullSkull.com Slider Demo</td></tr>
   <tr><td align="center" class=BodyHeader2>By Robbe D. Morris</td></tr>
   <tr><td align="center"> </td></tr>
   
   <tr><td><div id=SliderTable name=SliderTable > </div> </td></tr>
   <tr><td align="center"><Br></td></tr>
   <tr><td align="center">
    <a href=javascript:SliderTest(1); class=BodyLink>Percentage Example 1</a>
       <a href=javascript:SliderTest(2); class=BodyLink>Score Example 1</a>
    </td></tr>
 <tr><td align="center">
   <a href=javascript:SliderTest(3); class=BodyLink >Percentage Example 2</a>
      <a href=javascript:SliderTest(4); class=BodyLink>Score Example 2</a>
  </td></tr>
 </table>
   
 <div id=SliderHiddenElements name=SliderHiddenElements ></div>
</BODY>
</HTML>

SliderTest.js
   
 
 
 function SliderTest(nTest)
  {

      var oSliderRow;
      var lArrayLength=0;
      var lLoop=0;
      var lFoundCnt=0;
 
   try
   {

     lArrayLength = SliderArrays.length;
 
     if (lArrayLength < 1) { return false; }
 
     for (lLoop=0; lLoop<lArrayLength; lLoop++)
     {
		  
       oSliderRow = SliderArrays[lLoop];
       oSliderRow[idxSliderDisplay] = false;   
           
       switch (nTest)
       {

         case 1 :
    
           if ((lLoop >=0) && (lLoop <=6))                                                
           { oSliderRow[idxSliderDisplay] = true;  }
           break;

         case 2 :

           if ((lLoop >6) && (lLoop <=10))                                             
           { oSliderRow[idxSliderDisplay] = true;  }
                                        
           break;

         case 3 :

  
           if ((lLoop >10) && (lLoop <=20))                                      
           {oSliderRow[idxSliderDisplay] = true;  }
                                        
           break;

          case 4 :

   
             if ((lLoop >20) && (lLoop <=30))                                    
            {oSliderRow[idxSliderDisplay] = true;  }
                                        
            break;
         
        }

        SliderArrays[lLoop] = oSliderRow;

      }

    }
    catch (exception) 
    { 
        if (exception.description == null) { alert("Test Error: " + exception.message); }  
         else {  alert("Test Error: " + exception.description); }
             }
	 
        SliderDrawTable();
      }

SliderDraw.js
   
 

 function SliderDrawTable()
  {

      
     var sSliderName='';
     var sSliderImgDiv='';
     var sSliderLock='';
     var sSliderWgt='';
     var sH='';
     var Idx=0;
     var lArrayLength=0;
     var lLoop=0;
     var lFoundCnt=0;
     var oSliderRow;
     var nWidth=0;
     var nWeight=0;
     var nOffSet=0;
     var sS='';
     var oInp() = new Array();

    // Use oInp JavaScript array to drastically improve string concatenation.

     var sS='BORDER-RIGHT: 0px inset ' + SliderBarColor;   
           sS+=' ;BORDER-LEFT: 0px inset ' + SliderBarColor;
           sS+=' ;BORDER-TOP: 0px inset ' + SliderBarColor;
           sS+=' ;BORDER-BOTTOM: 0px outset ' + SliderBarColor;

      sSliderBarBorder = sS;

      var sS='BORDER-RIGHT: 0px outset ' + SliderBarKnobColor;
            sS+=' ;BORDER-LEFT: 0px outset ' + SliderBarKnobColor;
            sS+=' ;BORDER-TOP: 0px outset ' + SliderBarKnobColor;
            sS+=' ;BORDER-BOTTOM: 0px outset ' + SliderBarKnobColor;

      sSliderKnobBorder = sS;

      var sS='font-family:verdana,arial,helvetica;sans-serif color:#000000;';
           sS+=' font-size:12px;align="right"; BORDER-RIGHT: 0px outset #5D7BBA;';
           sS+=' BORDER-LEFT: 0px outset #5D7BBA; BORDER-TOP: 0px outset #5D7BBA;';
           sS+=' BORDER-BOTTOM: 0px outset #5D7BBA; text-align: RIGHT;';
           sS+=' BACKGROUND-COLOR:#FFFFFF;height:20px;';
      
      sSliderWeightStyle = sS;

      var sS='font-family:verdana,arial,helvetica;sans-serif color:#000000;';
           sS+=' font-size:12px; text-decoration:none; font-style:bold; background-color:#FFFFFF; ';
      
      sSliderNameStyle = sS;

      var sS='font-family:verdana,arial,helvetica;sans-serif color:#000000;';
           sS+=' font-size:10px; text-decoration:none; font-style:bold; background-color:#FFFFFF; ';
      sSliderNameStyle=sS;
      var oSlider = document.getElementById('SliderTable');
      var oSliderDIV;
 
    try
    {

 
        lArrayLength = SliderArrays.length;

    	if (lArrayLength < 1) { return false; }
 
        oInp.push('<table border="0" align="left" width=' + SliderTableWidth + ' cellpadding=0 cellspacing="2" >');
 
 
       for (lLoop=0; lLoop<lArrayLength; lLoop++)
       {
		  
           oSliderRow = SliderArrays[lLoop];
           Idx = lLoop;
  
           if (oSliderRow[idxSliderDisplay] == true)
            {
       
               lFoundCnt +=1;

               sSliderName = 'id=divSlider_' + Idx + ' name=divSlider_' + Idx;
               sSliderKnob = 'id=imgSliderKnob_' + Idx + ' name=imgSliderKnob_' + Idx;
               sSliderWgt = 'id=txtSliderWeight_' + Idx + ' name=txtSliderWeight_' + Idx;
               sSliderLock ='id=imgSliderLock_' + Idx + ' name=imgSliderLock_' + Idx;
   
 oInp.push('<tr>');
 oInp.push('<td align="center" valign=middle  >');
 oInp.push('<a href=# onclick=SliderLockClick("' + Idx + '");>');
 oInp.push('<img ' + sSliderLock + ' src=images/Slider_Open.jpg border="0" align=middle valign=middle></a>');
 oInp.push('</td>');
 oInp.push('<td align="left" valign=middle nowrap width=125 style="' + sSliderNameStyle + '">'
              + oSliderRow[idxSliderDisplayName] + ' </td>');
 oInp.push('<td align="left" valign="top"  width=' + SliderTableTDWidth + ' height=20 id=tblSlider1 name=tblSlider1 nowrap>');
 oInp.push('<div ' + sSliderName + ' style="' + sSliderBarBorder + ';position:relative;left:0px;top:0px;height:20;';
 oInp.push(' width:0;valign:top;BACKGROUND-COLOR:' + SliderBarColor + ';">)';
 oInp.push('<div ' + sSliderKnob + ' style="' + sSliderKnobBorder + ';position:relative;left:0px;top:0px;height:100%;';
 oInp.push(' width:20;BACKGROUND-COLOR:' + SliderBarKnobColor + ';"></div>');
 oInp.push('</div></td>');
 oInp.push('<td align="right"><input ' + sSliderWgt + ' type=text value="0.00" READONLY size=6 maxlength=30');
 oInp.push(' style="' + sSliderWeightStyle + '" ></td>');
 oInp.push('</tr>');
 
              SliderMathOption = oSliderRow[idxSliderMathType];

            }
          }

             oInp.push('<tr><td align="center" colspan="2"> </td><td align="center" style="'
			             + sSliderInsStyle + '"><b>');

             if (SliderMathOption == SliderMathTypePercent) { oInp.push('Use Slider To Adjust Percentages'); }
	         if (SliderMathOption == SliderMathTypeScore) { oInp.push('Use Slider To Adjust Scores (1-9)'); }
  
	          oInp.push('</b></td><td> </td></tr>';
           oInp.push('</table>';
      
           sH = oInp.join(' ');
             oSlider.innerHTML=sH;

            for (lLoop=0; lLoop<lArrayLength; lLoop++)
            {
		  
               oSliderRow = SliderArrays[lLoop];
               Idx = lLoop;
           
               if (oSliderRow[idxSliderDisplay] == true)
               {
       
                  lFoundCnt +=1;
                  oSliderDIV = document.getElementById('divSlider_' + Idx);

                  nWidth = SliderConvertWeightToWidth(oSliderRow[idxSliderDisplayWeight]); 
			               
                  if ((nWidth > SliderMaxWidth) || (nWidth < 0)) 
                  { 
                    nWidth = 0; 
                    nWeight = SliderConvertWidthToWeight(nWidth);
                   }
                  else { nWeight = oSliderRow[idxSliderDisplayWeight]; }
                
          
                  oSliderDIV.style.width=nWidth;
			  
                  nOffSet = parseFloat(oSliderDIV.style.pixelLeft) + parseFloat(oSliderDIV.style.width);
				  
                  if (nWidth == 0) { nOffSet = nOffSet + 1; }

                  document.getElementById("imgSliderKnob_" + Idx).style.pixelLeft = nOffSet;
               
                  document.getElementById("txtSliderWeight_" + Idx).value = SliderRoundNumber(nWeight,"1");
              
                 }
	        }

	      }
	       catch (exception) 
		  { 
		     if (exception.description == null) { alert("Slider Draw Error: " + exception.message); }  
		     else {  alert("Slider Draw Error: " + exception.description); }
		  }
  }


   function SliderWriteInputs()
  {

      var sSliderName='';
      var lArrayLength=0;
      var lLoop=0;
      var sH='';
      var oSliderRow;
      var oInp = new Array();

    try
   {

        var oSlider = document.getElementById('SliderHiddenElements');
  
        lArrayLength = SliderArrays.length;

    	if (lArrayLength < 1) { return false; }
 
        for (lLoop=0; lLoop<lArrayLength; lLoop++)
       {
		  
           oSliderRow = SliderArrays[lLoop]; 
           
           sSliderName = 'id=savSlider_' + oSliderRow[idxSliderDisplayKey]  +
		                     ' name=savSlider_' + oSliderRow[idxSliderDisplayKey] ;  

           oInp.push('<input ' + sSliderName + ' type=hidden value="' 
		                  + oSliderRow[idxSliderDisplayWeight] + '" size=10 maxlength=30 size=10>'); 
	 
        }
         
        sH = oInp.join(' ');
        oSlider.innerHTML=sH;
	 
  } 
    catch (exception) 
    { 
      if (exception.description == null) { alert("Slider Hidden Elements: " + exception.message); }  
      else {  alert("Slider Hidden Elements: " + exception.description); }
    }
  }

 
</pre></td></tr>

<tr><td align="left" colspan="2" class="clsBodyText"><b>SliderWeights</b></td></tr>
<tr><td align="left" colspan="2"><pre class="PreSourceCode">   
 

 function SliderLockClick(nItem)
   {
     
      var oCurImg = document.getElementById('imgSliderLock_' + nItem);

      if (oCurImg.src.indexOf('Slider_Locked') > 0) { oCurImg.src = imgSliderOpen.src;  return true; }
      else { oCurImg.src = imgSliderLocked.src; return true; }
 
      return true;
   }

   function SliderIsLocked(nItem)
   {
      var oCurImg = document.getElementById('imgSliderLock_' + nItem);
      if (oCurImg.src.indexOf('Slider_Locked') > 0) { return true; }
      return false;
   }



   function SliderButtonDown(Idx)
    {
	  try { document.getElementById("imgSliderKnob_" + Idx).style.backgroundColor = SliderBarKnobDownColor;  }
	  catch (e) {}
    }

  function SliderButtonUp(Idx)
  {
      try { document.getElementById("imgSliderKnob_" + Idx).style.backgroundColor = SliderBarKnobColor; }
	  catch (e) {}
  }


    function SliderGrabElement()
   { 

        SliderCurrentElement = event.srcElement; 
        while (SliderCurrentElement.id.indexOf("imgSliderKnob") == -1) 
        { 
            SliderCurrentElement = SliderCurrentElement.parentElement; 
            if (SliderCurrentElement == null) { return } 
         } 
        if (SliderCurrentElement !=  SliderActiveElement) {  SliderActiveElement = SliderCurrentElement;  } 
        SliderCurrentX = (event.clientX + document.body.scrollLeft); 
 
        SliderCurrentIdx = SliderGetNameIndex(SliderCurrentElement.id);
        SliderButtonDown(SliderCurrentIdx);
     
    } 

   function SliderGetNameIndex(sName)
    {
		 
        var oElement = document.getElementById(sName);
        var nNameLength = oElement.id.length;
        var nNameStart = parseFloat(oElement.id.indexOf("_")) + 1;
	 
        return oElement.id.substr(nNameStart, nNameLength - nNameStart);
	}


    function SliderMoveCurrentElement()
   {  
        if (SliderCurrentElement == null) {return; } 

        newX = (event.clientX + document.body.scrollLeft); 
        nDistanceX = (newX - SliderCurrentX); 
        SliderCurrentX = newX; 
        
        var nWeight='0.00';
        var oSliderRow;
        var nTmpDistance;
        var oSliderKnob = document.getElementById("imgSliderKnob_" + SliderCurrentIdx);
        var oSliderBar = document.getElementById("divSlider_" + SliderCurrentIdx);
        
	   try
       {

        if (SliderIsLocked(SliderCurrentIdx) == true) { return false; }
        if (SliderCheckLockedItems() == false) { return false; }

        var nSliderKnobOffSet = parseFloat(oSliderKnob.style.pixelLeft);
        var nSliderOffSet = parseFloat(oSliderBar.style.pixelLeft);
    
	    oSliderRow = SliderArrays[SliderCurrentIdx];

        if (nSliderKnobOffSet >= 1) 
       {
          
           if (nSliderKnobOffSet < SliderMaxWidth + SliderMaxBuffer)
           {
			  
                  nDistance = oSliderKnob.style.pixelLeft + nDistanceX;
                  nWeight = SliderConvertWidthToWeight(nDistance);
                  oSliderKnob.style.pixelLeft = nDistance; 
                  oSliderBar.style.width = parseFloat(oSliderKnob.offsetLeft); 
                  document.getElementById("txtSliderWeight_" +
				                     SliderCurrentIdx).value = SliderRoundNumber(nWeight,"1");
                  oSliderRow[idxSliderDisplayWeight] = nWeight;
                  SliderArrays[SliderCurrentIdx] = oSliderRow;
                  if (SliderSetOtherSliders() == true) { SliderMoveOtherSliders(); }
                  return false;
           }
       else
           {
		         
                  nWeight = SliderConvertWidthToWeight(SliderMaxWidth);
                  oSliderBar.style.width = SliderMaxWidth;
                  oSliderKnob.style.pixelLeft = nSliderOffSet + parseFloat(oSliderBar.style.width); 
                  document.getElementById("txtSliderWeight_" + SliderCurrentIdx).value = SliderRoundNumber(nWeight,"1");
                  oSliderRow[idxSliderDisplayWeight] = nWeight;
                  SliderArrays[SliderCurrentIdx] = oSliderRow; 
                  SliderDropElement();
                  if (SliderSetOtherSliders() == true) { SliderMoveOtherSliders(); }
                  return false;
            }
        }
        else
         {
             nWeight = SliderConvertWidthToWeight(1);
             oSliderBar.style.width = 1;
             oSliderKnob.style.pixelLeft = nSliderOffSet + 1;
             document.getElementById("txtSliderWeight_" + SliderCurrentIdx).value = SliderRoundNumber(nWeight,"1");
             oSliderRow[idxSliderDisplayWeight] = nWeight;
             SliderArrays[SliderCurrentIdx] = oSliderRow;
             if (SliderSetOtherSliders() == true) { SliderMoveOtherSliders(); }
			 
          }
           event.returnValue = false; 
        }
        catch (e) { event.returnValue=false;} 

    } 

 




  
 
   function SliderMoveOtherSliders()
   {

      var Idx=0;
      var lArrayLength=0;
      var lLoop=0;
      var lFoundCnt=0;
      var oSliderRow;
      var nWidth=0;
      var nWeight=0;
      var nOffSet=0;
      var oSliderDIV;
      var lTotal=0;

      try
	   {

           if (SliderMathOption != SliderMathTypePercent) { return true; }
           lArrayLength = SliderArrays.length;
           if (lArrayLength < 1) { return false; }

           for (lLoop=0; lLoop<lArrayLength; lLoop++)
            {
		  
               oSliderRow = SliderArrays[lLoop];
               Idx = lLoop;
           
               if (oSliderRow[idxSliderDisplay] == true)
               {
       
                  oSliderDIV = document.getElementById('divSlider_' + Idx);
                  lFoundCnt +=1;

                  nWidth = SliderConvertWeightToWidth(oSliderRow[idxSliderDisplayWeight]); 
	               
                  if ((nWidth > SliderMaxWidth) || (nWidth < 0)) 
				  {  nWidth = 0; nWeight = SliderConvertWidthToWeight(nWidth);   }
                  else { nWeight = oSliderRow[idxSliderDisplayWeight]; }
                
                  oSliderDIV.style.width=nWidth;
			  
                  nOffSet = parseFloat(oSliderDIV.style.pixelLeft) + parseFloat(oSliderDIV.style.width);
				  
                  if (nWidth == 0) { nOffSet = nOffSet + 1; }

                  document.getElementById("imgSliderKnob_" + Idx).style.pixelLeft = nOffSet;
                 
                  document.getElementById("txtSliderWeight_" + Idx).value = SliderRoundNumber(nWeight,"1");
                  lTotal += nWeight;
              
                 }
	        }
        
	      }
	       catch (exception) 
		  { 
		     if (exception.description == null) { alert("SliderMoveOtherSliders: " + exception.message); }  
		     else {  alert("SliderMoveOtherSliders: " + exception.description); }
		  }




   }
 


   function SliderCheckLockedItems()
   {

      var lArrayLength=0;
      var lLoop=0;
      var lFoundCnt=0;

      try
	   {

           if (SliderMathOption != SliderMathTypePercent) { return true; }
           lArrayLength = SliderArrays.length;
           if (lArrayLength < 1) { return false; }

           for (lLoop=0; lLoop<lArrayLength; lLoop++)
            {

               oSliderRow = SliderArrays[lLoop];
              
               if (oSliderRow[idxSliderDisplay] == true)
               {
                  if (SliderIsLocked(lLoop) == false) {  lFoundCnt += 1;  }
                }

            }

	   }
        catch (exception) 
        { 
          if (exception.description == null) { alert("SliderCheckLockedItems: " + exception.message); }  
          else {  alert("SliderCheckLockedItems: " + exception.description); }
         }
          
         if (lFoundCnt >1) { return true; }

        return false;
   }

   
 
   function SliderSaveElements()
   {

      var lArrayLength=0;
      var lLoop=0;
      var oSliderRow;
      var sKey;
 
   
      try
	  {

        lArrayLength = SliderArrays.length;

    	if (lArrayLength < 1) { return false; }
 
        for (lLoop=0; lLoop<lArrayLength; lLoop++)
       {
		  
           oSliderRow = SliderArrays[lLoop];
    
           if (oSliderRow[idxSliderDisplay] == true)
            {
               oSliderRow[idxSliderDisplayWeight] = document.getElementById("txtSliderWeight_" + lLoop).value;
               document.getElementById("savSlider_" +
			            oSliderRow[idxSliderDisplayKey]).value = oSliderRow[idxSliderDisplayWeight];
			}
        }
	  }
	  catch (e) {}
   }


    function SliderCheckElement()  { if (SliderCurrentElement!=null) { return false }  } 
    function SliderDropElement()   
	{ SliderSaveElements(); SliderButtonUp(SliderCurrentIdx); 	SliderCurrentElement = null;  } 
    function SliderCursorElement()
	{ if (event.srcElement.id.indexOf("imgSliderKnob") != -1) {  event.srcElement.style.cursor = "hand" } } 
  
    document.onmousedown = SliderGrabElement; 
    document.onmousemove = SliderMoveCurrentElement; 
    document.onmouseup = SliderDropElement; 
    document.onmouseover = SliderCursorElement; 
    document.onselectstart = SliderCheckElement; 
    SliderActiveElement=null;

</pre></td></tr>

<tr><td align="left" colspan="2" class="clsBodyText"><b>SliderMath</b></td></tr>
<tr><td align="left" colspan="2"><pre class="PreSourceCode">   
 

function SliderSetOtherSliders()
	{
          
            var oSliderRow;
            var lArrayLength=0;
            var lLoop=0;
            var lRowWeight=0;
            var lTotal=0;
            var lSubTotal=0;
            var lDelta=0;
            var lAdjustableItems=0;
            var lSumTotal=100;
            var fZerosAdjusted=false;
            var lZeroDelta=0;
            var lHotItemAdjuster=0;
 
      try
	 {

             if (SliderMathOption != SliderMathTypePercent) { return false; }
	        
             lArrayLength = SliderArrays.length;
             if (lArrayLength < 1) { return false; }
 
             //  Start Load lTotal = Total of all weights,
			 //  lSubTotal = Weights not included SliderCurrentIdx 
             //  or Locked Items, lDelta = Diff between lTotal and lSubTotal
            
 
            for (lLoop=0; lLoop<lArrayLength; lLoop++)
            {

                oSliderRow = SliderArrays[lLoop];
             
               if (oSliderRow[idxSliderDisplay] == true)
               {
                    
                 lRowWeight = parseFloat(oSliderRow[idxSliderDisplayWeight]); 
					 
                 lTotal += lRowWeight;

                 if((SliderIsLocked(lLoop) == false) && (lLoop != SliderCurrentIdx)) 
                 { lSubTotal += lRowWeight; lAdjustableItems += 1;  }

               }

            }
	   
            lDelta = lSumTotal - lTotal;
             
             // End Load Total

           
		   // Start Lock Down check.  If all items are locked down, warn the user.
		   
           if (lSubTotal == 0)
		   {
			   if (lAdjustableItems ==0) {  return false;  }
			   else  { fZerosAdjusted=true;  }
		   }

           //  End Lock Down Check
 
           // Start Distribution:
 
            for (lLoop=0; lLoop<lArrayLength; lLoop++)
            {
                oSliderRow = SliderArrays[lLoop];
             
               if (oSliderRow[idxSliderDisplay] == true)
               {
                 if((SliderIsLocked(lLoop) == false) && (lLoop != SliderCurrentIdx)) 
                   {
						
                     lRowWeight = parseFloat(oSliderRow[idxSliderDisplayWeight]); 
                       

                      if (fZerosAdjusted == true)
                       {
                          
                         lRowWeight = lDelta / lAdjustableItems;
        
                         if (lRowWeight < 0.0001) { lHotItemAdjuster += lRowWeight; lRowWeight = 0; }
       
                        }
                      else
                        {
                          lRowWeight = lRowWeight + ((lRowWeight / lSubTotal) * lDelta);
                          if (lRowWeight < 0.0001) { lHotItemAdjuster += lRowWeight; lRowWeight = 0; }
                        }
						  
                        oSliderRow[idxSliderDisplayWeight] = lRowWeight;
						  
                        SliderArrays[lLoop] = oSliderRow;

                     }

                  }

             }

 
                    //  Adjust the Current Index Weight for instances of other element rounding errors.

                         oSliderRow = SliderArrays[SliderCurrentIdx]; 
                         oSliderRow[idxSliderDisplayWeight] =
                             parseFloat(oSliderRow[idxSliderDisplayWeight]) + lHotItemAdjuster;
                         SliderArrays[SliderCurrentIdx] = oSliderRow;

                    // End Current Index Adjust




			// End Distribution
                 
	      }
		   catch (exception) 
		  { 
		     if (exception.description == null) { alert("Slider Set Other Sliders: " + exception.message); }  
		     else {  alert("Slider Set Other Sliders: " + exception.description); }
		  }

		 return true; 
	}

 


    function SliderConvertWidthToWeight(nWidth)
	{
         var nRet=0;
         var nMax=0;
         var nWeight=0;

	 nMax = parseFloat(SliderMaxWidth);
         nWidth = parseFloat(nWidth);
 
         switch (SliderMathOption)
		{

              case 1:
 
                           nWeight = (nWidth / nMax) * 100;	   
                           nRet =  nWeight;
		           break;

              case 2:
	
		           nWeight = (nWidth / nMax) * 9;	
			   if (nWeight <1) { nWeight=1; }
                           nRet =  nWeight;
		           break;

		}

		 return nRet;
		  
	}

   function SliderConvertWeightToWidth(nWeight)
  {
    var nRet=0;
    var nMax=0;
    var nWidthPercent=0;
		  
    nMax = parseFloat(SliderMaxWidth);
    nWeight = parseFloat(nWeight);
 
    switch (SliderMathOption)
    {

      case 1:

            nWeight = nWeight * 2;						   
            nRet = SliderRoundNumber(nWeight,"1");
            break;

      case 2:

            if ((nWeight<1) || (nWeight >9)) { nWeight=1;}
            nWidthPercent = nWeight / 9;
            nRet = SliderRoundNumber(nMax * nWidthPercent,"1");
            break;

    }

  return nRet;
		  
}


  function SliderRoundNumber(number,X)
  {
	  
     var number2;
     var TmpNum;

     X=(!X ? 1:X);
	
     number2 = Math.round(number*Math.pow(10,X))/Math.pow(10,X);
     TmpNum = "" + number2;
     var TmpArray = TmpNum.split(".");
     if (TmpArray.length <2) { number2 = number2 + ".0"; }
	 
     return number2;
  }
SliderGlobals
   
// Global Slider Variables

   var imgSliderImgPath = 'images/';
   var imgSliderLocked = new Image(); imgSliderLocked.src = imgSliderImgPath + 'Slider_Locked.jpg';
   var imgSliderOpen = new Image();	imgSliderOpen.src = imgSliderImgPath +'Slider_Open.jpg';
   var SliderBarColor = '#5D7BBA';
   var SliderBarKnobColor = '#000000';
   var SliderBarKnobDownColor = '#A8CCF0';
   var SliderMaxLeft=0;
   var SliderCurWidth=0;
   var SliderMaxWidth=200;
   var SliderMaxBuffer=2;
   var SliderKnobLeft=0;
   var SliderMouseStatus=false;
   var SliderLastMousePos=0;
   var SliderCurrentX = 0; 
   var SliderCurrentElement = null; 
   var SliderCurrentIdx=0;
   var SliderMathOption=1;
   var SliderTableWidth=430;
   var SliderTableTDWidth=230;
   var SliderMathTypePercent=1;
   var SliderMathTypeScore=2;

Robbe has been a Microsoft MVP in C# since 2004.  He is also the co-founder of NullSkull.com which provides .NET articles, book reviews, software reviews, and software download and purchase advice.