Abstract illustration for this script: a stylized picture of a swiss-army knife.

Each utility is separately controlled, and can be applied to the entire document, a single form or form-field, or to any arbitrary group of fields:

Get the script

Download the zipfile [126K], unpack it into your site directory and add the main script and stylesheet to the <head> section of your page:

<link rel="stylesheet" type="text/css" href="formtools.css" />

<script type="text/javascript" src="FormTools.js"></script>

The formtools.css stylesheet contains optional rules for styling the generated elements that some of the methods create (as documented with each method). None of that CSS is required, because any critical style properties are set by the script, but it gives you some useful examples as starting points. You can happily use whatever styling you like, to match the elements to your design.

FormTools.js is the main script containing the entire codebase. But there's also a separate set of scripts for each individual method, accompanied by a core script which has all the common stuff. So if you're only using one of the methods, then you only need include the script for that method, plus the core (which must come first). For example, for masked password functionality:

<script type="text/javascript" src="library/FormTools.CORE.js"></script>
<script type="text/javascript" src="library/FormTools.addPasswordMasking.js"></script>

You may prefer to merge them together into one file, and if so make sure the core comes first.

All the FormTools scripts have been aggressively compressed — all comments and unnecessary whitespace have been removed, and most of the names of variables, functions and so on have been minimized to 2 or 3 characters. For your interest and reference, the archive also includes copies of the original, uncompressed scripts, which have extensive commenting and friendly names  (smile)

Once you have the script(s) you need you'll be able to use their methods (as detailed in the Developer’s Guide below). Method-calls can come from anywhere on the page and don't have to wait for onload, but they obviously will need to be after the form-fields they apply to. So the simplest thing to do is to put all such scripting at the end of the <body> section.

Developer’s Guide

The documentation covers all aspects of using and configuring FormTools. It should be straightforward enough that you don't actually need to read these docs before you can get going, but they're here as a reference whenever you need more information:

General considerations:
  1. The universal context argument
  2. Return values
  3. Known issues
Individual methods:
  1. Create masked-password fields: addPasswordMasking
  2. Add show-password checkboxes: addShowPasswordCheckboxes
  3. Add/remove caps-lock warnings: addCapsLockWarnings / removeCapsLockWarnings
  4. Add/remove default-value handling: addDefaultValueBehaviors / removeDefaultValueBehaviors
  5. Add/remove single-click selection: addSingleClickSelection / removeSingleClickSelection
  6. Implement maxlength for textareas: addTextareaMaxlength / removeTextareaMaxlength
Global options:
  1. Re-define global options: define
  2. List of available options

The universal context argument

All the utility methods have a context argument, which you can use to specify the element, elements or document context to which the functionality should be applied. It works the same way for all:

  • You can specify either a String ID, in the format "#foo" (a hash-symbol plus the element's ID), or a direct Object reference to an element or document.
  • If you specify an element and it's an applicable form-field, then the functionality will apply only to that single element. If you specify any other kind of element, or a document, then the functionality will apply to all the applicable form-fields inside that context.

If you leave this argument empty it will default to the current document.

Return values

All the utility methods return in the same way:

  • Methods which add functionality (whose name begins with "add") will return true to indicate successful initialization. Should they fail to initialize because of an error, they won't return at all.
  • Methods which remove functionality (beginning with "remove") will return false to indicate successful removal. (Likewise.)
  • Methods which don't initialize because of a browser exclusion will return null. Currently, the only specific exclusion is for the addCapsLockWarnings method in Mac/Webkit browsers (Safari and Chrome), which is not implemented by default because they already have similar functionality built-in (an exclusion you can override with the "capslock-warning-macwebkit" option). There are also general exclusions for unsupported browsers (all pre-DOM browsers, and Opera 8), and these will return null for all the utility methods.

The define method does not return a value.

Known issues

This list summarizes the script's known issues, which will hopefully be fixed in the next version; I say hopefully because, right now, I'm not sure that all of these problems actually have a solution (#2 and #3 for example are deliberate behavior to improve security, and so can only be fixed if other ways are found to bring these fields up to the same level of security as ordinary password fields):

  1. masked-password fields can only be edited from the end, not from the beginning or the middle
  2. masked-password fields do not support autocomplete
  3. masked-password and show-password fields cannot have default values
  4. masked-password fields do not support single-click selection or default-value behaviors
  5. you can't have masked-password and show-password functionality on the same field

There is also one issue which probably can't be fixed, because it's a symptom of the vulgar code I had to use to make this work in IE!

  1. pre-existing event listeners on masked-password and show-password fields will be lost

It would be possible to code-fork between Internet Explorer and others, so that only IE has that last issue; but that could create a significant behavioral discrepancy, which is potentially worse than the problem — at least you know where you are with this, and if it becomes an issue for you, simply move the FormTools method calls so that they come first. (Listeners which apply via event delegation are naturally not affected.)

FormTools.addPasswordMasking([context]);

The addPasswordMasking method converts ordinary "password" fields into a special kind of masked-password field, in which all the characters are obscured except the last one — so you can see what you just typed, but the bulk of the password is always obscured. They're like the iPhone's password fields (also seen on Android and Symbian devices) which are very popular with users as they strike a good balance between security and usability.

This method only applies to "password" inputs (which are programmatically converted into "text" fields).

Code example

FormTools.addPasswordMasking(
    "#whatever"                       // context        [OPTIONAL String|Object]
    );

Arguments

context [OPTIONAL String|Object]

The element, elements or document context to which the functionality should be applied.

Notes

Forms reset onload
The parent form of all masked password fields will have their reset event fired at load time. In addition to deleting the field's default value, this is an attempt to improve security and match the behavior of normal "password" fields, by preventing residual values from being retained after soft-refresh.
Generated markup

This method needs to create a wrapper element around each original password field, so it has a unique output and positioning context. The original field will be removed and replaced by two generated fields — one "text" field for user input and display, and one "hidden" field to contain the real, plain-text password (which is what gets submitted with the form). So to give a complete example, if you started with this HTML:

<label for="pword">Password:</label>
<input type="password" id="pword" name="pword" />

Then you'd end up with this (including the added style properties):

<label for="pword">Password:</label>
<span class="context-wrapper" style="position:relative;">
    <input type="hidden" name="pword" />
    <input type="text" id="pword" class="masked-password" autocomplete="off" />
</span>

The class name of converted password fields, the masking symbol, and the plain-characters limit, can all be specified via the define method. All the attributes that are specified on the original password field (such as its class and id) will be copied across to the text field that replaces it, except for its name, which only the hidden field will have so that it's the one to get submitted.

Errors

The context passed to FormTools.addPasswordMasking() is not valid.

The specified context is not an element or document, or it evaluates to null (eg. it doesn't exist)

FormTools.addShowPasswordCheckboxes([context]);

The addShowPasswordCheckboxes method creates a labelled checkbox next to each "password" field, that lets you toggle between a plain-text version, and the regular starred-out version. This functionality is particularly useful where users have to type very long or complicated passwords.

This method only applies to "password" inputs.

Code example

FormTools.addShowPasswordCheckboxes(
    "#whatever"                       // context        [OPTIONAL String|Object]
    );

Arguments

context [OPTIONAL String|Object]

The element, elements or document context to which the functionality should be applied.

Notes

Forms reset onload
The parent form of all show-password fields will have their reset event fired at load time. In addition to deleting the field's default value, this is an attempt to improve security and match the behavior of normal "password" fields, by preventing residual values from being retained after soft-refresh.
Generated markup

This method needs to create a wrapper element around each password field, in addition to the extra UI elements after it. The original "password" field is supplemented with a "text" field, that stores the plain password and is hidden by default, so you can toggle between the plain and obfuscated versions at will. So to give a complete example, if you started with this HTML:

<label for="pword">Password:</label>
<input type="password" id="pword" name="pword" />

Then you'd end up with this (including the added style properties):

<label for="pword">Password:</label>
<span class="context-wrapper" style="position:relative;">
    <input type="password" id="pword" name="pword" />
    <input type="text" id="pword" class="plain-password" autocomplete="off" style="display:none;" />
    <label class="show-password" title="Show the password as plain text" style="display:block;position:static;">
        <input type="checkbox" title="Show the password as plain text" />
        <span style="display:inline-block;">Show Password</span>
    </label>
</span>

The class names, text and tooltips of the created elements can all be specified via the define method. All the attributes that are specified on the original password field (such as its class and id) will be copied across to the text field that replaces it, except for its name, which the password field alone retains so that it's the one to get submitted.

Adding extra user-cues

In practice I'd use a longer title attribute for the checkbox and label than what's shown in the example above; something along the lines of: Show the password as plain text -- not advisable in a public place, which is used in the main demo. (The tooltip value is specified with the "show-password-tooltip" option.) Along with one of those little-yellow warning icons next to the label text, this can help to warn users that there's a risk in displaying their password on the screen.

Errors

The context passed to FormTools.addShowPasswordCheckboxes() is not valid.

The specified context is not an element or document, or it evaluates to null (eg. it doesn't exist)

FormTools.addCapsLockWarnings([context]);

The addCapsLockWarnings method creates little warning messages — positioned next to "password" fields and hidden by default — that then appear if the user types into the field with Caps-Lock enabled.

This method only applies to password fields — either regular "password" inputs, or masked password fields.

Code example

FormTools.addCapsLockWarnings(
    "#whatever"                       // context        [OPTIONAL String|Object]
    );

Arguments

context [OPTIONAL String|Object]

The element, elements or document context to which the functionality should be applied.

Notes

Browser exceptions

By default, this method does not apply to Mac/Webkit browsers (Safari and Chrome), because they already have similar functionality built-in. But you can enable anyway it by changing the "capslock-warning-macwebkit" option to "yes". One reason to do this might be for masked password fields, which the native warnings won't apply to because they're not really "password" fields.

Generated markup

This method needs to create a wrapper element around each password field, in addition to the extra UI elements after it. So to give a complete example, if you started with this HTML:

<label for="pword">Password:</label>
<input type="password" id="pword" name="pword" />

Then you'd end up with this (including the added style properties):

<label for="pword">Password:</label>
<span class="context-wrapper" style="position:relative;">
    <input type="password" id="pword" name="pword" />
    <span class="capslock-warning hidden" title="Caps-Lock is ON!" 
        style="display:none;position:absolute;left:100%;top:0;>
        Caps-Lock is ON!
    </span>
</span>

The class names, text and tooltips of the created elements can all be specified via the define method.

Errors

The context passed to FormTools.addCapsLockWarnings() is not valid.

The specified context is not an element or document, or it evaluates to null (eg. it doesn't exist)

FormTools.removeCapsLockWarnings([context]);

The removeCapsLockWarnings method reverses the effect of addCapsLockWarnings, deleting the warning element and removing the functionality from any elements it's been applied to.

Code example

FormTools.removeCapsLockWarnings(
    "#whatever"                       // context        [OPTIONAL String|Object]
    );

You don't need to be careful of which elements you call this method on — you can use it in broad brush-strokes to remove the functionality from a whole group of elements, even if only some of them had it applied in the first place.

FormTools.addDefaultValueBehaviors([context]);

The addDefaultValueBehaviors method adds behaviors to applicable text fields that clears or restores their default value, as appropriate: if the field contains the default value, the value is cleared when the field receives focus; if the field is empty, the default value is restored when the field loses focus. Fields are also given a special class name that only applies when the default value is shown, and this can be used to apply dynamic effects, such as grayed-out text.

This method applies to "text" inputs, "password" inputs and "textarea" elements.

Code example

FormTools.addDefaultValueBehaviors(
    "#whatever"                       // context        [OPTIONAL String|Object]
    );

Arguments

context [OPTIONAL String|Object]

The element, elements or document context to which the functionality should be applied.

Notes

When to use or avoid this method

This method should not be used on form fields where the default value is important, such as pre-filled data in a user options form. It's intended for situations where the default value is just a prompt for user input, such as Enter search terms... in a search form's query field.

If the default value is important pre-filled data, then addSingleClickSelection would be more suitable.

Errors

The context passed to FormTools.addDefaultValueBehaviors() is not valid.

The specified context is not an element or document, or it evaluates to null (eg. it doesn't exist)

FormTools.removeDefaultValueBehaviors([context]);

The removeDefaultValueBehaviors method reverses the effect of addDefaultValueBehaviors, deleting its class and removing the functionality from any elements it's been applied to.

Code example

FormTools.removeDefaultValueBehaviors(
    "#whatever"                       // context        [OPTIONAL String|Object]
    );

You don't need to be careful of which elements you call this method on — you can use it in broad brush-strokes to remove the functionality from a whole group of elements, even if only some of them had it applied in the first place.

FormTools.addSingleClickSelection([context]);

The addSingleClickSelection method adds behavior to applicable text fields, whereby the whole value is pre-selected whenever the field receives focus (by tabbing into it with the keyboard, or clicking into it with the mouse). Conversely, the value is unselected when the field loses focus, or the cursor is moved internally.

This method applies to "text" inputs, "password" inputs and "textarea" elements.

Code example

FormTools.addSingleClickSelection(
    "#whatever"                       // context        [OPTIONAL String|Object]
    );

Arguments

context [OPTIONAL String|Object]

The element, elements or document context to which the functionality should be applied.

Notes

When to use or avoid this method

This method is intended for situations where the default value is pre-filled, editable data, such as values in a user options form. Here the user is mostly likely either to leave the value unedited, or delete it and replace it with a new value, and that's the situation in which pre-selecting the value would be helpful.

If the default value is just a prompt for user input, then addDefaultValueBehaviors would be more suitable.

Errors

The context passed to FormTools.addSingleClickSelection() is not valid.

The specified context is not an element or document, or it evaluates to null (eg. it doesn't exist)

FormTools.removeSingleClickSelection([context]);

The removeSingleClickSelection method reverses the effect of addSingleClickSelection, removing the functionality from any elements it's been applied to.

Code example

FormTools.removeSingleClickSelection(
    "#whatever"                       // context        [OPTIONAL String|Object]
    );

You don't need to be careful of which elements you call this method on — you can use it in broad brush-strokes to remove the functionality from a whole group of elements, even if only some of them had it applied in the first place.

FormTools.addTextareaMaxlength(maxlength [, context]);

The addTextareaMaxlength method implements a size-limit on the input value of textarea elements, analogous to the "maxlength" attribute of input elements, that prevents the user from entering more than the specified number of characters. The processing happens live as data is input, and applies equally to user input, programmatic input, and default values.

This method only applies to "textarea" elements.

Code example

FormTools.addTextareaMaxlength(
    150,                              // maxlength      [REQUIRED Number|String]
    "#whatever"                       // context        [OPTIONAL String|Object]
    );

Arguments

maxlength [OPTIONAL Number|String]

Specify a Number which is the integer max-length you wish to apply, such as 150 characters. You can also define the max-length as a numerical-string like "150".

context [OPTIONAL String|Object]

The element, elements or document context to which the functionality should be applied.

Notes

Multiple calls

If more than one max-length value is applied to an individual textarea (for example, if you're defining both a global and some individual values), then the last one to be defined will take effect.

Errors

The maxlength specified in FormTools.addTextareaMaxlength() is not valid.

The maxlength value is missing or invalid.

The context passed to FormTools.addTextareaMaxlength() is not valid.

The specified context is not an element or document, or it evaluates to null (eg. it doesn't exist)

FormTools.removeTextareaMaxlength([context]);

The removeTextareaMaxlength method reverses the effect of addTextareaMaxlength, removing the functionality from any elements it's been applied to.

Code example

FormTools.removeTextareaMaxlength(
    "#whatever"                       // context        [OPTIONAL String|Object]
    );

You don't need to be careful of which elements you call this method on — you can use it in broad brush-strokes to remove the functionality from a whole group of elements, even if only some of them had it applied in the first place.

FormTools.define(name, value);

The define method is used for modifying the library's global configuration options. All the options are private and can only be modified using this method.

Code example

FormTools.define(
    "caps-lock-warning-message",      // option name    [REQUIRED String]
    "Caps-Lock is ON!"                // option value   [REQUIRED String]
    );

Arguments

option name [REQUIRED String]

A String that specifies which option you're defining (see the options list below for what's available).

option value [REQUIRED String]

The String value itself. This method has no defaults, so a value must always be specified.

Notes

Allowed values

All the values are strings, and can only contain plain text (no HTML or entities, except in two cases which are documented in the options list below). But any of the values can contain unicode escape sequences, such as "\u25CF" which is the default password masking symbol. Furthermore any quotation-marks must be escaped (or expressed in unicode) — this is not validated by the script, but may result in JavaScript errors if you don't it.

Option names which name end with "-class" are used for class names, and of course there are standard limitations on their syntax — they can't begin with a number, for example, and support a limited range of special characters. The script does not validate this either, so it's up to to make sure you use suitable values.

Using dynamic options

You can re-define options at any time, allowing you specify different values for different instances of the same method. But all options are retained for the lifetime of a method/field instance (including transient options, like state-dependent class names). So a field will use the values that were in force at the time a method was applied, even if those options are changed later.

Errors

The option name or value passed to FormTools.define() is not valid.

The option name is missing or refers to an option that doesn't exist; or the option value is missing or contains HTML markup or entities when it's not allowed to.

List of available options

Options table

The following table details all the available options, what they're for and their default value.

Name Description Default value
context-wrapper-class The class name of the wrapper elements created by the addPasswordMasking, addShowPasswordCheckboxes and addCapsLockWarnings methods. The wrapper is inserted directly around each applicable form field, so if you're applying structural CSS to that field, then you may need to apply it to the wrapper as well or instead. A complete HTML example is given with each relevant method. "context-wrapper"
default-value-class The class name that's added to text fields, by the addDefaultValueBehaviors method, when their default value is displayed. This can be used as a dynamic styling hook, for example to apply a grayed-out effect. "defaultValue"
capslock-warning-class The class name of the warning-message element created by the addCapsLockWarnings method. "capslock-warning"
capslock-warning-hidden-class The class name of the caps-lock warning-message when it's not displayed. You can use this to apply state-specific styling, or to override the display toggle and use something else to show and hide it (opacity perhaps, leaving it always slightly visible). "hidden"
capslock-warning-macwebkit Whether to add caps-lock warnings in Mac/Webkit browsers (Safari and Chrome), which is "no" by default because they already have similar functionality built-in. But you can enable it by changing this option to "yes" (for example, for masked password fields, which the native warnings won't include). "no"
capslock-warning-message The content of the caps-lock warning-message. The message element itself is a block-level <span>, with configurable class and title attributes, plus whatever inner content you specify here. This option can contain HTML. "Caps-Lock is ON!"
capslock-warning-tooltip The title attribute of the caps-lock warning-message, which will appear as a tooltip on the message element whenever it's displayed (but not when it's hidden). The purpose of this option is so you can make the message have purely graphical content, while still having usable information to describe it. "Caps-Lock is ON!"
show-password-class The class name of the main <label> element surrounding the group of elements created by the addShowPasswordCheckboxes method. "show-password"
show-password-plainfield-class The class name of the created field used to store the plain-text version of the password. This class is made available purely as a styling-hook. "plain-password"
show-password-text The text written next to the show-password checkbox. This is a <span> element directly after the checkbox, with inline-block display, plus whatever inner content you specify here. This option can contain HTML. "Show password"
show-password-tooltip The main <label> title attribute, which is also applied to the checkbox <input>, and which will appear as a tooltip on one or both elements. to provide additional user information, such as the privacy warning included in the default value. "Show the password as plain text — not advisable in a public place."
masked-password-class The class name of the masked password fields created by the addPasswordMasking method (which are converted into "text" fields from original "password" inputs). "masked-password"
password-masking-symbol The symbol which is used to obscure a masked password, in place of the real characters. The default value is a small-round dot (●), which is what most browsers use for regular password fields. You may prefer to use something more esoteric, but do always consider the usability of what you choose — it must be obvious what it's for. "\u25CF"
password-masking-limit The number of readable characters that are shown at the end of a masked password while it's being edited. This limit only applies while the password field has the focus — once it loses focus the whole value will be masked. "1"

Get the script

BSD License → Terms of use

Categories...

Website gadgets

Bits of site functionality:

Usability widgets

For enhancing usability:

Local network apps

Web-applications for your home or office network:

Game and novelties

Our internal search engine is currently offline, undergoing some configuration changes in preparation for a major site overhaul. In the meantime, you can still search this site using Google Custom Search.


In this area

Main areas


[brothercake] a round peg in a square hole, that still fits