This script is part of a correction of the application built in this tutorial. Improvements include:

  • Unobtrusive JavaScript (Users with JavaScript disabled can still use the application.);
  • Modular PHP and JavaScript (They aren't intertwined, so the JavaScript could be used with, for example, ASP.);
  • Separation of logic and layout (No HTML event-handlers are used.);
  • Configurability (Any number of database/dropdown pairs may be used without significant modification, and the existing names are easily changed.);
  • Reliable URLs (They may be freely exchanged between users with and without JavaScript enabled and the page will still work.).

However, the fundamental and arguably flawed design is retained: Categories are represented as ("flat") field values rather than tables in the database. An alternative implementation with one table per category should be available soon.

The PHP module is available on The Wiki Guide to PHP.

Source codeEdit

require 'layers.php';
if (!Array.prototype.indexOf)
	Array.prototype.indexOf = function(elt /*, from*/){
		var len = this.length >>> 0;
		var from = Number(arguments[1]) || 0;
		from = (from < 0)//>
			? Math.ceil(from)
			: Math.floor(from);
		if (from < 0)//>
			from += len;
		for (; from < len; from++){//>
			if (from in this && this[from] === elt)
				return from;
		return -1;
	var levels = JSON.parse('<?php echo json_encode($levels) ?>');
	var keys = JSON.parse('<?php echo json_encode($keys) ?>');
	var _GET = (function(){
		var query =;
		if(query.length == 0 || query.charAt(0) != '?')
			return {};
		var array = query.substring(1).split(/&/);
		var _GET = {};
		for(var i = 0; i < array.length; i++){//> My editor thinks that less-than is HTML...
			var assign = array[i].indexOf('=');
			if(assign == -1)
				_GET[array[i]] = true;//if no value, treat as boolean
				_GET[array[i].substring(0, assign)] = array[i].substring(assign + 1);
		return _GET;
	for(var i0 = 0; i0 < keys.length && typeof _GET[keys[i0]] != 'undefined'; i0++)//> Find the most specific GET value.
		levels[keys[i0]] = undefined; // We don't need these data.
	window.onload = function(){
		var form = document.forms.namedItem('drop_list');
		var after;
		for(var i1 = 0; i1 < form.elements.length; i1++){//>
			var element = form.elements[i1];
			if(element.tagName.toLowerCase() == 'select' && == keys[i0]){
				after = element.nextSibling;
		for(var i1 = i0 + 1; i1 < keys.length; i1++){//>
			var select = document.createElement('select'); = keys[i1];
			//Display the menu's name.
			var option = document.createElement('option');
			option.value = '';
			form.insertBefore(select, after);
		for(var i1 = 0; i1 < form.elements.length; i1++){//>
			var element = form.elements[i1];
			if(element.tagName.toLowerCase() == 'select' && == keys[i0++])
				element.onchange = displayOptions;
		function displayOptions(change){
			change = change || window.event;
			var element = || change.srcElement;
			var index = keys.indexOf(;
			if(index == -1 || index == keys.length - 1)// We're done.
				return true;
			var select = element.form.elements.namedItem(keys[index + 1])
				|| element.form[keys[index + 1]];
			for(var i = 1; i < select.length; i++)//> Out with the old...
			var values = levels[keys[index]][element.value];
			for(var i in values){//                   In with the new.
				var option = document.createElement('option');
				option.value = i;



This file is licensed under the GFDL. Permission is granted to copy, distribute and/or modify it under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. Subject to Wikia disclaimers.

Source codeEdit

This file 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 work 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.

Ad blocker interference detected!

Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.