
        JSNumbers JavaScript Library

        Copyright 2006, James Melanson
                        james_melanson@yahoo.ca
        
                        JSNumbers V1.02       2007.01.07

        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
        
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>


  CONTENTS OF README FILE:
  
  1.) Overview
  2.) Implementation
      i    What files to use.
      ii   Linking to the files.
      iii  Instantiating the number object
            a.) Instantiating multiple auto-complete objects
      iv   Giving the object a number to work with, setting the value.
  3.) Manipulation Methods
      i    Testing Values
            a.) isInt()
            b.) isDecimal()
            c.) isNumber()
      ii   Converting Methods
            a.) integer()
            b.) dollar()
            c.) decimal()
      iii  Formatting Methods
            a.) addCommas()
            b.) Xnth()
            c.) padding()
            d.) paddingLeft()
            e.) clean()
  3.) Full Property & Method List
  4.) Combining Methods
  5.) Samples of instantion, property assignment and working sliders
  6.) Debugging
  7.) Support



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

  OVERVIEW

  Whenever I work on a JavaScript program, I always run into problem working
  with numbers. Either assessing the value, performing math or manipulating the
  look/format of the number. Quite often, I found myself re-creating the same
  code time and time again because life is rarely so simply as 2 + 2.

  While JavaScript has a lot of internal math functions through the Math() object,
  there are still things we need to do in the real world that it doesn't cover.
  That is what this library is for.

  This library is for manipulating numbers in a way that is not commonly seen
  other ways. The only duplicate method you will find is integer() and that's
  only because of chiding I received for not putting it in the first time.
  Happy Dave? As well, a couple of these CAN be done with existing methods but
  my version is a lot easier to remember.

  This library was developed for the purpose of formatting number values, not
  performing math functions per se.

  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:

  jsnumbers.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.


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

  IMPLEMENTATION - LINKING TO THE FILES.

  The JSNumbers 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 auto-complete object you will be creating.

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

  [-- Start Snippet --]

<script language="JavaScript" src="jsnumbers.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.

  **If you are using my Bar Slider library, this library is already implemented in it and you
    do not need to call this library file, simply jumpt ahead to creating the object.

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


  IMPLEMENTATION - INSTANTIATING THE JSNumbers OBJECT

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

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

                    var objHandle = new jsnumbers();

  You do not pass any arguments to the constructor.

  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 JSNumbers OBJECTS

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

  For each of the JSNumbers objects, you can specify a completely different value and
  access their methods individually.

  To have more than one JSNumbers on the page, simply instantiate each new JSNumbers
  object with a different handle name. For example, if I needed three separate number objects
  then I would instantiate the objects inside JavaScript tags inside the <head></head>
  tags of the page like this:


<script language="JavaScript">
<!--
var price = new jsnumbers();
var quantity = new jsnumbers();
var tax = new jsnumbers();
//-->
</script>


  I would now access methods individually for each JSNumbers object simply by
  refering to the handle for the slider in question (price, quantity, tax are
  the object handles).

  Given that it is not likely you really NEED to hold the value of a number
  in the objects memory, it would probably be easier on your code if you
  instantiate the object once and then use it in Number Cruncher mode (explained
  below) for your programming.


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

  IMPLEMENTATION - GIVING THE OBJECT A NUMBER TO WORK WITH, SETTING THE VALUE.

  There are two principle ways to use this object.

  The first way is to assign the object a value and then call methods that return
  the initial value with the ations taken upon it, without modifying the initially
  held value. For example, if you use the object this way, then as an example
  assume we passed the value "123.4" to it. Evey method that you call after that
  point will always perform actions on the value "123.4".

  You can set the value in the object by calling the value() method:

        objHandle.value([number]);

        Example:

            objHandle.value(234);

            ~OR~

            objHandle.value('234.5');

            ~OR~

            var someValue = 234 * Math.PI();
            objHandle.value(someValue);


  The other method of using this script is to simply use it as a NUMBER CRUNCHER.
  To do that, you instantiate the object then call any of it's methods and pass
  a new value as an extra argument to the method you want to use. Note that
  this passed value will be stored in the object as it's new set value until
  a new value is passed.  Each of the methods below will have an example showing
  how to pass an argument to use it as a number cruncher.



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


           IMPORTANT NOTICE

           ALL OF THE FOLLOWING METHOD EXAMPLE ASSUME THAT:

           1.) YOU HAVE INSTANTIATED THE OBJECT

           2.) YOU HAVE PASSED THE OBJECT A VALUE:  objHandle.value(someValue);


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


  MANIPULATION METHODS - TESTING VALUES - isInt()

  This method provides a quick and simple test to see if the value is
  an integer or not. If it is, it returns a true value, otherwise it
  returns a false value.

        if( objHandle.isInt() ) {
            ... do something nifty with the integer ...
        }


  **Number Cruncher Example:       if(objHandle.isInt(someValue)) {


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



  MANIPULATION METHODS - TESTING VALUES - isDecimal()

  Using isNan will tell you if something is a number but will not tell you if it
  is a floating point number. The method isDecimal() will do just that. If the
  passed value has a decimal place in it, this method returns true, otherwise it
  returns false.

        if( objHandle.isDecimal() ) {
            ... do something nifty with the floating point number ...
        }


  **Number Cruncher Example:       if(objHandle.isDecimal(someValue)) {

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


  MANIPULATION METHODS - TESTING VALUES - isNumber()

  Simply because I don't like testing for a negative to find a positive ( !isNaN ), I
  created a method that will return TRUE if it is a number and false if it is not.

        if( objHandle.isNumber() ) {
            ... do something nifty with the number ... 
        }



  **Number Cruncher Example:       if(objHandle.isNumber(someValue)) {

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


  MANIPULATION METHODS - CONVERTING METHODS - integer()

  This takes ANY input value and returns it as an integer. If it was a floating point
  number before, it returns only the integer portion of it. If the submitted value
  was a string, it returns it as an integer (do you see the power in that?).

        someExistingValue += objHandle.integer();



  **Number Cruncher Example:  var somevar = objHandle.integer(someValue);

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


  MANIPULATION METHODS - CONVERTING METHODS - dollar()

  Since a lot of web applications involved selling things and other money matters,
  this method simply and easily converts any value into a visual representation
  of that number as a dollar figure (with commas added in).

        document.write('The cost is \$'+objHandle.dollar());



  **Number Cruncher Example:  var totalcost = objHandle.dollar(someValue);

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


  MANIPULATION METHODS - CONVERTING METHODS - decimal()

  This method takes one argument, the number places you want the value returned to
  as a decimal. If the value currently has MORE than that places of decimals already,
  it returns the value ROUNDED to that many decimal places.

  To return a number to two decimal places, call the method like this:

        objHandle.decimal(2);

  If the passed value was 123.5678 then the returned value would be 123.57
  If the passed value was 123.342  then the returned value would be 123.34
  If the passed value was 123.2    then the returned value would be 123.20

  
  **Number Cruncher Example:  var somevar = objHandle.decimal(x, someValue);

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


  MANIPULATION METHODS - FORMATTING METHODS - addCommas()

  This method takes a number and inserts commas every third digit from the decimal
  point or the left end or the number. This method is called like this:

        objHandle.addCommas();

  If the passed value was 1234567  then the returned value would be 1,234,567
  If the passed value was 123456   then the returned value would be 123,456
  If the passed value was 26457.32 then the returned value would be 26,457.32
  If the passed value was 432      then the returned value would be 432


  **Number Cruncher Example:  var somevar = objHandle.addCommas(someValue);

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


  MANIPULATION METHODS - FORMATTING METHODS - Xnth()

  This method accepts one argument, the number of digits to return of the decimal
  portion of a number only. That is the digits to the right of the decimal place.
  Quite often I found myself doing a modulus test and then wanting to grab the
  decimals value. This method is called like this:

        objHandle.Xnth(2);

  If the passed value was 123.45678 and the argument was "2", the returned value would be 123.46
  If the passed value was 123.4523  and the argument was "3", the returned value would be 123.452
  If the passed value was 123.48    and the argument was "4", the returned value would be 123.48

  **You can see from the examples above, unlike decimal() which pads the results, Xnth does NOT
    pad the returned value, however, it DOES round it up.

  **NOTE: If the passed value is an integer, this method returns a value of zero, not a null or
          false boolean value.



  **Number Cruncher Example:  var somevar = objHandle.Xnth(someValue);

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


  MANIPULATION METHODS - FORMATTING METHODS - paddingLeft()

  This method accepts two arguments. The first argument is the number of places to
  pad and the second argument is the character to pad the number with. This method
  pads to the left of the integer portion of a value. This method is called like this:

        objHandle.paddingLeft(3, '0');

  If the passed value was 123   and the arguments were 5 and '0', the returned value would be 00123
  If the passed value was 12345 and the arguments were 4 and '0', the returned value would be 12345
  If the passed value was 123   and the arguments were 6 and 'x', then the returned value would be xxx123

  If no character (second argument) is passed, then a blank space is used for the padding character.



  **Number Cruncher Example:  var somevar = objHandle.paddingLeft(x, 'char', someValue);

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


  MANIPULATION METHODS - FORMATTING METHODS - clean()

  This is the method that makes this library more controversial in nature. It is applied
  every time a value is passed to one of the methods AND it can be called on it's own
  as well.

  What the clean() method does is strip any character out of a passed value that is not
  a digit or a decimal.

  For example:

        var someFunkyValue = 'iiiu2h3j2j23.3u5y';
        document.write('The funky value has been cleaned up to be '+objHandle.clean(someFunkyValue));

      The output of this would be:

        The funky value has been cleaned up to be 23223.35

  Because it is called on ALL methods, it adds a great deal of flexibility to your programming
  and can reduce your code signicantly in some cases. For example, suppose you have an order
  form and in it you ask how many packages of pencils the client wants to order. You anticipate
  that a rational person would input the value "5". However, given this is the web and experience
  has shown your just as likely to receive "5 pkgs", you know that you have to test and scrub all
  your inputs to make sure clients are entering the right information. This can lead to some tricky
  JavaScript code that you simply don't know how to write.

  Calling parseInt() or parseFloat() on the value "5 pkgs" would return a value of "Nan" or "Undefined".

  However, using this library you could scrub that value like this:

        objHandle.clean(document.getElementById('numberofpencilpkgs').value);

      The result then of cleaning "5 pkgs" would be "5".

  As well, since it is also called on every method, you wouldn't need to expressly call the clean()
  method, you could just act on one of the other methods.

        objHandle.value(document.getElementById('numberofpencilpkgs').value);
        var cost = 2.35 * objHandle.integer();
        document.write('The cost of '+objHandle.integer()+' packages of pencils is \$'+objHandle.dollar(cost)+'<br>');

      The results would be:

        The cost of 5 packages of pencils is $11.75




  **Number Cruncher Example:  var somevar = objHandle.clean(someValue);

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

  FULL PROPERTY & METHOD LIST


  [PROPERTIES]

            *** This library has NO properties for you to set or access ***

  [METHODS]

  METHOD                     ARGUMENTS               NUMBER CRUNCHER EXAMPLE

  value()                    Value to act on         N/A

  isInt()                    None                    objHandle.isInt(someValue);

  isDecimal()                None                    objHandle.isDecimal(someValue);

  isNumber()                 None                    objHandle.isNumber(someValue);

  integer()                  None                    objHandle.integer(someValue);

  dollar()                   None                    objHandle.dollar(someValue);

  decimal()                  None                    objHandle.decimal(someValue);

  addCommas()                None                    objHandle.addCommas(someValue);

  Xnth()                     Integer                 objHandle.Xnth(someValue);

  padding()                  Integer                 objHandle.padding(someValue);

  paddingLeft()              Integer, AlphNumeric Character  objHandle.paddingLeft(someValue);

  clean()                    Any value               objHandle.clean(someValue);



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

  COMBINING METHODS:

  It is possible to combine methods if necessary. Here are some examples (though why
  you would use them would be up to you, I haven't had enough coffee yet today for
  that question):

  var somvar = objHandle.paddingLeft(4, '0', objHandle.integer(somevalue));

  var somevar = objHandle.addCommas(objHandle.decimal(3));

  var somevar = objHandle.addCommas(objHandle.paddingLeft(6, '0', objHandle.padding(2)));

  **Just remember in your own combination that the methods are evaluated
    from right to left. That being, the method furthest to the right is evaluated
    prior to the method appearing to it's left.



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



  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 the file "example_jsnumbers.html" in your browser. 

  After seeing how they work, you can then view the source code to examine the
  object instantiation 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 auto-complete
  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:

     objHandle.isInt;    //Not good, will always return a TRUE value.
     objHandle.isInt();  //The proper way


  >> 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 number, you must NOT enclose it in quotes. Here are some examples:

     objHandle.value('someValue'); //This is VERY bad. Will set the value to NULL.
     objHandle.value(someValue);   //Martha says, "This is a very good thing"

  >> Order of method call. Remember that some methods will alter the stored value in the object
     thus the subsequent methods act on the modified value, not the original value. It is
     recommended you reset the value before making subsequent calls OR you call the method
     as a number cruncher.

  >> 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 methods
     you have typed and work you way upwards, reading each method and handle 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 JSNumbers 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 speling 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.



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

  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 auto-complete 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. If I estimate that my time will exceed one hour, then you
  will be notified BEFORE I commence any work.

  I do not offer support for this library as it is free, easy to implement and well documented.
  If you are REALLY, REALLY stuck, e-mail me and I'll try to answer in a timely manner.
  Any mistakes that occur which prevent it from operating are most likely yours. If you
  are using it for a mission critical application and MUST get it running but can't
  figure it out, I will offer custom integration per the terms above.

  PLEASE CONTACT ME AT:      james_melanson@yahoo.ca

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


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

