Version History
---------------
Listed below is the complete version history of the changes to the qForms
API. Use the following key to determine the type of change:

 [*] A change in the behavior, pay close attention to these changes, as
     they could affect existing applications using the qForms JSAPI
 [+] Some additional functionality has been added. This should not affect
     existing code.
 [-] A bug was fixed or some other minor change was made that should not
     affect existing code.


Build 123a1 (February 19, 2001)
---------------------------------------------------------------------------
[-] The last three release note dates were wrong.
[-] Fixed the advanced.htm example. I forget to set the last parameter
    of the addEvent() method to false, which caused a problem in Netscape.
[-] Fixed the multilayer.htm example so that it works with Netscape v4.0.
    I keep forgetting how much Netscape dislike the STYLE attribute. If
    you're having weird display problems with layers, the odds are you've
    got some inline CSS in a STYLE attribute, move it to a class statement
    and you're ok. :)
[-] Changed the example files to call "qforms.js" instead of "qForms.js"
    for Unix users. Also, changed all FORM action statements in the layer
    examples to point to the showdata.htm file.

Build 123a (February 19, 2001)
---------------------------------------------------------------------------
[-] Changed a few lines in the "Field" constructor to support field names
    with odd syntaxes--namely added support for field names in the format
    of "SomeField[]".
[*] Had the wrong GNU License agreement in the first release. Oops!
[-] Corrected a few typos in the docs

Build 123 (February 18, 2001)
---------------------------------------------------------------------------
[-] First public release!!!
[+] Created the HTML documentation and example files. If I ever say it will
    only take me a couple of hours to do docs, kick me--please! :)
[-] Looked for code redundency and try to cut down the qForms footprint.
[*] Got rid of excess properties in both the qForm and Field constructors.
    These were properties that were supposed to act as pointers, but didn't
    work correctly. However, as always, you can access the same information
    by using the "obj" pointer for those constructors.
[-] Re-wrote some of the code to cut down on the file size
[*] Renamed _Trim(), _RTrim() & _LTrim() functions to all lowercase.
[-] Renamed the /lib/qForms/ folder to /lib/qforms/ to prevent possible
    problems on Unix-based boxes.
[+] Added the obj.fieldName.dummyContainer property for container objects.
    Setting a container to a dummyContainer will exclude the items in the
    option array from being returned or submitted.
[-] Fixed bug in the _getURLParams() function that caused variables that
    appear multiple times in the query string to only grab the last value.
[-] Changed the obj.fieldName.getValue() method so that if a select box
    option doesn't have a "VALUE" attribute, it'll use the use the text
    between the <OPTION></OPTION> tags.
[-] Changed the reset() methods so they now run the enforceDependency()
    method anytime it clears a value.
[+] Added _getEventType() function which returns the correct event for
    to use when adding an event that should happen as soon as the field
    value is sure to have changed
[-] Changed the obj.fieldName.mirrorTo() method so that non-text fields
    are updated as soon as the value changes 
[+] Added obj.fieldName.init() method--this allows the use of 
    this.addEvent() to initialize event handlers
[+] Added a parameter to the disabled() method to specify the status.
    Leaving the parameter out will continue to toggle the status. 
[-] Fixed bug in the obj.fieldName.enforceDependency() method which wasn't 
    losing variable declarations, was force to use the setTimeout() method.
[-] Fixed bug in the obj.fieldName.addEvent() method which wasn't properly
    added events to multi-arrayed items--such as radio buttons. This
    caused problems with some aspects of the qForms, like with the
    createDependencyTo() method
[-] Fixed bug that was causing the onBlur events not to always run when
    using the setValue() method (once again the multi-arrayed thing)
[*] Changed the name of the "whatsnew.txt" file to "history.txt"
[*] Renamed the qFormAPI.getAllForms() method to qFormAPI.getFields()
[*] Renamed the obj.getForm() method to obj.getFields() 
[*] Renamed the obj.setForm() method to obj.setFields() 
[*] Renamed the obj.setForm() method to obj.setFields() 
    of the form objects populating fields by matching the field name
    to the keys in the specified structure.
[*] Renamed the Cookie library functions loadForm() to loadFields()
    and saveForm() to saveFields()
[+] Added the obj.dump() method which will display all of the fields
    in the selected qForm object and their values to an alert box.
[+] Added the qFormAPI.dump() method which will display all of the fields
    in all of the qForm objects and their values to an alert box.
[+] Added the qFormAPI.serialize() method which will serialize all the
    qForm objects into a single WDDX packet
[+] Added the qFormAPI.reset() method which will run the obj.reset() method 
    for all the qForm objects on the page
[-] Fixed bug which was causing the qFormAPI.usewddx variable to 
    be false if the wddx.js file was loaded after the qForm.js library.
    The wddx library is now check for each time a qForms object is
    initialized.
[+] Added support for JavaScript v1.4 and v1.5


Build 122 (January 30, 2001)
---------------------------------------------------------------------------
[-] Fixed bug which caused problems when defining the parent layer when
    creating a new layer. (This was an NS4 problem.)
[+] Created the qFormAPI.validate() method. This method is now used instead
    of obj.validate(). This allows for validating multiple qForm objects
    anytime a form is submitted. By default, only the form being submitted
    is checked. To check all qForm objects, set the property 
    qFormAPI.validateAll to true.
[-] Split the obj.validate() function in to two seperate functions:
    obj.validate() and obj.checkForErrors(). The checkForErrors() method
    now actually clears and rebuilds the error queue for the specified 
    qForm object. The validate() method runs the checkForErrors() method
    and generates an error message if any errors exist. You can call the
    checkForErrors() any time you want to manually rebuild the error's 
    queue.
[+] Added the qFormAPI.getAllForms() method which will return a structure
    similiar to the obj.getForm() method, except it will contain the data
    from all of the qForm objects on the page.
[*] Changed the functionality of the obj.fieldName.mirrorTo() method. This
    method now takes the name of a valid object (as a string) instead of
    another field. This allows you to mirror the value to any field in 
    any form, or even a JS variable.
[-] Fixed bug in the obj.submit() method which was causing some browsers
    to not run the onSubmit event.


Build 121 (January 29, 2001)
---------------------------------------------------------------------------
[+] Added the qFormAPI.libs structure. This is used to create global 
    workspace for custom libraries. The workspace will be initialized 
    automatically for you in the format: qFormAPI.libs.[library name].
[+] Added the "cookies" library.
[-] Fixed another bug in the validate() method.
[+] Added the _functionToString() function
[+] Added onSubmit() method which is run before the page is submitted to 
    the server
[*] Changed the process for creating the pointers some of the field 
    properties by using typeof != undefined
[+] Added the makeContainer() method to the field.js extension library. 
    Use this method for marking a field as a container. Simply setting the 
    container property to false will cause errors.
[-] Fixed bug in the isDate() function with both parseInt() and with finding 
    months with 30 days in it. (Thanks to Jeremy Allen!)
[-] Removed Version History from the qForms.js file to a seperate 
    "whatsnew.txt" file


Build 120 (January 10, 2001)
---------------------------------------------------------------------------
[*] Changed the isDependentTo() method to check the expression evaluate for
    the phrase "this."--if it doesn't exist, it'll treat the expression as a
    string.
[-] Moved the customValidators property to the "qFormAPI" constructor.
[+] Added the _allowSubmitOnError form property. This dictates whether or not
    validation errors should be in an alert (false) or confirm (true) box.
[+] Added the _setContainerValues() function which makes sure that if a select 
    box is flagged as a container, that when the form is submitted, all the 
    items get selected. This ensures that the value the server recieves matches 
    the "getValue()" method.
[-] Fixed bug which was preventing the form from submitting!!! Oops!


Build 119 (January 09, 2001)
---------------------------------------------------------------------------
[+] Added container property to field constructor. The container is a special
    property for select boxes. If a select box is consider a container, then
    all the items in the select box are consider part of the value, rather then
    just the selected values. 
[*] Gave the createDependencyTo(field, expression) method a new argument of 
    "expression". The expression must validate to true in order for the 
    dependency to take effect.
[-] Multiple dependencies now work correctly for the same fields now work 
    correctly
[-] Dependency will now climb the dependency tree: meaning if field3 is only 
    required if field2 is filled in and field2 is normally optional, but a 
    dependency on field1 that has been matched making field2 required, then 
    field3 will show required as well.


Build 118 (January 08, 2001)
---------------------------------------------------------------------------
[-] Fixed bug with locked status
[*] Changed the name of the qForm's property back to locked from _locked
[+] Added CSS change to failed validation fields as well as required fields 
    that were left empty
[*] Changed isLocked() method to checkIfLocked()
[+] Added isLocked() method which return true if the current field should 
    be locked
[+] Added isDisabled() method which checks to see if the current field has 
    it's disabled property set to true.
[+] Added mirrorTo(field) method which will copy the value of the select 
    field to another field--this is useful for updating hidden form fields
[-] Changed the transferTo(), transferFrom(), location() and populate() 
    methods so they will not work if the field is disabled or locked
[-] The setValue() method now calls the field's onblur event if the argument 
    doBlur is true (default.) The reset() & setForm() methods call the 
    setValue() method with the doBlur event set to false.
[+] Added createDependencyTo(field) and enforceDependency(field) methods--this 
    methods create a relationship between two fields. If the field the 
    dependency is created on is blank, then the dependent field is not required. 
    If there is a value entered, then the field is required.
[-] CSS styles on the form fields are now reset each time the validate() method 
    runs, this makes sure that fields aren't left a color they shouldn't be


Build 117 (January 08, 2001)
---------------------------------------------------------------------------
[-] Fixed bug which was causing endless loops to occur if you tab between two 
    fields that required validation
[+] Added browser detection to the qFormAPI object, this will detects the 
    browser version. You can use these variables to help write DHTML code.
[+] Text fields are now turned red if required and not filled in when the 
    validate() method is called. The fields will be return to the normal 
    background style once focus is returned to the form field. (This works in 
    IE4+ and NS6 only)
[-] Fixed bug in NS3 w/disabled methods
[-] Fixed bug in NS3 that was causing the validate methods to fail
[-] Fixed bug which was double verifying required fields that had a validation 
    type defined on them
[*] Changed the isBlank() method to isNotEmpty()--which more correctly reflects 
    the purpose of the function
[+] Created isNotNull() method which makes sure the string lenght is not zero
[*] Moved some of the global qForm variables into the qFormAPI object
[-] Fixed problem in NS3 & 6 that caused the field to lose focus even when a 
    field has forced validation assigned to it.


Build 116 (January 08, 2001)
---------------------------------------------------------------------------
[-] Removed duplicate lines in the _addValidator() function
[+] Added addEvent(event, command, [append]) methods which allow you to attach an
    event to either the qForm object or one of it's fields
[+] Added _addEvent(object, event, command, [append]) function
[+] Added validateExp(expression, error, [command]) method, which validates a simple 
    expression
[+] Added reset command on the form when initialization occurs--this makes sure that the
    default values initialized for the form are correct
[*] Changed (again) the structure of the validation methods. To attach validation to a field
    you know would use validateXXXX (where XXXX is the name of the method initialized.)
    For example: objForm.Email.validateEmail() would ensure that when the form is submitted
    that if a value is supplied for the Email field, that it's a valid e-mail address
[*] The "is"-style validation can now be called to return "true" if no error occured, or
    "false" if an error occurred. This gives you the ability to write custom code to check
    the validation of a field.
[-] In order to get the onBlur field validation to display the error, you must append to 
    the qForm's status the string "_ShowError". This will ensure that the error is displayed.
[*] Changed the "qForms_load.js" file to "qForms_init.js" (which makes more sense.)


Build 115 (January 05, 2001)
---------------------------------------------------------------------------
[-] Made changes to make the API work in NS3 (got rid of "function literals")
[*] Major changes to the validation mechanisms. The validate() function is no longer
    required. Validation rules can be initialized any time after the form object
    had been created.
[*] Changed internal qForm properties to start with an underscore--this should help
    to avoid naming convention conflicts within a form
[+] Added the required and validate properties to the Field objects
[+] Revised validate() method to check to make sure required fields are not blank
    (this runs the isBlank() validation method)
[+] Added required() and optional() methods to set whether a field is required or not
[+] Added the forceValidation() method--which forces a field to be validate when the
    field's onBlur event occurs
[+] Created addMethod() method which allows you to create a new prototype
[+] Created addValidator() method to create new inline validation methods
[+] Created _addValidator() function which is used to create new validation prototypes
    The function creates two prototypes for the function specified, once for validation
    purpose, and the second which attaches it to any required events and places it in
    the validation queue.
[*] Rewrote Validation library to work with the new validation methods
[*] No more "check"-style validations--they're no longer required


Build 114 (December 29, 2000)
---------------------------------------------------------------------------
[-] Removed alert() line used for debugging that was at line 282.


Build 113 (December 28, 2000)
---------------------------------------------------------------------------
[-] Fixed bug which was causing the "is"-style validations from popping up
    when you'd lock the entire form object
[-] Changed the message for the isState() check. It no longer says "postal
    code."
[-] Fixed bug which caused most methods to fail once an "is"-style checked
    had thrown an error. (Seems I was setting the value of the qForm's status
    to null, when it should have been set to "idle".)
[-] Fixed bug with onSubmit event that prohibitted the user-defined onSubmit
    events from running. The validate() function is now executed after the
    user-defined code.
[+] Added isZip() and checkZip() validation methods.
[-] The isPassword() validation method now excepts a null entry for the
    field attribute. This will skip compare the password field to another
    field.


Build 112 (December 28, 2000)
---------------------------------------------------------------------------
[+] Added check to make sure that a field name exists when validating
    the field using the "check"-style validations


Build 111 (December 28, 2000)
---------------------------------------------------------------------------
[+] Added check for the validate() function in the onSubmit event. If it
    exists, then we parse it out. This will prevent double validate()
    functions from running in v4.0 browsers.
[-] Fixed bug that was causing the form not to be submitted in v4.0 browsers
    once an error had occurred. Now if the browser's validate function
    returns false, the status of the form will be reset
[-] Created a bug when changing the isLocked() method in the last build.
    isLocked() returns false if the field is locked, and true if the
    field is not locked


Build 110 (December 27, 2000)
---------------------------------------------------------------------------
[-] Fixed NS bug in bit library that didn't use the options[] object
[-] Renamed a few of the arguments
[-] Fixed bug in isLocked which wasn't really returning the correct value
    when the showMsg arguement was set to false.


Build 109 (December 22, 2000)
---------------------------------------------------------------------------
[-] Fixed bug in the include path which didn't load custom modules correctly
[+] Added _listSum() function
[+] Added "Bits Extensions Library" and "example_bits.htm" files
[*] Changed the declaration of the _createFields() function


Build 108 (December 22, 2000)
---------------------------------------------------------------------------
[+] Added the populate() method which will repopulate an option based upon a
    structure
[+] Added custom function _sortOption() which can be used to sort a select box's
    option array. You can sort asc or desc by either the text or value 
    (default is "text");
[+] Added custom function _getURLParams() which will parse the query string and
    return it as a structure. Useful for populating a form based on the URL
    parameters passed to it.
[+] Added custom function _createFields() which will create form fields based
    upon a structure. Useful for passing information from one form to the next.
[+] Added custom function _transferOptions() which will move the selected option(s)
    from one select box to another select box.
[+] Added the transferTo() and transferFrom() methods which will move options from
    one select box to another.
[-] Fixed the submit() method so that a form can only be submitted once when using
    this function.
[*] Changed the validate() method so that it will return true if the form's status
    has been set to "submitting"
[-] The form's "onSubmit" event now prepends a check to make sure the form hasn't
    already been submitted. If it has, it will cancel the submit request. This
    prevents multiple submissions to the server.
[-] The form's "onSubmit" event now prepends a check to see if the function 
    "validate" exists in the document. If it does, it'll automatically run the
    function on form submission.


Build 107 (December 20, 2000)
---------------------------------------------------------------------------
[*] Broke the API into modules
[*] Changed the name of the file from qform.js to qforms.js

Build 106 (December 19, 2000)
[-] Fixed bug which caused selected box with no default value to give error when 
    it calculated the default values
[-] Fixed bug which caused form fields that contained multiple values to not be 
    selected correctly. (This was caused by not checking for the delimiter before
    and after the value!!!)


Build 105 (December 15, 2000)
---------------------------------------------------------------------------
[+] Added isPhoneNumber() and checkPhoneNumber() methods
[+] Added isLength() and checkLength() methods
[+] Added isState() and checkState() methods (which uses the US Postal 2-digit abbreviation)
[+] Added function _getState(abbr) which returns a states full name if a valid 2 digit
    abbreviation is passed.
[+] Added the field-level "format()" method which allows you to create masking for fields
[-] Fixed bug that was occurring with some "for" loops by adding the var defintion
    before the variable declarations
[-] Fixed bug which called endless loop in Netscape when you went from one form field with
    "is"-style onBlur event to another form field with an "is"-style onBlur event


Build 104 (December 14, 2000)
---------------------------------------------------------------------------
[+] Added form-level "hasChanged()" function which return true if a value in the form
    has changed or false if the form contains the default values
[+] Added the "reset" attribute to the setForm() method which allows you to reset the
    default values with that of the object being passed in
[-] Changed the reset() method from using the default reset() form method to a custom
    one that reads the current defaultValue variable and resets the value occordingly
[-] Changed the setForm() function so that it's case insensitive. To accomedate this,
    I had to add a "pointers" object to the form which keeps pointers as lower case 
    representatives of the field names
[-] Fixed bug which was causing IE to loss the value of the form field when the isLocked()
    event occurred
[+] Added miscellaneous functions--these begin with underscores ("_")
[+] Added trim methods (trim(), ltrim(), rtrim()) at the field level
[-] Fixed bug with "check"-style validations that didn't allow spaces between the comma
    delimiter
[+] Added "serialize()" method which serializes the forms content to WDDX. If the WDDX.JS
    library is not loaded, an error is thrown when calling this method. This returns a
    string. You can pass the argument "exclude" which will exclude fields from being
    serialized.
[+] Added "toUpperCase()" and "toLowerCase()" field-level methods


Build 103 (December 13, 2000)
---------------------------------------------------------------------------
[+] Got event capturing working in Netscape (still looking for a better way to handle 
    selectboxes)
[+] added changedFields() method that returns a structure of all the form fields that have value
    different from the defaultValue variable


Build 102 (December 12, 2000)
---------------------------------------------------------------------------
[+] Added the "extension" add-on library for fields (location() and isLocked())
[+] Added event capturing to the fields
[+] Added field-level "reset" method


Build 101 (December 11, 2000)
---------------------------------------------------------------------------
[+] Added support for all normal form and field properties and methods 
 (action, click, focus, method, target, selectedIndex, etc.)
[+] Added base form validation methods (isBlank, isEmail, isNumeric, isAlpha
    isAlphaNumeric, isCreditCard, isDate, checkBlank, checkEmail, isPassword
    checkCreditCard, checkDate, compare, isRange, isDifferent)
[*] "Check" function are at the form object level, and are for validating 
    multiple fields (example: objForm.checkBlank("Name");)
[*] "Is" functions are at the field level and are for validating a single
    field object (example: objForm.Name.isBlank();)
[*] After running any "check" methods, you must run the validate() method
    in order to view the errors.


Build 100 (December 10, 2000)
---------------------------------------------------------------------------
[-] First beta release
