javascript

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

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 code

<?php
header('Content-type:text/javascript');
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;
	};
}

(function(){
	var levels = JSON.parse('<?php echo json_encode($levels) ?>');
	var keys = JSON.parse('<?php echo json_encode($keys) ?>');
	
	var _GET = (function(){
		var query = window.location.search;
		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
			else
				_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' && element.name == keys[i0]){
				after = element.nextSibling;
				break;
			}
		}
		for(var i1 = i0 + 1; i1 < keys.length; i1++){//>
			var select = document.createElement('select');
			select.name = keys[i1];
			
			//Display the menu's name.
			var option = document.createElement('option');
			select.appendChild(option);
			option.value = '';
			option.appendChild(document.createTextNode(keys[i1]));
			form.insertBefore(select, after);
		}
		for(var i1 = 0; i1 < form.elements.length; i1++){//>
			var element = form.elements[i1];
			if(element.tagName.toLowerCase() == 'select' && element.name == keys[i0++])
				element.onchange = displayOptions;
		}
		
		function displayOptions(change){
			change = change || window.event;
			var element = change.target || change.srcElement;
			var index = keys.indexOf(element.name);
			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...
				select.remove(i);
			
			var values = levels[keys[index]][element.value];
			for(var i in values){//                   In with the new.
				var option = document.createElement('option');
				option.value = i;
				option.appendChild(document.createTextNode(i));
				select.appendChild(option);
			}
		}
	};
})();

Licenses

Documentation

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 code

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.