Merge branch 'feature/form_helper' of github.com:darkhouse/CodeIgniter into feature/form_helpers_extra_array

Manually fixed conflicts in:
	user_guide_src/source/changelog.rst
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
index 53ee8eb..f8c6a9d 100644
--- a/system/helpers/form_helper.php
+++ b/system/helpers/form_helper.php
@@ -197,7 +197,7 @@
 	 *
 	 * @param	mixed
 	 * @param	string
-	 * @param	string
+	 * @param	mixed
 	 * @return	string
 	 */
 	function form_input($data = '', $value = '', $extra = '')
@@ -208,6 +208,8 @@
 			'value' => $value
 		);
 
+		$extra = _attributes_to_string($extra);
+
 		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
@@ -223,7 +225,7 @@
 	 *
 	 * @param	mixed
 	 * @param	string
-	 * @param	string
+	 * @param	mixed
 	 * @return	string
 	 */
 	function form_password($data = '', $value = '', $extra = '')
@@ -245,7 +247,7 @@
 	 *
 	 * @param	mixed
 	 * @param	string
-	 * @param	string
+	 * @param	mixed
 	 * @return	string
 	 */
 	function form_upload($data = '', $value = '', $extra = '')
@@ -253,6 +255,9 @@
 		$defaults = array('type' => 'file', 'name' => '');
 		is_array($data) OR $data = array('name' => $data);
 		$data['type'] = 'file';
+
+		$extra = _attributes_to_string($extra);
+		
 		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
@@ -266,7 +271,7 @@
 	 *
 	 * @param	mixed	$data
 	 * @param	string	$value
-	 * @param	string	$extra
+	 * @param	mixed	$extra
 	 * @return	string
 	 */
 	function form_textarea($data = '', $value = '', $extra = '')
@@ -287,6 +292,8 @@
 			unset($data['value']); // textareas don't use the value attribute
 		}
 
+		$extra = _attributes_to_string($extra);
+
 		return '<textarea '._parse_form_attributes($data, $defaults).$extra.'>'.html_escape($val)."</textarea>\n";
 	}
 }
@@ -301,11 +308,13 @@
 	 * @param	string
 	 * @param	array
 	 * @param	mixed
-	 * @param	string
+	 * @param	mixed
 	 * @return	string
 	 */
 	function form_multiselect($name = '', $options = array(), $selected = array(), $extra = '')
 	{
+		$extra = _attributes_to_string($extra);
+
 		if ( ! strpos($extra, 'multiple'))
 		{
 			$extra .= ' multiple="multiple"';
@@ -420,7 +429,7 @@
 	 * @param	mixed
 	 * @param	string
 	 * @param	bool
-	 * @param	string
+	 * @param	mixed
 	 * @return	string
 	 */
 	function form_checkbox($data = '', $value = '', $checked = FALSE, $extra = '')
@@ -450,6 +459,8 @@
 			unset($defaults['checked']);
 		}
 
+		$extra = _attributes_to_string($extra);
+
 		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
@@ -464,13 +475,14 @@
 	 * @param	mixed
 	 * @param	string
 	 * @param	bool
-	 * @param	string
+	 * @param	mixed
 	 * @return	string
 	 */
 	function form_radio($data = '', $value = '', $checked = FALSE, $extra = '')
 	{
 		is_array($data) OR $data = array('name' => $data);
 		$data['type'] = 'radio';
+
 		return form_checkbox($data, $value, $checked, $extra);
 	}
 }
@@ -484,7 +496,7 @@
 	 *
 	 * @param	mixed
 	 * @param	string
-	 * @param	string
+	 * @param	mixed
 	 * @return	string
 	 */
 	function form_submit($data = '', $value = '', $extra = '')
@@ -495,6 +507,8 @@
 			'value' => $value
 		);
 
+		$extra = _attributes_to_string($extra);
+
 		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
@@ -508,7 +522,7 @@
 	 *
 	 * @param	mixed
 	 * @param	string
-	 * @param	string
+	 * @param	mixed
 	 * @return	string
 	 */
 	function form_reset($data = '', $value = '', $extra = '')
@@ -519,6 +533,8 @@
 			'value' => $value
 		);
 
+		$extra = _attributes_to_string($extra);
+
 		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
@@ -532,7 +548,7 @@
 	 *
 	 * @param	mixed
 	 * @param	string
-	 * @param	string
+	 * @param	mixed
 	 * @return	string
 	 */
 	function form_button($data = '', $content = '', $extra = '')
@@ -548,6 +564,8 @@
 			unset($data['content']); // content is not an attribute
 		}
 
+		$extra = _attributes_to_string($extra);
+
 		return '<button '._parse_form_attributes($data, $defaults).$extra.'>'.$content."</button>\n";
 	}
 }
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index b7888ca..4fe3b94 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -8,7 +8,7 @@
 Release Date: Not Released
 
 -  Core
-
+   
    -  Added DoS mitigation to :php:func:`hash_pbkdf2()` :doc:`compatibility function <general/compatibility_functions>`.
 
 -  Database
@@ -28,6 +28,7 @@
 -  Helpers
 
    -  Added Unicode support to :doc:`URL Helper <helpers/url_helper>` function :php:func:`url_title()`.
+   -  Added support for passing the "extra" parameter as an array to all :doc:`Form Helper <helpers/form_helper>` functions that use it.
 
 Bug fixes for 3.0.1
 -------------------
diff --git a/user_guide_src/source/helpers/form_helper.rst b/user_guide_src/source/helpers/form_helper.rst
index 9ddca89..1c55f56 100644
--- a/user_guide_src/source/helpers/form_helper.rst
+++ b/user_guide_src/source/helpers/form_helper.rst
@@ -191,7 +191,7 @@
 
 	:param	array	$data: Field attributes data
 	:param	string	$value: Field value
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML text input field tag
 	:rtype:	string
 
@@ -226,11 +226,16 @@
 		$js = 'onClick="some_function()"';
 		echo form_input('username', 'johndoe', $js);
 
+	Or you can pass it as an array::
+
+		$js = array('onClick' => "some_function()");
+		echo form_input('username', 'johndoe', $js);
+
 .. php:function:: form_password([$data = ''[, $value = ''[, $extra = '']]])
 
 	:param	array	$data: Field attributes data
 	:param	string	$value: Field value
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML password input field tag
 	:rtype:	string
 
@@ -242,7 +247,7 @@
 
 	:param	array	$data: Field attributes data
 	:param	string	$value: Field value
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML file upload input field tag
 	:rtype:	string
 
@@ -255,7 +260,7 @@
 
 	:param	array	$data: Field attributes data
 	:param	string	$value: Field value
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML textarea tag
 	:rtype:	string
 
@@ -270,7 +275,7 @@
 	:param	string	$name: Field name
 	:param	array	$options: An associative array of options to be listed
 	:param	array	$selected: List of fields to mark with the *selected* attribute
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML dropdown select field tag
 	:rtype:	string
 
@@ -324,6 +329,11 @@
 		$js = 'id="shirts" onChange="some_function();"';
 		echo form_dropdown('shirts', $options, 'large', $js);
 
+	Or you can pass it as an array::
+
+		$js = array('id' => "shirts", 'onChange' => "some_function();");
+		echo form_dropdown('shirts', $options, 'large', $js);
+
 	If the array passed as ``$options`` is a multidimensional array, then
 	``form_dropdown()`` will produce an <optgroup> with the array key as the
 	label.
@@ -334,7 +344,7 @@
 	:param	string	$name: Field name
 	:param	array	$options: An associative array of options to be listed
 	:param	array	$selected: List of fields to mark with the *selected* attribute
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML dropdown multiselect field tag
 	:rtype:	string
 
@@ -417,7 +427,7 @@
 	:param	array	$data: Field attributes data
 	:param	string	$value: Field value
 	:param	bool	$checked: Whether to mark the checkbox as being *checked*
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML checkbox input tag
 	:rtype:	string
 
@@ -450,13 +460,18 @@
 		$js = 'onClick="some_function()"';
 		echo form_checkbox('newsletter', 'accept', TRUE, $js)
 
+	Or you can pass it as an array::
+
+		$js = array('onClick' => "some_function()");
+		echo form_checkbox('newsletter', 'accept', TRUE, $js)
+
 
 .. php:function:: form_radio([$data = ''[, $value = ''[, $checked = FALSE[, $extra = '']]]])
 
 	:param	array	$data: Field attributes data
 	:param	string	$value: Field value
 	:param	bool	$checked: Whether to mark the radio button as being *checked*
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML radio input tag
 	:rtype:	string
 
@@ -495,7 +510,7 @@
 
 	:param	string	$data: Button name
 	:param	string	$value: Button value
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML input submit tag
 	:rtype:	string
 
@@ -513,7 +528,7 @@
 
 	:param	string	$data: Button name
 	:param	string	$value: Button value
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML input reset button tag
 	:rtype:	string
 
@@ -525,7 +540,7 @@
 
 	:param	string	$data: Button name
 	:param	string	$content: Button label
-	:param	string	$extra: Extra attributes to be added to the tag *as is*
+	:param	mixed	$extra: Extra attributes to be added to the tag either as array or string
 	:returns:	An HTML button tag
 	:rtype:	string