Javascript Utilities

Select Loader

A common pattern in web applications is that the options available in one select element (the "child") depend on what has been chosen in another select element (the "parent").

A SelectLoader may be used to display the contents of the child select and (if neccessary) asynchronously retrieve them before doing so.

Test Form
Files:
selectloader.js
Dependencies:
prototype.js - version 1.3.1 of the Prototype Javascript framework.
prototype-extend.js - extensions to the Prototype framework.
json.js - JavaScript Object Notation parser.
log4js-refac.js - a refactored version of Log4JS.

The following scenarios should be accounted for:

User with Javascript disabled or otherwise not available

Provide form controls within noscript elements which submit the form to retrieve and display the child select via page generation logic.

These controls may be hidden or disabled by Javascript when available.

In other words - make the page work without Javascript first, but ensure that the core functionality used is implemented in an easily re-usable way. In this case, the code for retrieving a list of options for a child select should be easily accessible.

User with Javascript enabled and relatively small domain of parent/child data

Create an associative arrayan object-literal "hashtable" [1] mapping values in the parent select to an arrayarrays of objects, each of which has a text and a value attribute which may be used to populate an Option in the child select. Pass this associative arrayhashtable into the SelectLoader constructor as shown below:

var domain = { "1": [  {value: 1, text: "Town 1"},
                       {value: 2, text: "Town 2"},
                       {value: 3, text: "Town 3"}
                    ],
               "2": [  {value: 1, text: "Town 6"},
                       {value: 2, text: "Town 7"},
                       {value: 3, text: "Town 8"}
                    ]
             };

new SelectLoader({
    parentSelect: document.forms["someForm"].elements["countySelect"],
    childSelect: document.forms["someForm"].elements["townSelect"],
    contents: domain
});

User with Javascript enabled and large domain of parent/child data

Provide some of the domain of data as a starting cache - popular choices, for instance - or none at all. Provide SelectLoader with a URL at which a Display Service will determine which child data should be loaded and return the child data as a JSON [2] string, the format of which is described further below.

The partial domain provided on instantiation and any asynchronously loaded data will be cached, and this cache checked before any loading takes place.

A "spinner" id may also be provided - this is the id of an element which will be shown when SelectLoader is communicating with the Display Service to indicate to the user that loading is taking place.

Another optional variableparameter is "deselectedValue" - if provided, SelectLoader will clear the child select of its options when a select elementan option whose value matches the given value has been selected in the parent.

var partialDomain = { "1": [ {value: 1, text: "Town 1"},
                             {value: 2, text: "Town 2"},
                             {value: 3, text: "Town 3"}
                           ]
                    };

new SelectLoader({
    parentSelect: document.forms["someForm"].elements["countySelect"],
    childSelect: document.forms["someForm"].elements["townSelect"],
    spinnerId: "townSelectSpinner",
    url: "DisplayService.php?action=GetTownSelectContent&id=",
    cache: partialDomain,
    deselectedValue: 0
});

Returning Data From The Display Service

In the case where child select options were successfully obtained, the Display Service wouldshould return something of the form of:

{"success":true,
 "parentId":1,
 "options":[ {"value":1,"text":"Town 1"},
             {"value":2,"text":"Town 2"},
             {"value":3,"text":"Town 3"}
           ]
}

Otherwise, if there was an error in the Display Service:

{"success":false,
 "errorMessage":"Error message generated by Display Service"}

Notes