Selectbox Functions with Javascript

28 March, 2006

These functions allowed you to do commonly-requested actions with select boxes.

For example, you can easily pass values between two select boxes. This makes a nice Windows-style interface for choosing components, adding and removing items from a list, etc. Options are re-ordered as they are added and removed from the lists.

Several other functions are included in the source that are not in the examples. This includes copying items in lists instead of moving them, copying/moving all items, and automatically selecting all items in a list.

DESCRIPTION: These are general functions to deal with and manipulate
select boxes. Also see the OptionTransfer library to more easily
handle transferring options between two lists

COMPATABILITY: These are fairly basic functions – they should work on
all browsers that support Javascript.

Code:
// ——————————————————————-
// hasOptions(obj)
// Utility function to determine if a select object has an options array
// ——————————————————————-
function hasOptions(obj) {
if (obj!=null && obj.options!=null) { return true; }
return false;
}

// ——————————————————————-
// selectUnselectMatchingOptions(select_object,regex,select/unselect,true/false)
// This is a general function used by the select functions below, to
// avoid code duplication
// ——————————————————————-
function selectUnselectMatchingOptions(obj,regex,which,only) {
if (window.RegExp) {
if (which == “select”) {
var selected1=true;
var selected2=false;
}
else if (which == “unselect”) {
var selected1=false;
var selected2=true;
}
else {
return;
}
var re = new RegExp(regex);
if (!hasOptions(obj)) { return; }
for (var i=0; i (b.text+”")) { return 1; }
return 0;
}
);

for (var i=0; i object as follows:
// onDblClick=”moveSelectedOptions(this,this.form.target)
// This way, when the user double-clicks on a value in one box, it
// will be transferred to the other (in browsers that support the
// onDblClick() event handler).
// ——————————————————————-
function moveSelectedOptions(from,to) {
// Unselect matching options, if required
if (arguments.length>3) {
var regex = arguments[3];
if (regex != “”) {
unSelectMatchingOptions(from,regex);
}
}
// Move them over
if (!hasOptions(from)) { return; }
for (var i=0; i=0; i–) {
var o = from.options[i];
if (o.selected) {
from.options[i] = null;
}
}
if ((arguments.length=0; i–) {
if (obj.options[i].selected) {
if (i != (obj.options.length-1) && ! obj.options[i+1].selected) {
swapOptions(obj,i,i+1);
obj.options[i+1].selected = true;
}
}
}
}

// ——————————————————————-
// removeSelectedOptions(select_object)
// Remove all selected options from a list
// (Thanks to Gene Ninestein)
// ——————————————————————-
function removeSelectedOptions(from) {
if (!hasOptions(from)) { return; }
if (from.type==”select-one”) {
from.options[from.selectedIndex] = null;
}
else {
for (var i=(from.options.length-1); i>=0; i–) {
var o=from.options[i];
if (o.selected) {
from.options[i] = null;
}
}
}
from.selectedIndex = -1;
}

// ——————————————————————-
// removeAllOptions(select_object)
// Remove all options from a list
// ——————————————————————-
function removeAllOptions(from) {
if (!hasOptions(from)) { return; }
for (var i=(from.options.length-1); i>=0; i–) {
from.options[i] = null;
}
from.selectedIndex = -1;
}

// ——————————————————————-
// addOption(select_object,display_text,value,selected)
// Add an option to a list
// ——————————————————————-
function addOption(obj,text,value,selected) {
if (obj!=null && obj.options!=null) {
obj.options[obj.options.length] = new Option(text, value, false, selected);
}
}


Dynamic options in Javascript

28 March, 2006

On this page I explain the basics of generating options in a select box and give a script for dynamic options: when the user selects something from one option box another is automatically filled with new data.

First of all some basics on how to create and delete options from a select box, after which it's time for the important topic of object detection. Then it's time for the example, the script and its explanation.
The basics

This is an option box:

first option
second option
third option
your browser can't handle this script

To access options in a select box, you use the following code:

document.forms['testform'].testselect.options[i]

where i is the number of the option you want to access. Remember that the first option is options[0], the second one is options[1] etc.

Now if you want to delete the option, do

document.forms['testform'].testselect.options[i] = null;

By making it null, the option is completely removed from the list. Note that this also affects the numbering of the options. Suppose you remove option[1] from the example above, the old option[2] ('Third option') becomes option[1] etc.

To create a new option, do:

document.forms['testform'].testselect.options[i] = new Option('new text','new value');

where new text is the text the user sees and new value is the VALUE of the new option, the bit that's sent to the server when the form is submitted. Of course the new option overwrites the old one.

To completely clear a select box, do

document.forms['testform'].testselect.options.length = 0;
Object detection

Your browser can't handle this script

As to this cryptic option in the example above, it is for object detection.

One big problem is that you cannot create or delete options in some browsers. Therefore we have to do some object detection to find out if the browser can handle everything.

This is more difficult than usual because the option object itself is supported by all browsers. What we want to know here is if we can add or remove option objects. The trick is to put one extra option in one select box. A script called onLoad tries to remove this option. If, after that, the option's still there the browser has failed its support detect.

This script performs the detect and gives a variable optionTest. If it's false the browser can't handle dynamic options and you should not execute the scripts.

function init()
{
optionTest = true;
lgth = document.forms['testform'].testselect.options.length – 1;
document.forms['testform'].testselect.options[lgth] = null;
if (document.forms['testform'].testselect.options[lgth]) optionTest = false;
}

If you select the place of the test option wisely, the text Your browser can't handle this script informs people with old browsers that they can't use this select box script, while users with modern browsers never see the option since it's removed quickly.
You can also place one in the option if you don't want any text.
Example

Try the example below. The options in the second box are links.

One of the strange things I discovered is that the target select box (the second one) must have a SIZE of more than 1, or else Netscape and Explorer each develop their own bugs.
The script

var store = new Array();

store[0] = new Array(
'HTML Compendium',
'http://www.htmlcompendium.org',
'Web Designer\'s Forum',
'http://www.wdf.net');

store[1] = new Array(
'Web Designer\'s Forum',
'http://www.wdf.net',
'CSS1 Mastergrid',
'http://webreview.com/wr/pub/guides/style/mastergrid.html');

store[2] = new Array(
'Stefan Koch\'s JavaScript Tutorial',
'http://rummelplatz.uni-mannheim.de/~skoch/js/tutorial.htm',
'Client Side JavaScript Reference',
'http://developer.netscape.com/docs/manuals/js/client/jsref/index.htm',
'Web Designer\'s Forum',
'http://www.wdf.net');

function init()
{
optionTest = true;
lgth = document.forms[0].second.options.length – 1;
document.forms[0].second.options[lgth] = null;
if (document.forms[0].second.options[lgth]) optionTest = false;
}

function populate()
{
if (!optionTest) return;
var box = document.forms[0].first;
var number = box.options[box.selectedIndex].value;
if (!number) return;
var list = store[number];
var box2 = document.forms[0].second;
box2.options.length = 0;
for(i=0;i
html
css
javascript

Explanation

First of all, create some arrays that hold the options. Options are stored in name/value pairs.

var store = new Array();

store[0] = new Array(
'HTML Compendium','http://www.htmlcompendium.org',
etc.

Please note that the number of the array corresponds with the value of the option: HTML has value 0 and if it's selected it writes store[0] into the second select box.

Then for the actual script. First check if optionTest is false, if so the script is not executed.

function populate()
{
if (!optionTest) return;

Get the value of the selected option. This should be a number.

For more information about reading out a select box, see the Introduction to forms.

var box = document.forms[0].first;
var number = box.options[box.selectedIndex].value;

If for some reason it doesn't exist, end the function. This gives you the freedom to put empty options in the select boxes (like — Select a category –).

if (!number) return;

Get the correct option list store[number] and put it in list[]. Then access the second select box.

var list = store[number];
var box2 = document.forms[0].second;

Clear the second select box.

box2.options.length = 0;

for(i=0;iExplorer 5.0 problems

When it comes to dynamically generating options and selects, Explorer 5.0 on Windows has quite a few problems:
Generating options in another frame or window doesn't work. Put the script in the page that contains the select. I have heard, but did not test, that this problem still exists in Explorer 6.0
Generating selects and options through the 'pure' W3C DOM (ie. with any document.createElement()) crashes Explorer 5.0 . Solved in 5.5
Generate these selects and options through innerHTML instead.
Generating options from a popup window may crash any Explorer Windows.

I have heard, but did not test, that the script below works fine in IE 5.0:

var doc = select.ownerDocument;
if (!doc)
doc = select.document;
var opt = doc.createElement('OPTION');
opt.value = value;
opt.text = text;
select.options.add(opt, index);


Asynchronous file upload with AJAX progress bar in PHP

27 March, 2006

One of the few things that I find lacking in PHP is the ability to
report the progress of a file upload.upload This means that file uploads,
especially uploads of larger files, can be extremely frustrating for
end users when they don’t know if the upload is progressing or if it
has stalled or if it has even started. There are two ways around this.
One is to patch PHP, Pdoru
provides such a patch. Not everyone can patch PHP though. You can’t use
a patch if you’re on a shared server, if you want to use ready-made
binaries, if you don’t want to risk stability by using a patch or if
you just don’t want to have to remember to apply the patch again every
time you upgrade PHP. The other option is to use a perl script to
receive the file when it’s uploaded. This is the approach used by MegaUpload.
MegaUpload is what I have based my solution on, but I have added
asynchronous file upload support and an AJAX upload progress bar,
instead of the refreshing popup used by MegaUpload.

Asynchronous file upload

I wanted to use an asynchronous file upload, like the one on gmail.
This means that the file is uploaded in the background, allowing you to
still use the page while the file is being uploaded. Since the
XMLHttpRequest object doesn’t support file uploads, this had to be done
using iframes. Whenever the file input changes, the file is uploaded to
the cgi-script in a hidden iframe. The cgi-script writes the total size
of the upload and the actual uploaded file to temporary files.

The progress bar

When the upload starts, a Prototype Ajax.PeriodicalUpdater
object is created. This object calls a PHP file twice every second
using AJAX. The PHP file checks the temporary files while they are
being written by the perl file, and returns the total progress in
percentage of total upload size. The percentage value is used to set
the width of the progress bar.

File & Links

You can download the complete source code here. There is no live demo at this point (sorry!). Similar projects are PHP Upload Progress which can’t report total file size and therefore can’t be used to create a progress bar, and Asynchronous image file upload without AJAX
(seems to be down at the moment) which has asynchronous upload of
files, but no progress bar. Since it always comes up, I’m also going to
mention Filechucker, which is pure perl, doesn’t do asynchronous file uploads and isn’t free.

Limitations & Possible improvements

It can’t currently upload two files concurrently in IE or Firefox,
but it can in Safari. Haven’t tested other browsers. It requires
Prototype at the moment (included in the archive above) which some see
as a downside because of its size. It doesn’t report speed of download.
Upload speed is printed when using MegaUpload, so porting that to work
with this code wouldn’t be difficult.


Hello world!

27 March, 2006

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!