Location: PHPKode > scripts > Form Builder > form-builder/class.form.php
<?
/*
---------------------------------INCLUDE THIS SECTION IN ANY MODIFICATION OR REDISTRIBUTION----------------------------------
Project: Form Builder Class
Author: Andrew Porterfield
Original Release Date: 2009-04-24
License: GPL - for more information visit http://www.gnu.org/licenses/quick-guide-gplv3.html
---------------------------------INCLUDE THIS SECTION IN ANY MODIFICATION OR REDISTRIBUTION----------------------------------
*/

class base {
	/*This class provides two methods - setAttributes and debug - that can be used for all classes that extend this class.*/
	function setAttributes($params) {
		if(!empty($params) && is_array($params))
		{
			foreach($params as $key => $value)
			{
				if(isset($this->$key))	
				{
					if(is_array($this->$key) && !empty($this->$key))
					{
						/*Using array_merge prevents any default values from being overwritten.*/
						$this->$key = array_merge($this->$key, $value);
					}	
					else
						$this->$key = $value;
				}	
				elseif(isset($this->attributes))
					$this->attributes[$key] = $value;
			}
		}
	}

	/*Used for development/testing.*/
	function debug()
	{
		echo("<pre>");
			print_r($this);
		echo("</pre>");
	}
}

class form extends base { 
	/*Variables that can be set through the setAttributes function on the base class.*/
	protected $attributes;
	protected $tableAttributes;
	protected $tdAttributes;
	protected $labelAttributes;
	protected $requiredAttributes;
	protected $jqueryPath;				/*Allows jquery directory's location to be identified.*/
	protected $googleMapsAPIKey;		/*Required for using latlng field type.*/
	protected $map;
	protected $returnUrl;

	/*Variables that can only be set inside this class.*/
	private $elements;
	private $buttons;
	private $jqueryDateArr;
	private $jquerySortArr;
	private $latlngArr;
	private $checkform;
	private $allowedFields;				/*Controls what attributes can be attached to various html elements.*/
	private $stateArr;
	private $countryArr;
	private $mapIndex;
	private $mapCount;
	private $mapOriginalWidth;
	private $referenceValues;			/*Associative array of values to pre-fill form fields.*/

	public function __construct() {
		/*Provide default values for class variables.*/
		$this->attributes = array(
			"name" => "formclass_" . rand(0, 999),
			"method" => "post",
			"action" => basename($_SERVER["SCRIPT_NAME"]),
			"style" => "padding: 0; margin: 0;"
		);
		$this->tableAttributes = array(
			"cellpadding" => "4",
			"cellspacing" => "0",
			"border" => "0"
		);
		$this->tdAttributes = array(
			"valign" => "top",
			"align" => "left"
		);
		$this->labelAttributes = array();
		$this->requiredAttributes = array();
		$this->jqueryPath = "jquery";
		$this->googleMapsAPIKey = "";
		$this->map = array();
		$this->returnUrl = "";

		$this->elements = array();
		$this->buttons = array();
		$this->jqueryDateArr = array();
		$this->jquerySortArr = array();
		$this->latlngArr = array();
		$this->checkform = "";
		/*This array prevents junk from being inserted into the form's HTML.  If you find that an attributes you need to use is not included
		in this list, feel free to customize to fit your needs.*/
		$this->allowedFields = array(
			"form" => array("method", "action", "enctype", "onsubmit", "id", "class", "name"),
			"table" => array("cellpadding", "cellspacing", "border", "style", "id", "class", "name", "align", "width"),
			"td" => array("id", "name", "valign", "align", "style", "id", "class", "width"),
			"div" => array("id", "name", "valign", "align", "style", "id", "class"),
			"span" => array("id", "name", "valign", "align", "style", "id", "class"),
			"hidden" => array("id", "name", "value", "type"),
			"text" => array("id", "name", "value", "type", "class", "style", "onclick", "onkeyup", "maxlength", "size"),
			"file" => array("id", "name", "value", "type", "class", "style", "onclick", "onkeyup", "maxlength", "size"),
			"textarea" => array("id", "name", "class", "style", "onclick", "onkeyup", "maxlength", "size", "rows", "cols"),
			"select" => array("id", "name", "class", "style", "onclick", "onchange", "size"),
			"radio" => array("name", "style", "class", "onclick", "type"),
			"checkbox" => array("name", "style", "class", "onclick", "type"),
			"date" => array("id", "name", "value", "type", "class", "style", "onclick", "onkeyup", "maxlength", "size"),
			"button" => array("name", "value", "type", "id", "onclick", "class", "style"),
			"a" => array("id", "name", "href", "class", "style"),
			"latlng" => array("id", "name", "type", "class", "style", "onclick", "onkeyup", "maxlength", "size")
		);
		$this->stateArr = array();
		$this->countryArr = array();
		$this->mapIndex = 0;
		$this->mapCount = 0;
		$this->mapOriginalWidth = 0;
		$this->referenceValues = "";
	}

	/*Creates new element opbject instances and attaches them to the form object.  This function is private and can only be called inside this class.*/
	private function attachElement($params)
	{
		$ele = new element();
		$ele->setAttributes($params);
		$eleType = &$ele->attributes["type"];

		if($eleType == "state")
		{
			/*This section prevents the stateArr from being generated for each form and/or multiple state field types per form.*/
			$eleType = "select";
			if(empty($this->stateArr))
			{
				$this->stateArr = array(
					array("key" => "", "value" => "--Select a State/Province--"),
					array("key" => "AL", "value" => "Alabama"),
					array("key" => "AK", "value" => "Alaska"),
					array("key" => "AZ", "value" => "Arizona"),
					array("key" => "AR", "value" => "Arkansas"),
					array("key" => "CA", "value" => "California"),
					array("key" => "CO", "value" => "Colorado"),
					array("key" => "CT", "value" => "Connecticut"),
					array("key" => "DE", "value" => "Delaware"),
					array("key" => "DC", "value" => "District of Columbia"),
					array("key" => "FL", "value" => "Florida"),
					array("key" => "GA", "value" => "Georgia"),
					array("key" => "HI", "value" => "Hawaii"),
					array("key" => "ID", "value" => "Idaho"),
					array("key" => "IL", "value" => "Illinois"),
					array("key" => "IN", "value" => "Indiana"),
					array("key" => "IA", "value" => "Iowa"),
					array("key" => "KS", "value" => "Kansas"),
					array("key" => "KY", "value" => "Kentucky"),
					array("key" => "LA", "value" => "Louisiana"),
					array("key" => "ME", "value" => "Maine"),
					array("key" => "MD", "value" => "Maryland"),
					array("key" => "MA", "value" => "Massachusetts"),
					array("key" => "MI", "value" => "Michigan"),
					array("key" => "MN", "value" => "Minnesota"),
					array("key" => "MS", "value" => "Mississippi"),
					array("key" => "MO", "value" => "Missouri"),
					array("key" => "MT", "value" => "Montana"),
					array("key" => "NE", "value" => "Nebraska"),
					array("key" => "NV", "value" => "Nevada"),
					array("key" => "NH", "value" => "New Hampshire"),
					array("key" => "NJ", "value" => "New Jersey"),
					array("key" => "NM", "value" => "New Mexico"),
					array("key" => "NY", "value" => "New York"),
					array("key" => "NC", "value" => "North Carolina"),
					array("key" => "ND", "value" => "North Dakota"),
					array("key" => "OH", "value" => "Ohio"),
					array("key" => "OK", "value" => "Oklahoma"),
					array("key" => "OR", "value" => "Oregon"),
					array("key" => "PA", "value" => "Pennsylvania"),
					array("key" => "RI", "value" => "Rhode Island"),
					array("key" => "SC", "value" => "South Carolina"),
					array("key" => "SD", "value" => "South Dakota"),
					array("key" => "TN", "value" => "Tennessee"),
					array("key" => "TX", "value" => "Texas"),
					array("key" => "UT", "value" => "Utah"),
					array("key" => "VT", "value" => "Vermont"),
					array("key" => "VA", "value" => "Virginia"),
					array("key" => "WA", "value" => "Washington"),
					array("key" => "WV", "value" => "West Virginia"),
					array("key" => "WI", "value" => "Wisconsin"),
					array("key" => "WY", "value" => "Wyoming"),
					array("key" => "", "value" => ""),
					array("key" => "", "value" => "-- Canadian Province--"),
					array("key" => "AB", "value" => "Alberta"),
					array("key" => "BC", "value" => "British Columbia"),
					array("key" => "MB", "value" => "Manitoba"),
					array("key" => "NB", "value" => "New Brunswick"),
					array("key" => "NL", "value" => "Newfoundland and Labrador"),
					array("key" => "NS", "value" => "Nova Scotia"),
					array("key" => "NT", "value" => "Northwest Territories"),
					array("key" => "NU", "value" => "Nunavut"),
					array("key" => "ON", "value" => "Ontario"),
					array("key" => "PE", "value" => "Prince Edward Island"),
					array("key" => "QC", "value" => "Qu&#233;bec"),
					array("key" => "SK", "value" => "Saskatchewan"),
					array("key" => "YT", "value" => "Yukon"),
					array("key" => "", "value" => ""),
					array("key" => "", "value" => "-- US Territories--"),
					array("key" => "AS", "value" => "American Samoa"),
					array("key" => "FM", "value" => "Federated States of Micronesia"),
					array("key" => "GU", "value" => "Guam"),
					array("key" => "MH", "value" => "Marshall Islands"),
					array("key" => "PW", "value" => "Palau"),
					array("key" => "PR", "value" => "Puerto Rico"),
					array("key" => "VI", "value" => "Virgin Islands")
				);
			}
			$ele->options = array();
			$stateSize = sizeof($this->stateArr);
			for($s = 0; $s < $stateSize; ++$s)
			{
				$opt = new option();
				$opt->setAttributes($this->stateArr[$s]);
				$ele->options[] = $opt;
			}
		}	
		elseif($eleType == "country")
		{
			/*This section prevents the countryArr from being generated for each form and/or multiple country field types per form.*/
			$eleType = "select";
			if(empty($this->countryArr))
			{
				$this->countryArr = array(
					array("key" => "", "value" => "--Select a Country--"),
					array("key" => "US", "value" => "United States"),
					array("key" => "AF", "value" => "Afghanistan"),
					array("key" => "AL", "value" => "Albania"),
					array("key" => "DZ", "value" => "Algeria"),
					array("key" => "AS", "value" => "American Samoa"),
					array("key" => "AD", "value" => "Andorra"),
					array("key" => "AO", "value" => "Angola"),
					array("key" => "AI", "value" => "Anguilla"),
					array("key" => "AG", "value" => "Antigua and Barbuda"),
					array("key" => "AR", "value" => "Argentina"),
					array("key" => "AM", "value" => "Armenia"),
					array("key" => "AW", "value" => "Aruba"),
					array("key" => "AU", "value" => "Australia"),
					array("key" => "AT", "value" => "Austria"),
					array("key" => "AZ", "value" => "Azerbaijan"),
					array("key" => "BS", "value" => "Bahamas"),
					array("key" => "BH", "value" => "Bahrain"),
					array("key" => "BD", "value" => "Bangladesh"),
					array("key" => "BB", "value" => "Barbados"),
					array("key" => "BY", "value" => "Belarus"),
					array("key" => "BE", "value" => "Belgium"),
					array("key" => "BZ", "value" => "Belize"),
					array("key" => "BJ", "value" => "Benin"),
					array("key" => "BM", "value" => "Bermuda"),
					array("key" => "BT", "value" => "Bhutan"),
					array("key" => "BO", "value" => "Bolivia"),
					array("key" => "BA", "value" => "Bosnia and Herzegowina"),
					array("key" => "BW", "value" => "Botswana"),
					array("key" => "BR", "value" => "Brazil"),
					array("key" => "IO", "value" => "British Indian Ocean Territory"),
					array("key" => "BN", "value" => "Brunei Darussalam"),
					array("key" => "BG", "value" => "Bulgaria"),
					array("key" => "BF", "value" => "Burkina Faso"),
					array("key" => "BI", "value" => "Burundi"),
					array("key" => "KH", "value" => "Cambodia"),
					array("key" => "CM", "value" => "Cameroon"),
					array("key" => "CA", "value" => "Canada"),
					array("key" => "CV", "value" => "Cape Verde"),
					array("key" => "KY", "value" => "Cayman Islands"),
					array("key" => "CF", "value" => "Central African Republic"),
					array("key" => "TD", "value" => "Chad"),
					array("key" => "CL", "value" => "Chile"),
					array("key" => "CN", "value" => "China"),
					array("key" => "CO", "value" => "Colombia"),
					array("key" => "CG", "value" => "Congo"),
					array("key" => "CK", "value" => "Cook Islands"),
					array("key" => "CR", "value" => "Costa Rica"),
					array("key" => "CI", "value" => "Cote d'Ivoire"),
					array("key" => "HR", "value" => "Croatia"),
					array("key" => "CY", "value" => "Cyprus"),
					array("key" => "CZ", "value" => "Czech Republic"),
					array("key" => "DK", "value" => "Denmark"),
					array("key" => "DJ", "value" => "Djibouti"),
					array("key" => "DM", "value" => "Dominica"),
					array("key" => "DO", "value" => "Dominican Republic"),
					array("key" => "EC", "value" => "Ecuador"),
					array("key" => "EG", "value" => "Egypt"),
					array("key" => "SV", "value" => "El Salvador"),
					array("key" => "GQ", "value" => "Equatorial Guinea"),
					array("key" => "ER", "value" => "Eritrea"),
					array("key" => "EE", "value" => "Estonia"),
					array("key" => "ET", "value" => "Ethiopia"),
					array("key" => "FO", "value" => "Faroe Islands"),
					array("key" => "FJ", "value" => "Fiji"),
					array("key" => "FI", "value" => "Finland"),
					array("key" => "FR", "value" => "France"),
					array("key" => "GF", "value" => "French Guiana"),
					array("key" => "PF", "value" => "French Polynesia"),
					array("key" => "GA", "value" => "Gabon"),
					array("key" => "GM", "value" => "Gambia"),
					array("key" => "GE", "value" => "Georgia"),
					array("key" => "DE", "value" => "Germany"),
					array("key" => "GH", "value" => "Ghana"),
					array("key" => "GI", "value" => "Gibraltar"),
					array("key" => "GR", "value" => "Greece"),
					array("key" => "GL", "value" => "Greenland"),
					array("key" => "GD", "value" => "Grenada"),
					array("key" => "GP", "value" => "Guadeloupe"),
					array("key" => "GU", "value" => "Guam"),
					array("key" => "GT", "value" => "Guatemala"),
					array("key" => "GN", "value" => "Guinea"),
					array("key" => "GW", "value" => "Guinea-Bissau"),
					array("key" => "GY", "value" => "Guyana"),
					array("key" => "HT", "value" => "Haiti"),
					array("key" => "HM", "value" => "Heard Island And Mcdonald Islands"),
					array("key" => "HK", "value" => "Hong Kong"),
					array("key" => "HU", "value" => "Hungary"),
					array("key" => "IS", "value" => "Iceland"),
					array("key" => "IN", "value" => "India"),
					array("key" => "ID", "value" => "Indonesia"),
					array("key" => "IR", "value" => "Iran, Islamic Republic Of"),
					array("key" => "IL", "value" => "Israel"),
					array("key" => "IT", "value" => "Italy"),
					array("key" => "JM", "value" => "Jamaica"),
					array("key" => "JP", "value" => "Japan"),
					array("key" => "JO", "value" => "Jordan"),
					array("key" => "KZ", "value" => "Kazakhstan"),
					array("key" => "KE", "value" => "Kenya"),
					array("key" => "KI", "value" => "Kiribati"),
					array("key" => "KP", "value" => "Korea, Democratic People's Republic Of"),
					array("key" => "KW", "value" => "Kuwait"),
					array("key" => "KG", "value" => "Kyrgyzstan"),
					array("key" => "LA", "value" => "Lao People's Democratic Republic"),
					array("key" => "LV", "value" => "Latvia"),
					array("key" => "LB", "value" => "Lebanon"),
					array("key" => "LS", "value" => "Lesotho"),
					array("key" => "LR", "value" => "Liberia"),
					array("key" => "LI", "value" => "Liechtenstein"),
					array("key" => "LT", "value" => "Lithuania"),
					array("key" => "LU", "value" => "Luxembourg"),
					array("key" => "MO", "value" => "Macau"),
					array("key" => "MK", "value" => "Macedonia, The Former Yugoslav Republic Of"),
					array("key" => "MG", "value" => "Madagascar"),
					array("key" => "MW", "value" => "Malawi"),
					array("key" => "MY", "value" => "Malaysia"),
					array("key" => "MV", "value" => "Maldives"),
					array("key" => "ML", "value" => "Mali"),
					array("key" => "MT", "value" => "Malta"),
					array("key" => "MH", "value" => "Marshall Islands"),
					array("key" => "MQ", "value" => "Martinique"),
					array("key" => "MR", "value" => "Mauritania"),
					array("key" => "MU", "value" => "Mauritius"),
					array("key" => "MX", "value" => "Mexico"),
					array("key" => "FM", "value" => "Micronesia, Federated States Of"),
					array("key" => "MD", "value" => "Moldova, Republic Of"),
					array("key" => "MC", "value" => "Monaco"),
					array("key" => "MN", "value" => "Mongolia"),
					array("key" => "MS", "value" => "Montserrat"),
					array("key" => "MA", "value" => "Morocco"),
					array("key" => "MZ", "value" => "Mozambique"),
					array("key" => "NA", "value" => "Namibia"),
					array("key" => "NP", "value" => "Nepal"),
					array("key" => "NL", "value" => "Netherlands"),
					array("key" => "AN", "value" => "Netherlands Antilles"),
					array("key" => "NC", "value" => "New Caledonia"),
					array("key" => "NZ", "value" => "New Zealand"),
					array("key" => "NI", "value" => "Nicaragua"),
					array("key" => "NE", "value" => "Niger"),
					array("key" => "NG", "value" => "Nigeria"),
					array("key" => "NF", "value" => "Norfolk Island"),
					array("key" => "MP", "value" => "Northern Mariana Islands"),
					array("key" => "NO", "value" => "Norway"),
					array("key" => "OM", "value" => "Oman"),
					array("key" => "PK", "value" => "Pakistan"),
					array("key" => "PW", "value" => "Palau"),
					array("key" => "PA", "value" => "Panama"),
					array("key" => "PG", "value" => "Papua New Guinea"),
					array("key" => "PY", "value" => "Paraguay"),
					array("key" => "PE", "value" => "Peru"),
					array("key" => "PH", "value" => "Philippines"),
					array("key" => "PL", "value" => "Poland"),
					array("key" => "PT", "value" => "Portugal"),
					array("key" => "PR", "value" => "Puerto Rico"),
					array("key" => "QA", "value" => "Qatar"),
					array("key" => "RE", "value" => "Reunion"),
					array("key" => "RO", "value" => "Romania"),
					array("key" => "RU", "value" => "Russian Federation"),
					array("key" => "RW", "value" => "Rwanda"),
					array("key" => "KN", "value" => "Saint Kitts and Nevis"),
					array("key" => "LC", "value" => "Saint Lucia"),
					array("key" => "VC", "value" => "Saint Vincent and the Grenadines"),
					array("key" => "WS", "value" => "Samoa"),
					array("key" => "SM", "value" => "San Marino"),
					array("key" => "SA", "value" => "Saudi Arabia"),
					array("key" => "SN", "value" => "Senegal"),
					array("key" => "SC", "value" => "Seychelles"),
					array("key" => "SL", "value" => "Sierra Leone"),
					array("key" => "SG", "value" => "Singapore"),
					array("key" => "SK", "value" => "Slovakia"),
					array("key" => "SI", "value" => "Slovenia"),
					array("key" => "SB", "value" => "Solomon Islands"),
					array("key" => "SO", "value" => "Somalia"),
					array("key" => "ZA", "value" => "South Africa"),
					array("key" => "ES", "value" => "Spain"),
					array("key" => "LK", "value" => "Sri Lanka"),
					array("key" => "SD", "value" => "Sudan"),
					array("key" => "SR", "value" => "Suriname"),
					array("key" => "SZ", "value" => "Swaziland"),
					array("key" => "SE", "value" => "Sweden"),
					array("key" => "CH", "value" => "Switzerland"),
					array("key" => "SY", "value" => "Syrian Arab Republic"),
					array("key" => "TW", "value" => "Taiwan, Province Of China"),
					array("key" => "TJ", "value" => "Tajikistan"),
					array("key" => "TZ", "value" => "Tanzania, United Republic Of"),
					array("key" => "TH", "value" => "Thailand"),
					array("key" => "TG", "value" => "Togo"),
					array("key" => "TO", "value" => "Tonga"),
					array("key" => "TT", "value" => "Trinidad and Tobago"),
					array("key" => "TN", "value" => "Tunisia"),
					array("key" => "TR", "value" => "Turkey"),
					array("key" => "TM", "value" => "Turkmenistan"),
					array("key" => "TC", "value" => "Turks and Caicos Islands"),
					array("key" => "TV", "value" => "Tuvalu"),
					array("key" => "UG", "value" => "Uganda"),
					array("key" => "UA", "value" => "Ukraine"),
					array("key" => "AE", "value" => "United Arab Emirates"),
					array("key" => "GB", "value" => "United Kingdom"),
					array("key" => "UY", "value" => "Uruguay"),
					array("key" => "UZ", "value" => "Uzbekistan"),
					array("key" => "VU", "value" => "Vanuatu"),
					array("key" => "VE", "value" => "Venezuela"),
					array("key" => "VN", "value" => "Vietnam"),
					array("key" => "VG", "value" => "Virgin Islands (British)"),
					array("key" => "VI", "value" => "Virgin Islands (U.S.)"),
					array("key" => "WF", "value" => "Wallis and Futuna Islands"),
					array("key" => "EH", "value" => "Western Sahara"),
					array("key" => "YE", "value" => "Yemen"),
					array("key" => "YU", "value" => "Yugoslavia"),
					array("key" => "ZM", "value" => "Zambia"),
					array("key" => "ZR", "value" => "Zaire"),
					array("key" => "ZW", "value" => "Zimbabwe")
				);
			}
			$ele->options = array();
			$countrySize = sizeof($this->countryArr);
			for($s = 0; $s < $countrySize; ++$s)
			{
				$opt = new option();
				$opt->setAttributes($this->countryArr[$s]);
				$ele->options[] = $opt;
			}
		}
		elseif($eleType == "yesno")
		{
			$eleType = "radio";
			$ele->options = array();
			$opt = new option();
			$opt->setAttributes(array("key" => "1", "value" => "Yes"));
			$ele->options[] = $opt;
			$opt = new option();
			$opt->setAttributes(array("key" => "0", "value" => "No"));
			$ele->options[] = $opt;
		}
		elseif($eleType == "truefalse")
		{
			$eleType = "radio";
			$ele->options = array();
			$opt = new option();
			$opt->setAttributes(array("key" => "1", "value" => "True"));
			$ele->options[] = $opt;
			$opt = new option();
			$opt->setAttributes(array("key" => "0", "value" => "False"));
			$ele->options[] = $opt;
		}
		else
		{
			/*Various form types (select, radio, check, sort) use the options parameter to handle multiple choice elements.*/
			if(array_key_exists("options", $params))
			{
				$ele->options = array();
				foreach($params["options"] as $key => $value)
				{
					$opt = new option();
					$opt->setAttributes(array("key" => $key, "value" => $value));
					$ele->options[] = $opt;
				}
			}

			/*If there is a file field type in the form, make sure that the encytype is set accordingly.*/
			if($eleType == "file")
				$this->attributes["enctype"] = "multipart/form-data";
		}

		/*If there is a required field type in the form, make sure javascript error checking is enabled.*/
		if(!empty($ele->required) && empty($this->checkform))
			$this->checkform = 1;
		
		$this->elements[] = $ele;
	}
	
	/*-------------------------------------------START: HOW USERS CAN ADD FORM FIELDS--------------------------------------------*/

	/*addElements allows users to add multiple form elements by passing a multi-dimensional array.*/
	public function addElements($params)
	{
		$paramSize = sizeof($params);
		for($i = 0; $i < $paramSize; ++$i)
			$this->attachElement($params[$i]);
	}

	/*addElement allows users to add a single form element by passing an array.*/
	public function addElement($label, $name, $type="", $value="", $additionalParams="")
	{
		$params = array("label" => $label, "name" => $name);
		if(!empty($type))
			$params["type"] = $type;
		if(!empty($value))
			$params["value"] = $value;
			
		/*Commonly used attributes such as name, type, and value exist as parameters in the function.  All other attributes
		that need to be included should be passed in the additionalParams field.  This field should exist as an associative
		array with the key being the attribute's name.  Examples of attributes passed in the additionalParams field include
		style, class, and onkeyup.*/	
		if(!empty($additionalParams) && is_array($additionalParams))
		{
			foreach($additionalParams as $key => $value)
				$params[$key] = $value;
		}
		$this->attachElement($params);
	}

	/*The remaining function are shortcuts for adding each supported form field.*/
	public function addHidden($name, $value="", $additionalParams="") {
		$this->addElement("", $name, "hidden", $value, $additionalParams);
	}
	public function addTextbox($label, $name, $value="", $additionalParams="") {
		$this->addElement($label, $name, "text", $value, $additionalParams);
	}
	public function addTextarea($label, $name, $value="", $additionalParams="") {
		$this->addElement($label, $name, "textarea", $value, $additionalParams);
	}
	public function addPassword($label, $name, $value="", $additionalParams="") {
		$this->addElement($label, $name, "password", $value, $additionalParams);
	}
	public function addFile($label, $name, $value="", $additionalParams="") {
		$this->addElement($label, $name, "file", $value, $additionalParams);
	}
	public function addDate($label, $name, $value="", $additionalParams="") {
		$this->addElement($label, $name, "date", $value, $additionalParams);
	}
	public function addState($label, $name, $value="", $additionalParams="") {
		$this->addElement($label, $name, "state", $value, $additionalParams);
	}
	public function addCountry($label, $name, $value="", $additionalParams="") {
		$this->addElement($label, $name, "country", $value, $additionalParams);
	}
	public function addYesNo($label, $name, $value="", $additionalParams="") {
		$this->addElement($label, $name, "yesno", $value, $additionalParams);
	}
	public function addTrueFalse($label, $name, $value="", $additionalParams="") {
		$this->addElement($label, $name, "truefalse", $value, $additionalParams);
	}
	public function addSelectbox($label, $name, $value="", $options="", $additionalParams="") {
		if(!is_array($additionalParams))
			$additionalParams = array();
		$additionalParams["options"] = $options;	
		$this->addElement($label, $name, "select", $value, $additionalParams);
	}
	public function addRadio($label, $name, $value="", $options="", $additionalParams="") {
		if(!is_array($additionalParams))
			$additionalParams = array();
		$additionalParams["options"] = $options;	
		$this->addElement($label, $name, "radio", $value, $additionalParams);
	}
	public function addCheckbox($label, $name, $value="", $options="", $additionalParams="") {
		if(!is_array($additionalParams))
			$additionalParams = array();
		$additionalParams["options"] = $options;	
		$this->addElement($label, $name, "checkbox", $value, $additionalParams);
	}
	public function addSort($label, $name, $options="", $additionalParams="") {
		if(!is_array($additionalParams))
			$additionalParams = array();
		$additionalParams["options"] = $options;	
		$this->addElement($label, $name, "sort", "", $additionalParams);
	}
	public function addLatLng($label, $name, $value="", $additionalParams="") {
		$this->addElement($label, $name, "latlng", $value, $additionalParams);
	}
	/*-------------------------------------------END: HOW USERS CAN ADD FORM FIELDS--------------------------------------------*/

	/*This function can be called to clear all attached element object instances from the form - beneficial when using the elementsToString function.*/
	public function clearElements() {
		$this->elements = array();
	}

	/*This function creates new button object instances and attaches them to the form.  It is private and can only be used inside this class.*/
	private function attachButton($params)
	{
		$button = new button();
		$button->setAttributes($params);
		$this->buttons[] = $button;
	}

	/*This function allows users to add multiple button object instances to the form by passing a multi-dimensional array.*/
	public function addButtons($params)
	{
		$paramSize = sizeof($params);
		for($i = 0; $i < $paramSize; ++$i)
			$this->attachButton($params[$i]);
	}

	/*This function allows users to add a single button object instance to the form by passing an array.*/
	function addButton($value="Submit", $type="submit", $additionalParams="")
	{
		$params = array("value" => $value, "type" => $type);

		/*The additionalParams performs a similar role as in the addElement function.  For more information, please read to description
		of this field in the addElement function.  Commonly used attributes included for additionalParams in this function include
		onclick.*/
		if(!empty($additionalParams) && is_array($additionalParams))
		{
			foreach($additionalParams as $key => $value)
				$params[$key] = $value;
		}
		$this->attachButton($params);
	}

	/*This function renders the form's HTML.*/
	public function render()
	{
		ob_start();
		echo("<form");
		$tmpAllowFieldArr = $this->allowedFields["form"];
		foreach($this->attributes as $key => $value)
		{
			if($key == "onsubmit" && !empty($this->checkform))
				continue;
			if(in_array($key, $tmpAllowFieldArr))
				echo ' ', $key, '="', $value, '"';
		}	
			
		if(!empty($this->checkform))	
			echo ' onsubmit="return check_', $this->attributes["name"], '(this);"';
		echo(">\n");

		echo("<table");
		$tmpAllowFieldArr = $this->allowedFields["table"];
		foreach($this->tableAttributes as $key => $value)
		{
			if(in_array($key, $tmpAllowFieldArr))
				echo ' ', $key, '="', $value, '"';
		}		
		echo(">\n");

		/*Render the elements by calling elementsToString function with the includeTable tags field set to false.  There is no need
		to render the table tag b/c we have just done that above.*/
		echo($this->elementsToString(false));

		/*If there are buttons included, render those to the screen now.*/
		if(!empty($this->buttons))
		{
			echo "\t", '<tr><td align="right"';
			$tmpAllowFieldArr = $this->allowedFields["td"];
			foreach($this->tdAttributes as $key => $value)
			{
				if($key != "align" && in_array($key, $tmpAllowFieldArr))
					echo ' ', $key, '="', $value, '"';
			}		
			echo(">\n");
			$buttonSize = sizeof($this->buttons);
			for($i = 0; $i < $buttonSize; ++$i)
			{
				if(!empty($this->buttons[$i]->wrapLink))
				{
					echo("\t\t<a");
					$tmpAllowFieldArr = $this->allowedFields["a"];
					foreach($this->buttons[$i]->linkAttributes as $key => $value)
					{
						if(in_array($key, $tmpAllowFieldArr))
							echo ' ', $key, '="', $value, '"';
					}		
					echo(">");
				}
				else
					echo("\t");

				if(!empty($this->buttons[$i]->phpFunction))
				{
					$execStr = $this->buttons[$i]->phpFunction . "(";
					if(!empty($this->buttons[$i]->phpParams))
					{
						if(is_array($this->buttons[$i]->phpParams))
						{
							$buttonSize = sizeof($this->buttons[$i]->phpParams);
							for($p = 0; $p < $buttonSize; ++$p)
							{
								if($p != 0)
									$execStr .= ",";

								if(is_string($this->buttons[$i]->phpParams[$p]))	
									$execStr .= '"' . $this->buttons[$i]->phpParams[$p] . '"';
								else	
									$execStr .= $this->buttons[$i]->phpParams[$p];	
							}
						}
						else
							$execStr .= $this->buttons[$i]->phpParams;
					}
					$execStr .= ");";
					echo(eval("return " . $execStr));
				}
				else
				{
					if(empty($this->buttons[$i]->wrapLink))
						echo("\t");
					echo("<input");
					$tmpAllowFieldArr = $this->allowedFields["button"];
					foreach($this->buttons[$i]->attributes as $key => $value)
					{
						if(in_array($key, $tmpAllowFieldArr))
							echo " ", $key, '="', htmlentities($value, ENT_COMPAT), '"';
					}		
					echo("/>");
				}

				if(!empty($this->buttons[$i]->wrapLink))
					echo("</a>");
				
				echo("\n");
			}
			echo("\t</td></tr>\n");
		}
		echo("</table>\n");

		echo("</form>\n\n");

		/*
		If there are any required fields in the form, build a javascript function for performing form validation before submission.
		To save from calling the echo function multiple times and from inserting the appropriate new lines (\n) and tabs (\t) for indention,
		single quotes were used - which unfortunately makes this section hard to read.  Future releases may inclde a modified version of this section.
		*/
		if(!empty($this->checkform))
		{
			?>
<script language="javascript">
function check_<?=$this->attributes["name"]?>(formObj)
{
<?
$elementSize = sizeof($this->elements);
for($i = 0; $i < $elementSize; ++$i)
{
	$ele = $this->elements[$i];
	$eleType = $ele->attributes["type"];
	if(!empty($ele->required))
	{
		if($eleType == "checkbox")
		{
			echo 'if(formObj.elements["', $ele->attributes["name"], '"].length)
	{
		var is_checked = false;
		for(i = 0; i < formObj.elements["', $ele->attributes["name"], '"].length; i++)
		{
			if(formObj.elements["', $ele->attributes["name"], '"][i].checked)
				is_checked = true;
		}
		
		if(!is_checked)
		{
			alert("', $ele->label, ' is a required field.");
			return false;
		}
	}
	else if(!formObj.elements["', $ele->attributes["name"], '"].checked)
	{
		alert("', $ele->label, ' is a required field.");
		return false;
	}';
		}
		elseif($eleType == "text" || $eleType == "textarea" || $eleType == "select" || $eleType == "hidden" || $eleType == "file" || $eleType == "password")
		{
			echo 'if(formObj.elements["', $ele->attributes["name"], '"].value == "")
	{		
		alert("', $ele->label, ' is a required field.");
		formObj.elements["', $ele->attributes["name"], '"].focus();
		return false;
	}
';
		}
		elseif($eleType == "date")
		{
			echo 'if(formObj.elements["', $ele->attributes["name"], '"].value == "Click to Select Date...")
	{		
		alert("', $ele->label, ' is a required field.");
		formObj.elements["', $ele->attributes["name"], '"].focus();
		return false;
	}
';
		}
		elseif($eleType == "latlng")
		{
			echo 'if(formObj.elements["', $ele->attributes["name"], '"].value == "Drag Map Marker to Select Location...")
	{		
		alert("', $ele->label, ' is a required field.");
		formObj.elements["', $ele->attributes["name"], '"].focus();
		return false;
	}
';
		}
	}
}	
echo("\n\treturn true;\n");
?>
}
</script>
			<?
			echo("\n\n");
		}


		$content = ob_get_contents();
		ob_end_clean();
		if($return)
			return $content;
		else
			echo($content);
	}

	/*This function builds and returns a string containing the HTML for the form fields.  Typeically, this will be called from within the render() function; however, it can also be called by the user during unique situations.*/
	public function elementsToString($includeTableTags = true)
	{
		$str = "";
		/*If this map array is set, an additional table will be inserted in each row - this way colspans can be omitted.*/
		if(!empty($this->map))
		{
			if($includeTableTags)
				$str .= "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n";
			if(!empty($this->tdAttributes["width"]))
				$this->mapOriginalWidth = $this->tdAttributes["width"];
		}	
		else
		{
			if($includeTableTags)
			{
				$str .= "<table";
				$tmpAllowFieldArr = $this->allowedFields["table"];
				foreach($this->tableAttributes as $key => $value)
				{
					if(in_array($key, $tmpAllowFieldArr))
						$str .= ' ' . $key . '="' . $value . '"';
				}		
				$str .= ">\n";
			}
			
		}

		$elementSize = sizeof($this->elements);
		for($i = 0; $i < $elementSize; ++$i)
		{
			$ele = $this->elements[$i];

			/*If the referenceValues array is filled, check for this specific elemet's name in the associative array key and populate the field's value if applicable.*/
			if(!empty($this->referenceValues) && is_array($this->referenceValues) && array_key_exists($ele->attributes["name"], $this->referenceValues))
				$ele->attributes["value"] = $this->referenceValues[$ele->attributes["name"]];

			/*Hidden values do not need to be inside any table cell container; therefore, they are handled differently than the other fields.*/
			if($ele->attributes["type"] == "hidden")
			{
				$str .= "\t<input";
				$tmpAllowFieldArr = $this->allowedFields["hidden"];
				foreach($ele->attributes as $key => $value)
				{
					if(in_array($key, $tmpAllowFieldArr))
						$str .= ' ' . $key . '="' . htmlentities($value, ENT_COMPAT) . '"';
				}		
				$str .= "/>\n";
			}
			else
			{
				if(!empty($this->map))
				{
					if(array_key_exists($this->mapIndex, $this->map) && $this->map[$this->mapIndex] > 1)
					{
						if($this->mapCount == 0)
						{
							$str .= "\t<tr><td>\n";
							$str .= "\t\t<table";
							$tmpAllowFieldArr = $this->allowedFields["table"];
							foreach($this->tableAttributes as $key => $value)
							{
								if(in_array($key, $tmpAllowFieldArr))
									$str .= ' ' . $key . '="' . $value . '"';
							}		
							$str .= ">\n";
							$str .= "\t\t\t<tr>\n\t\t\t\t";

							/*Widths are percentage based and are calculated by dividing 100 by the number of form fields in the given row.*/
							if(($elementSize - $i) < $this->map[$this->mapIndex])
								$this->tdAttributes["width"] = number_format(100 / ($elementSize - $i), 2, ".", "") . "%";
							else
								$this->tdAttributes["width"] = number_format(100 / $this->map[$this->mapIndex], 2, ".", "") . "%";
						}	
						else
							$str .= "\t\t\t\t";
					}
					else
					{
						$str .= "\t<tr><td>\n";
						$str .= "\t\t<table";
						$tmpAllowFieldArr = $this->allowedFields["table"];
						foreach($this->tableAttributes as $key => $value)
						{
							if(in_array($key, $tmpAllowFieldArr))
								$str .= ' ' . $key . '="' . $value . '"';
						}		
						$str .= ">\n";
						$str .= "\t\t\t<tr>\n\t\t\t\t";
						if(!empty($this->mapOriginalWidth))
							$this->tdAttributes["width"] = $this->mapOriginalWidth;
						else
							unset($this->tdAttributes["width"]);
					}	
				}
				else
					$str .= "\t<tr>";

				$str .= "<td";
				$tmpAllowFieldArr = $this->allowedFields["td"];
				foreach($this->tdAttributes as $key => $value)
				{
					if(in_array($key, $tmpAllowFieldArr))
						$str .= ' ' . $key . '="' . $value . '"';
				}		
				$str .= ">\n";

				if(!empty($ele->label))
				{
					$str .= "\t\t";
					if(!empty($this->map))
						$str .= "\t\t\t";

					/*Render the label inside a <div> tag.*/	
					$str .= "<div";
					$tmpAllowFieldArr = $this->allowedFields["div"];
					foreach($this->labelAttributes as $key => $value)
					{
						if(in_array($key, $tmpAllowFieldArr))
							$str .= ' ' . $key . '="' . $value . '"';
					}		
					$str .= ">";
					/*If this field is set as required, render an "*" inside a <span> tag.*/
					if(!empty($ele->required))
					{
						$str .= " <span";
						$tmpAllowFieldArr = $this->allowedFields["span"];
						foreach($this->requiredAttributes as $key => $value)
						{
							if(in_array($key, $tmpAllowFieldArr))
								$str .= ' ' . $key . '="' . $value . '"';
						}		
						$str .= ">*</span> ";
					}	
					$str .= $ele->label . "</div>\n";
				}	

				/*preHTML and postHTML allow for any special case scenarios.  One specific situation where these may be used would
				be if you need to toggle the visibility of an item or items based on the state of another field such as a radio button.*/
				if(!empty($ele->attributes["preHTML"]))
				{
					$str .= "\t\t";
					if(!empty($this->map))
						$str .= "\t\t\t";
					$str .= $ele->attributes["preHTML"];
					$str .= "\n";	
				}		

				/*Check the element's type and render the field accordinly.*/
				$eleType = &$ele->attributes["type"];
				if($eleType == "text" || $eleType == "password")
				{
					if(empty($ele->attributes["style"]))
						$ele->attributes["style"] = "width: 100%;";
					$str .= "\t\t";
					if(!empty($this->map))
						$str .= "\t\t\t";
					$str .= "<input";
					$tmpAllowFieldArr = $this->allowedFields["text"];
					foreach($ele->attributes as $key => $value)
					{
						if(in_array($key, $tmpAllowFieldArr))
							$str .= ' ' . $key . '="' . htmlentities($value, ENT_COMPAT) . '"';
					}		
					if(!empty($ele->disabled))
						$str .= " disabled";
					if(!empty($ele->readonly))
						$str .= " readonly";
					$str .= "/>\n";
				}
				elseif($eleType == "file")
				{
					$str .= "\t\t";
					if(!empty($this->map))
						$str .= "\t\t\t";
					$str .= "<input";
					$tmpAllowFieldArr = $this->allowedFields["file"];
					foreach($ele->attributes as $key => $value)
					{
						if(in_array($key, $tmpAllowFieldArr))
							$str .= ' ' . $key . '="' . htmlentities($value, ENT_COMPAT) . '"';
					}		
					if(!empty($ele->disabled))
						$str .= " disabled";
					if(!empty($ele->readonly))
						$str .= " readonly";
					$str .= "/>\n";
				}
				elseif($eleType == "textarea")
				{
					if(empty($ele->attributes["style"]))
						$ele->attributes["style"] = "width: 100%; height: 100px;";
					$str .= "\t\t";
					if(!empty($this->map))
						$str .= "\t\t\t";
					$str .= "<textarea";
					$tmpAllowFieldArr = $this->allowedFields["textarea"];
					foreach($ele->attributes as $key => $value)
					{
						if(in_array($key, $tmpAllowFieldArr))
							$str .= ' ' . $key . '="' . htmlentities($value, ENT_COMPAT) . '"';
					}		
					if(!empty($ele->disabled))
						$str .= " disabled";
					if(!empty($ele->readonly))
						$str .= " readonly";
					$str .= "/>" . $ele->attributes["value"] . "</textarea>\n";
				}
				elseif($eleType == "select")
				{
					$selected = false;
					if(empty($ele->attributes["style"]))
						$ele->attributes["style"] = "width: 100%;";
					$str .= "\t\t";
					if(!empty($this->map))
						$str .= "\t\t\t";
					$str .= "<select";
					$tmpAllowFieldArr = $this->allowedFields["select"];
					foreach($ele->attributes as $key => $value)
					{
						if(in_array($key, $tmpAllowFieldArr))
							$str .= ' ' . $key . '="' . htmlentities($value, ENT_COMPAT) . '"';
					}		
					$str .= "/>\n";

					if(is_array($ele->options))
					{
						$optionSize = sizeof($ele->options);
						for($o = 0; $o < $optionSize; ++$o)
						{
							$str .= "\t\t\t";
							if(!empty($this->map))
								$str .= "\t\t\t";
							$str .= '<option value="' . htmlentities($ele->options[$o]->key, ENT_COMPAT) . '"';
							if(!$selected && $ele->attributes["value"] == $ele->options[$o]->key)
							{
								$str .= " selected";
								$selected = true;
							}	
							if(!empty($ele->disabled))
								$str .= " disabled";
							if(!empty($ele->readonly))
								$str .= " readonly";
							if(!empty($ele->multiple))
								$str .= " multiple";
							$str .= '>' . $ele->options[$o]->value . "</option>\n"; 
						}	
					}

					$str .= "\t\t";
					if(!empty($this->map))
						$str .= "\t\t\t";
					$str .= "</select>\n";
				}
				elseif($eleType == "radio")
				{
					if(is_array($ele->options))
					{
						$optionSize = sizeof($ele->options);
						for($o = 0; $o < $optionSize; ++$o)
						{
							$str .= "\t\t";
							if(!empty($this->map))
								$str .= "\t\t\t";

							if($o != 0)
							{
								if(!empty($ele->nobreak))
									$str .= "&nbsp;&nbsp;";
								else
									$str .= "<br>";
							}	

							$str .= "<input";
							$tmpAllowFieldArr = $this->allowedFields["radio"];
							foreach($ele->attributes as $key => $value)
							{
								if(in_array($key, $tmpAllowFieldArr))
									$str .= ' ' . $key . '="' . htmlentities($value, ENT_COMPAT) . '"';
							}		
							$str .= ' id="' . $ele->attributes["name"] . $o . '"';		
							$str .= ' value="' . htmlentities($ele->options[$o]->key, ENT_COMPAT) . '"';		
							if((empty($ele->attributes["value"]) && $o == 0) || $ele->attributes["value"] == $ele->options[$o]->key)
								$str .= " checked";
							if(!empty($ele->disabled))
								$str .= " disabled";
							$str .= '><label for="' . $ele->attributes["name"] . $o . '" style="cursor: pointer;">' . $ele->options[$o]->value . "</label>\n"; 
						}	
					}
				}
				elseif($eleType == "checkbox")
				{
					if(is_array($ele->options))
					{
						$optionSize = sizeof($ele->options);
						for($o = 0; $o < $optionSize; ++$o)
						{
							$str .= "\t\t";
							if(!empty($this->map))
								$str .= "\t\t\t";

							if($o != 0)
							{
								if(!empty($ele->nobreak))
									$str .= "&nbsp;&nbsp;";
								else
									$str .= "<br>";
							}	

							$str .= "<input";
							$tmpAllowFieldArr = $this->allowedFields["checkbox"];
							foreach($ele->attributes as $key => $value)
							{
								if(in_array($key, $tmpAllowFieldArr))
									$str .= ' ' . $key . '="' . htmlentities($value, ENT_COMPAT) . '"';
							}		
							$str .= ' id="' . $ele->attributes["name"] . $o . '"';		
							$str .= ' value="' . htmlentities($ele->options[$o]->key, ENT_COMPAT) . '"';		
							/*For checkboxes, the value parameter can be an array - which allows for multiple boxes to be checked by default.*/
							if((!is_array($ele->attributes["value"]) && $ele->attributes["value"] == $ele->options[$o]->key) || (is_array($ele->attributes["value"]) && in_array($ele->options[$o]->key, $ele->attributes["value"])))
								$str .= " checked";
							if(!empty($ele->disabled))
								$str .= " disabled";
							$str .= '><label for="' . $ele->attributes["name"] . $o . '" style="cursor: pointer;">' . $ele->options[$o]->value . "</label>\n"; 
						}	
					}
				}
				elseif($eleType == "date")
				{
					if(empty($ele->attributes["style"]))
						$ele->attributes["style"] = "width: 100%; cursor: pointer;";
					$eleType = "text";
					if(empty($ele->attributes["id"]))
						$ele->attributes["id"] = "dateinput_" . rand(0, 999);

					if(empty($ele->attributes["value"]))
						$ele->attributes["value"] = "Click to Select Date...";
					
					$this->jqueryDateArr[] = $ele->attributes["id"];	

					$str .= "\t\t";
					if(!empty($this->map))
						$str .= "\t\t\t";
					$str .= "<input";
					$tmpAllowFieldArr = $this->allowedFields["date"];
					foreach($ele->attributes as $key => $value)
					{
						if(in_array($key, $tmpAllowFieldArr))
							$str .= ' ' . $key . '="' . htmlentities($value, ENT_COMPAT) . '"';
					}	

					$str .= " readonly";
					$str .= "/>\n";
					$eleType = "date";
				}
				elseif($eleType == "sort")
				{
					if(is_array($ele->options))
					{
						$str .= "\t\t";
						if(!empty($this->map))
							$str .= "\t\t\t";
						if(empty($ele->attributes["id"]))
							$ele->attributes["id"] = "sortinput_" . rand(0, 999);
						if(substr($ele->attributes["name"], -2) != "[]")
							$ele->attributes["name"] .= "[]";
						$this->jquerySortArr[] = array($ele->attributes["id"], $ele->attributes["name"]);	
						$str .= "<ul id='" . $ele->attributes["id"] . "'>\n";
						$optionSize = sizeof($ele->options);
						for($o = 0; $o < $optionSize; ++$o)
						{
							$str .= "\t\t\t";
							if(!empty($this->map))
								$str .= "\t\t\t";
							$str .= '<li class="ui-state-default" id="' . $ele->options[$o]->key . '"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>' . $ele->options[$o]->value . '</li>';
							$str .= "\n";
							$str .= "\t\t\t";
							if(!empty($this->map))
								$str .= "\t\t\t";
							$str .=  '<input type="hidden" name="' . $ele->attributes["name"] . '" value="' . $ele->options[$o]->key . '">' . "\n";	
						}	
						$str .= "\t\t";
						if(!empty($this->map))
							$str .= "\t\t\t";
						$str .= "</ul>\n";
					}
				}
				elseif($eleType == "latlng")
				{
					if(empty($ele->attributes["style"]))
						$ele->attributes["style"] = "width: 100%;";
					$eleType = "text";
					if(empty($ele->attributes["id"]))
						$ele->attributes["id"] = "latlnginput_" . rand(0, 999);
					
					$this->latlngArr[] = $ele;

					$str .= "\t\t";
					if(!empty($this->map))
						$str .= "\t\t\t";
					$str .= "<input";
					/*Allowed fields used from date field type as they perform identically.*/
					$tmpAllowFieldArr = $this->allowedFields["latlng"];
					foreach($ele->attributes as $key => $value)
					{
						if(in_array($key, $tmpAllowFieldArr))
							$str .= ' ' . $key . '="' . htmlentities($value, ENT_COMPAT) . '"';
					}	
					$str .= ' value="';
					if(empty($ele->attributes["value"]))
						$str .= "Drag Map Marker to Select Location...";
					elseif(!empty($ele->attributes["value"]) && is_array($ele->attributes["value"]))	
						$str .=  "Latitude: " . $ele->attributes["value"][0] . ", Longitude: " . $ele->attributes["value"][1];
					$str .= '"';

					$str .= " readonly";
					$str .= "/>\n";

					if(empty($ele->latlngHeight))
						$ele->latlngHeight = 200;

					$str .= '<div id="' . $ele->attributes["id"] . '_canvas" style="margin-top: 2px; height: ' . $ele->latlngHeight . 'px;';
					if(!empty($ele->latlngWidth))
						$str .= ' width: ' . $ele->latlngWidth . 'px;';
					$str .= '"></div>';
					$eleType = "latlng";
				}

				if(!empty($ele->attributes["postHTML"]))
				{
					$str .= "\t\t";
					if(!empty($this->map))
						$str .= "\t\t\t";
					$str .= $ele->attributes["postHTML"];
					$str .= "\n";	
				}		

				$str .= "\t";
				if(!empty($this->map))
					$str .= "\t\t\t";
				$str .= "</td>";

				if(!empty($this->map))
				{
					if(($i + 1) == $elementSize)
						$str .= "\n\t\t\t</tr>\n\t\t</table>\n\t</td></tr>\n";
					elseif(array_key_exists($this->mapIndex, $this->map) && $this->map[$this->mapIndex] > 1)
					{
						if(($this->mapCount + 1) == $this->map[$this->mapIndex])
						{
							$this->mapCount = 0;
							++$this->mapIndex;
							$str .= "\n\t\t\t</tr>\n\t\t</table>\n\t</td></tr>\n";
						}
						else
						{
							++$this->mapCount;
							$str .= "\n";
						}	
					}
					else
					{
						++$this->mapIndex;
						$this->mapCount = 0;
						$str .= "\n\t\t\t</tr>\n\t\t</table>\n\t</td></tr>\n";
					}	
				}
				else
					$str .= "</tr>\n";
			}	
		}

		if(!empty($this->map) && !empty($this->mapOriginalWidth))
			$this->tdAttributes["width"] = $this->mapOriginalWidth;
		else
			unset($this->tdAttributes["width"]);

		if($includeTableTags)
			$str .= "</table>\n";

		/*The two jQuery hybrid fields - sort and date - require javascript and css elements to be included in the markup.  Feel free
		to edit the css and/or javascript to fit your needs.  For instance, you can change the date field's formatted date string below, or
		change how the sort operates.  Visit http://www.jqueryui.com for instructions/examples on how to do this.*/
		if(!empty($this->jqueryDateArr) || !empty($this->jquerySortArr))
		{
			$str .= "\n\t" . '<link href="' . $this->jqueryPath . '/jquery-ui-1.7.1.css" rel="stylesheet" type="text/css">';
			$str .= "\n\t" . '<script language="javascript" src="' . $this->jqueryPath . '/jquery-1.3.2.min.js"></script>';
			$str .= "\n\t" . '<script language="javascript" src="' . $this->jqueryPath . '/jquery-ui-1.7.1.min.js"></script>';

			if(!empty($this->jqueryDateArr))
				$str .= "\n\t" . '<style type="text/css">.ui-datepicker-div, .ui-datepicker-inline, #ui-datepicker-div {font-size:0.8em}</style>';

			if(!empty($this->jquerySortArr))
			{
				$str .= "\n\t" . '<style type="text/css">';
				$jquerySize = sizeof($this->jquerySortArr);
				for($j = 0; $j < $jquerySize; ++$j)
				{
					$str .= "\n\t\t#" . $this->jquerySortArr[$j][0] . " { list-style-type: none; margin: 0; padding: 0; cursor: pointer; }";
					$str .= "\n\t\t#" . $this->jquerySortArr[$j][0] . " li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 14px; height: 18px; }";
					$str .= "\n\t\t#" . $this->jquerySortArr[$j][0] . " li span { position: absolute; margin-left: -1.3em;}";
				}
				$str .= "\n\t" . '</style>';
			}

			$str .= "\n\t" . '<script language="javascript" defer="true">';
			if(!empty($this->jqueryDateArr))
			{
				$jquerySize = sizeof($this->jqueryDateArr);
				for($j = 0; $j < $jquerySize; ++$j)
					$str .= "\n\t\t" . '$("#' . $this->jqueryDateArr[$j] . '").datepicker({ dateFormat: "MM d, yy", showButtonPanel: true });';
			}

			if(!empty($this->jquerySortArr))
			{
				$jquerySize = sizeof($this->jquerySortArr);
				for($j = 0; $j < $jquerySize; ++$j)
					$str .= "\n\t\t" . '$("#' . $this->jquerySortArr[$j][0] . '").sortable({ axis: "y", update: function(event, ui) { ulObj = document.getElementById("' . $this->jquerySortArr[$j][0] . '"); liLen = ulObj.childNodes.length; liIndex = 0; if(liLen > 0) { for(i = 0; i < liLen; i++) { liObj = ulObj.childNodes[i]; if(liObj.tagName && liObj.tagName.toLowerCase() == "li") { document.forms["' . $this->attributes["name"] . '"].elements["' . $this->jquerySortArr[$j][1] . '"][liIndex].value = liObj.id; liIndex++; } } } } });';
			}
			$str .= "\n\t" . '</script>' . "\n\n";
		}	

		if(!empty($this->latlngArr) && !empty($this->googleMapsAPIKey))
		{
			$str .= "\n\t" . '<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=' . $this->googleMapsAPIKey . '" type="text/javascript"></script>';
			$str .= "\n\t" . '<script language="javascript" defer="true">';
			$str .= "\n\t\tfunction initialize_" . $this->attributes["name"] . "_latlng() {";
				$str .= "\n\t\t\tif (GBrowserIsCompatible()) {";
				$latlngSize = sizeof($this->latlngArr);
				for($l = 0; $l < $latlngSize; ++$l)
				{
					$latlng = $this->latlngArr[$l];
					$latlngID = $latlng->attributes["id"];
					if(!empty($latlng->attributes["value"]))
					{
						$latlngCenter = $latlng->attributes["value"];
						if(empty($latlng->latlngZoom))
							$latlngZoom = 9;
						else
							$latlngZoom = $latlng->latlngZoom;
					}		
					else	
					{
						$latlngCenter = array(39, -96);
						if(empty($latlng->latlngZoom))
							$latlngZoom = 3;
						else
							$latlngZoom = $latlng->latlngZoom;
					}	
					$str .= "\n\t\t\t\t" . 'var map_' . $latlngID . ' = new GMap2(document.getElementById("' . $latlngID . '_canvas"));';
					$str .= "\n\t\t\t\t" . 'map_' . $latlngID . '.addControl(new GSmallMapControl());';
					$str .= "\n\t\t\t\t" . 'var center_' . $latlngID . ' = new GLatLng(' . $latlngCenter[0] . ', ' . $latlngCenter[1] . ');';
					$str .= "\n\t\t\t\t" . 'map_' . $latlngID . '.setCenter(center_' . $latlngID . ', ' . $latlngZoom . ');';
					$str .= "\n\t\t\t\t" . 'var marker_' . $latlngID . ' = new GMarker(center_' . $latlngID . ', {draggable: true});';
					$str .= "\n\t\t\t\t" . 'map_' . $latlngID . '.addOverlay(marker_' . $latlngID . ');';
					$str .= "\n\t\t\t\t" . 'GEvent.addListener(marker_' . $latlngID . ', "dragend", function() {';
					$str .= "\n\t\t\t\t\tvar latlng = marker_" . $latlngID . ".getLatLng();";
					$str .= "\n\t\t\t\t\tvar lat = latlng.lat();";
					$str .= "\n\t\t\t\t\tvar lng = latlng.lng();";
					$str .= "\n\t\t\t\t\t" . 'document.forms["' . $this->attributes["name"] . '"].elements["' . $latlng->attributes["name"] . '"].value = "Latitude: " + lat.toFixed(3) + ", Longitude: " + lng.toFixed(3);';
					$str .= "\n\t\t\t\t});";
				}
				$str .= "\n\t\t\t}";
			$str .= "\n\t\t}";
			$str .= "\n\t\t" . 'if(window.addEventListener) { window.addEventListener("load", initialize_' . $this->attributes["name"] . '_latlng, false); }'; 
			$str .= "\n\t\t" . 'else if(window.attachEvent) { window.attachEvent("onload", initialize_' . $this->attributes["name"] . '_latlng); }'; 
			$str .= "\n\t" . '</script>';
		}

		return $str;
	}

	/*This function handles php form checking to be used after submission.  Serialization needs to be utilized before calling this function to revive the forms past state.  If returnUrl is set, this function will redirect and exit.*/
	public function checkForm()
	{
		if(strtolower($this->attributes["method"]) == "post")
			$ref = $_POST;
		else
			$ref = $_GET;

		$error_msg = "";
		$elementSize = sizeof($this->elements);
		for($i = 0; $i < $elementSize; ++$i)
		{
			$ele = $this->elements[$i];
			if(!empty($ele->required))
			{
				if($ele->attributes["type"] == "date" && (empty($ref[$ele->attributes["name"]]) || $ref[$ele->attributes["name"]] == "Click to Select Date..."))
				{
					$error_msg = $ele->label . " is a required field.";	
					break;
				}
				if($ele->attributes["type"] == "latlng" && (empty($ref[$ele->attributes["name"]]) || $ref[$ele->attributes["name"]] == "Drag Map Marker to Select Location..."))
				{
					$error_msg = $ele->label . " is a required field.";	
					break;
				}
				elseif(empty($ref[$ele->attributes["name"]]))
				{
					$error_msg = $ele->label . " is a required field.";	
					break;
				}	
			}
		}	

		if(!empty($error_msg))
		{
			if(strpos($this->returnUrl, "?") === false)
				$error_msg = "?error_message=" . rawurlencode($error_msg);
			else	
				$error_msg = "&error_message=" . rawurlencode($error_msg);

			if(!empty($this->returnUrl))
			{
				header("Location: " . $this->returnUrl . $error_msg);
				exit();
			}
			else
				return $error_msg;
		}
		else 
			return;
	}

	/*This function set the referenceValues variables which can be used to pre-fill form fields.  This function needs to be called before the render function.*/
	public function setReferenceValues($ref)
	{
		$this->referenceValues = $ref;
	}
}

class element extends base {
	/*Public variables to be read/written in both the base and form classes.*/
	public $attributes;
	public $label;
	public $options;
	public $required;
	public $disabled;
	public $multiple;
	public $readonly;
	public $nobreak;
	public $preHTML;
	public $postHTML;

	/*latlng specific fields*/
	public $latlngHeight;
	public $latlngWidth;
	public $latlngZoom;

	public function __construct() {
		/*Set default values where appropriate.*/
		$this->attributes = array(
			"type" => "text"
		);
		$this->label = "";
		$this->options = array();
		$this->required = "";
		$this->disabled = "";
		$this->multiple = "";
		$this->readonly = "";
		$this->nobreak = "";
		$this->preHTML = "";
		$this->postHTML = "";
		$this->latlngHeight = "";
		$this->latlngWidth = "";
		$this->latlngZoom = "";
	}
}
class option extends base {
	/*Public variables to be read/written in both the base and form classes.*/
	public $key;
	public $value;

	/*Set default values where appropriate.*/
	public function __construct() {
		$this->key = "";
		$this->value = "";
	}
}
class button extends base {
	/*Public variables to be read/written in both the base and form classes.*/
	public $attributes;
	public $phpFunction;
	public $phpParams;
	public $wrapLink;
	public $linkAttributes;

	/*Set default values where appropriate.*/
	public function __construct() {
		$this->attributes = array();
		$this->phpFunction = "";
		$this->phpParams = "";
		$this->wrapLink = "";
		$this->linkAttributes = array(
			"style" => "text-decoration: none;"
		);
	}
}
?>
Return current item: Form Builder