Newer
Older
/**
* @defgroup form Form generation
* @{
* Functions to enable output of HTML forms and form elements.
*
* Drupal uses these functions to achieve consistency in its form presentation,
* while at the same time simplifying code and reducing the amount of HTML that

Dries Buytaert
committed
* must be explicitly generated by modules. See the reference at
* http://drupaldocs.org/api/head/file/contributions/docs/developer/topics/forms_api_reference.html
* and the quickstart guide at
* http://drupaldocs.org/api/head/file/contributions/docs/developer/topics/forms_api.html
*/
/**
* Check if the key is a property.
*/
function element_property($key) {
return $key[0] == '#';
/**
* Get properties of a form tree element. Properties begin with '#'.
*/
function element_properties($element) {
return array_filter(array_keys((array) $element), 'element_property');
}
/**
* Check if the key is a child.
*/
function element_child($key) {
return $key[0] != '#';
/**
* Get keys of a form tree element that are not properties (i.e., do not begin with '#').
*/
function element_children($element) {
return array_filter(array_keys((array) $element), 'element_child');

Dries Buytaert
committed
* Processes a form array and produces the HTML output of a form.
* If there is input in the $_POST['edit'] variable, this function

Dries Buytaert
committed
* will attempt to validate it, using drupal_validate_form(),
* and then submit the form using drupal_submit_form().
*
* @param $form_id
* A unique string identifying the form. Allows each form to be themed.
* @param $form
* An associative array containing the structure of the form.
* @param $callback
* An optional callback that will be used in addition to the form_id.
*
*/
function drupal_get_form($form_id, &$form, $callback = NULL) {

Dries Buytaert
committed
$form['#type'] = 'form';
if (isset($form['#token'])) {
// Make sure that a private key is set:
if (!variable_get('drupal_private_key', '')) {
variable_set('drupal_private_key', mt_rand());
}

Dries Buytaert
committed
$form['form_token'] = array('#type' => 'hidden', '#value' => md5(session_id() . $form['#token'] . variable_get('drupal_private_key', '')));
$form['form_id'] = array('#type' => 'hidden', '#default_value' => $form_id);
$form = array_merge(_element_info('form'), $form);
if (!isset($form['#validate'])) {
if (function_exists($form_id .'_validate')) {
$form['#validate'] = array($form_id .'_validate' => array());
}
elseif (function_exists($callback .'_validate')) {
$form['#validate'] = array($callback .'_validate' => array());

Dries Buytaert
committed
if (!isset($form['#submit'])) {
if (function_exists($form_id .'_submit')) {
// we set submit here so that it can be altered but use reference for
// $form_values because it will change later
$form['#submit'] = array($form_id .'_submit' => array($form_id, &$form_values));

Dries Buytaert
committed
elseif (function_exists($callback .'_submit')) {
$form['#submit'] = array($callback .'_submit' => array($form_id, &$form_values));
foreach (module_implements('form_alter') as $module) {
$function = $module .'_form_alter';

Dries Buytaert
committed
$function($form_id, $form);

Steven Wittens
committed
$form = _form_builder($form_id, $form);

Steven Wittens
committed
if (!empty($_POST['edit']) && (($_POST['edit']['form_id'] == $form_id) || ($_POST['edit']['form_id'] == $callback))) {

Dries Buytaert
committed
drupal_validate_form($form_id, $form, $callback);
if ($form_submitted && !form_get_errors()) {

Dries Buytaert
committed
drupal_submit_form($form_id, $form, $callback);

Dries Buytaert
committed
}
if (theme_get_function($form_id)) {

Dries Buytaert
committed
$form['#theme'] = $form_id;
elseif (theme_get_function($callback)) {

Dries Buytaert
committed
$form['#theme'] = $callback;
}
return form_render($form);
}
function drupal_validate_form($form_id, &$form, $callback = NULL) {
global $form_values;

Dries Buytaert
committed
if (isset($form['#token'])) {
if ($form_values['form_token'] != md5($_SERVER['REMOTE_ADDR'] . $form['#token'] . variable_get('drupal_private_key', ''))) {
// setting this error will cause the form to fail validation
form_set_error('form_token', t('Validation error, please try again. If this error persists, please contact the site administrator.'));
}
}
_form_validate($form, $form_id);

Dries Buytaert
committed
function drupal_submit_form($form_id, $form, $callback = NULL) {

Dries Buytaert
committed
if (isset($form['#submit'])) {
foreach ($form['#submit'] as $function => $args) {
if (function_exists($function)) {
call_user_func_array($function, $args);
function _form_validate($elements, $form_id = NULL) {
/* Validate the current input */
if (!$elements['#validated'] && ($elements['#input'] || isset($form_id))) {

Dries Buytaert
committed
// An empty textfield returns '' so we use empty(). An empty checkbox
// and a textfield could return '0' and empty('0') returns TRUE so we
// need a special check for the '0' string.
if ($elements['#required'] && empty($elements['#value']) && $elements['#value'] !== '0') {
form_error($elements, t('%name field is required.', array('%name' => $elements['#title'])));

Dries Buytaert
committed
}
// Add legal choice check if element has #options.
if (isset($elements['#options']) && isset($elements['#value'])) {
$message = t('Illegal choice in %title.', array('%title' => theme('placeholder', $elements['#title'])));
if ($elements['#type'] == 'select') {
$options = form_options_flatten($elements['#options']);
}
else {
$options = $elements['#options'];
}
if (is_array($elements['#value'])) {
$value = $elements['#type'] == 'checkboxes' ? array_keys(array_filter($elements['#value'])) : $elements['#value'];
foreach ($value as $v) {
if (!isset($options[$v])) {
form_error($elements, $message);
}
}
}
elseif (!isset($options[$elements['#value']])) {
form_error($elements, $message);
}
}
// User-applied checks.
foreach ($elements['#validate'] as $function => $args) {
$args = array_merge(array($elements), $args);
// for the full form we hand over a copy of $form_values
if (isset($form_id)) {
$args = array_merge(array($form_id, $GLOBALS['form_values']), $args);
if (function_exists($function)) {
call_user_func_array($function, $args);

Dries Buytaert
committed
$elements['#validated'] = TRUE;
// Recurse through all children.
foreach (element_children($elements) as $key) {
if (isset($elements[$key]) && $elements[$key]) {
_form_validate($elements[$key]);
}
}
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/**
* File an error against a form element. If the name of the element is
* edit[foo][bar] then you may pass either foo or foo][bar as $name
* foo will set an error for all its children.
*/
function form_set_error($name = NULL, $message = NULL) {
static $form = array();
if (isset($name) && !isset($form[$name])) {
$form[$name] = $message;
drupal_set_message($message, 'error');
}
return $form;
}
/**
* Return an associative array of all errors.
*/
function form_get_errors() {
$form = form_set_error();
if (!empty($form)) {
return $form;
}
}
/**
* Return the error message filed against the form with the specified name.
*/
function form_get_error($element) {
$form = form_set_error();
$key = $element['#parents'][0];
if (isset($form[$key])) {
return $form[$key];
}
$key = implode('][', $element['#parents']);
if (isset($form[$key])) {
return $form[$key];
}
}
/**
* Flag an element as having an error.
*/
function form_error(&$element, $message) {

Dries Buytaert
committed
$element['#error'] = TRUE;
form_set_error(implode('][', $element['#parents']), $message);
}
/**
* Adds some required properties to each form element, which are used internally in the form api.
* This function also automatically assigns the value property from the $edit array, provided the
* element doesn't already have an assigned value.
*/

Steven Wittens
committed
function _form_builder($form_id, $form) {
/* Use element defaults */

Dries Buytaert
committed
if ((!empty($form['#type'])) && ($info = _element_info($form['#type']))) {

Dries Buytaert
committed
// overlay $info onto $form, retaining preexisting keys in $form
$form += $info;
}
if (isset($form['#input']) && $form['#input']) {
if (!isset($form['#name'])) {
$form['#name'] = 'edit[' . implode('][', $form['#parents']) . ']';
}
if (!isset($form['#id'])) {
$form['#id'] = 'edit-' . implode('-', $form['#parents']);
}

Steven Wittens
committed
$posted = (isset($_POST['edit']) && ($_POST['edit']['form_id'] == $form_id));
$edit = $posted ? $_POST['edit'] : array();
$ref =& $form_values;

Dries Buytaert
committed
foreach ($form['#parents'] as $parent) {
$edit = isset($edit[$parent]) ? $edit[$parent] : NULL;
$ref =& $ref[$parent];
}

Dries Buytaert
committed
if (!isset($form['#value'])) {

Dries Buytaert
committed
if ($posted) {
if (isset($edit)) {
$form['#value'] = $edit; // normal element
}
elseif (isset($form['#return_value'])) {

Dries Buytaert
committed
$form['#value'] = '0'; // checkbox unchecked

Dries Buytaert
committed
}
}
if (!isset($form['#value'])) {
$function = $form['#type'] . '_value';
if (function_exists($function)) {
$function($form);
}
else {
$form['#value'] = $form['#default_value'];
}

Dries Buytaert
committed
}

Dries Buytaert
committed
}
if (isset($form['#form_submitted']) && isset($_POST[$form['#name']])) {

Dries Buytaert
committed
if ($_POST[$form['#name']] == $form['#value']) {
$form_submitted = $form_submitted || $form['#form_submitted'];

Dries Buytaert
committed
// Allow for elements to expand to multiple elements, e.g. radios, checkboxes and files.
if (isset($form['#process']) && !$form['#processed']) {
foreach ($form['#process'] as $process => $args) {
if (function_exists($process)) {
$args = array_merge(array($form), $args);
$form = call_user_func_array($process, $args);

Dries Buytaert
committed
$form['#processed'] = TRUE;

Dries Buytaert
committed
// Set the $form_values key that gets passed to validate and submit.
// We call this after #process gets called so that #process has a
// chance to update #value if desired.
if (isset($form['#input']) && $form['#input']) {

Dries Buytaert
committed
$ref = $form['#value'];
}
// Recurse through all child elements.
$count = 0;
foreach (element_children($form) as $key) {
if (!isset($form[$key]['#tree'])) {
$form[$key]['#tree'] = $form['#tree'];
}
// don't squash existing parents value
if (!isset($form[$key]['#parents'])) {
// Check to see if a tree of child elements is present. If so, continue down the tree if required.
$form[$key]['#parents'] = $form[$key]['#tree'] && $form['#tree'] ? array_merge($form['#parents'], array($key)) : array($key);

Dries Buytaert
committed
# Assign a decimal placeholder weight to preserve original array order
if (!isset($form[$key]['#weight'])) {
$form[$key]['#weight'] = $count/1000;
}

Steven Wittens
committed
$form[$key] = _form_builder($form_id, $form[$key]);
if (isset($form['#after_build']) && function_exists($form['#after_build']) && !isset($form['#after_build_done'])) {
$function = $form['#after_build'];
$form = $function($form, $form_values, $ref);
$form['#after_build_done'] = TRUE;
return $form;
}
/**

Dries Buytaert
committed
* Renders a HTML form given a form tree. Recursively iterates over each of
* the form elements, generating HTML code. This function is usually
* called from within a theme. To render a form from within a module, use

Dries Buytaert
committed
* drupal_get_form().
*
* @param $elements
* The form tree describing the form.
* @return
* The rendered HTML form.
*/
function form_render(&$elements) {

Dries Buytaert
committed
if (!isset($elements)) {
return NULL;

Dries Buytaert
committed
$content = '';
uasort($elements, "_form_sort");
if (!isset($elements['#children'])) {
/* render all the children using a theme function */
if (isset($elements['#theme']) && !$elements['#theme_used']) {

Dries Buytaert
committed
$elements['#theme_used'] = TRUE;
$previous_type = $elements['#type'];
$elements['#type'] = 'markup';
$content = theme($elements['#theme'], $elements);
$elements['#type'] = $previous_type;
}
/* render each of the children using form_render and concatenate them */
if (!$content) {
foreach (element_children($elements) as $key) {
$content .= form_render($elements[$key]);
}
}
}
if ($content) {

Dries Buytaert
committed
$elements['#children'] = $content;
}
/* Call the form element renderer */
if (!isset($elements['#printed'])) {

Dries Buytaert
committed
$content = theme(($elements['#type']) ? $elements['#type']: 'markup', $elements);
$elements['#printed'] = TRUE;

Dries Buytaert
committed
if ($content) {
$prefix = isset($elements['#prefix']) ? $elements['#prefix'] : '';
$suffix = isset($elements['#suffix']) ? $elements['#suffix'] : '';
return $prefix . $content . $suffix;

Dries Buytaert
committed
}

Dries Buytaert
committed
* Function used by uasort in form_render() to sort form by weight.
*/
function _form_sort($a, $b) {
$a_weight = (is_array($a) && isset($a['#weight'])) ? $a['#weight'] : 0;
$b_weight = (is_array($b) && isset($b['#weight'])) ? $b['#weight'] : 0;
if ($a_weight == $b_weight) {
return ($a_weight < $b_weight) ? -1 : 1;
}
/**
* Retrieve the default properties for the defined element type.
*/
function _element_info($type, $refresh = null) {
static $cache;

Dries Buytaert
committed
'#description' => NULL,
'#attributes' => array(),
'#required' => FALSE,
'#parents' => array()
if (!isset($cache) || $refresh) {
$cache = array();
foreach (module_implements('elements') as $module) {
$elements = module_invoke($module, 'elements');

Dries Buytaert
committed
if (isset($elements) && is_array($elements)) {
$cache = array_merge_recursive($cache, $elements);
}
}
if (sizeof($cache)) {
foreach ($cache as $element_type => $info) {
$cache[$element_type] = array_merge_recursive($basic_defaults, $info);
}
}
}
return $cache[$type];
}
function form_options_flatten($array, $reset = TRUE) {
static $return;
if ($reset) {
$return = array();
}
foreach ($array as $key => $value) {
if (is_array($value)) {
form_options_flatten($value, FALSE);
}
else {
$return[$key] = 1;
}
}
return $return;
}
/**
* Format a dropdown menu or scrolling selection box.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: title, value, options, description, extra, multiple, required
* @return
* A themed HTML string representing the form element.
*
* It is possible to group options together; to do this, change the format of
* $options to an associative array in which the keys are group labels, and the
* values are associative arrays in the normal $options format.
*/
function theme_select($element) {
$select = '';
$size = $element['#size'] ? ' size="' . $element['#size'] . '"' : '';

Dries Buytaert
committed
return theme('form_element', $element['#title'], '<select name="'. $element['#name'] .''. ($element['#multiple'] ? '[]' : '') .'"'. ($element['#multiple'] ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) .' id="' . $element['#id'] .'" '. $size .'>'. form_select_options($element) .'</select>', $element['#description'], $element['#id'], $element['#required'], form_get_error($element));
}
function form_select_options($element, $choices = NULL) {
if (!isset($choices)) {
$choices = $element['#options'];
}

Dries Buytaert
committed
// array_key_exists() accomodates the rare event where $element['#value'] is NULL.
// isset() fails in this situation.
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
$value_is_array = is_array($element['#value']);

Dries Buytaert
committed
$options = '';
foreach ($choices as $key => $choice) {

Dries Buytaert
committed
$options .= '<optgroup label="'. $key .'">';
$options .= form_select_options($element, $choice);
$options .= '</optgroup>';

Dries Buytaert
committed
$key = (string)$key;
if ($value_valid && ($element['#value'] == $key || ($value_is_array && in_array($key, $element['#value'])))) {
$selected = ' selected="selected"';
}
else {
$selected = '';
}

Dries Buytaert
committed
$options .= '<option value="'. $key .'"'. $selected .'>'. check_plain($choice) .'</option>';

Dries Buytaert
committed
return $options;
}
/**
* Format a group of form items.
*
* @param $element
* An associative array containing the properties of the element.
* Properties used: attributes, title, value, description, children, collapsible, collapsed
* @return
* A themed HTML string representing the form item group.
*/
function theme_fieldset($element) {

Dries Buytaert
committed
if ($element['#collapsible']) {
drupal_add_js('misc/collapse.js');

Dries Buytaert
committed
$element['#attributes']['class'] .= ' collapsible';
if ($element['#collapsed']) {
$element['#attributes']['class'] .= ' collapsed';

Dries Buytaert
committed
return '<fieldset' . drupal_attributes($element['#attributes']) .'>' . ($element['#title'] ? '<legend>'. $element['#title'] .'</legend>' : '') . $element['#children'] . $element['#value'] . ($element['#description'] ? '<div class="description">'. $element['#description'] .'</div>' : '') . "</fieldset>\n";
}
/**
* Format a radio button.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: required, return_value, value, attributes, title, description
* @return
* A themed HTML string representing the form item group.
*/
function theme_radio($element) {
$output = '<input type="radio" ';
$output .= 'class="'. _form_get_class('form-radio', $element['#required'], form_get_error($element)) .'" ';

Dries Buytaert
committed
$output .= 'name="' . $element['#name'] .'" ';
$output .= 'value="'. $element['#return_value'] .'" ';
$output .= ($element['#value'] == $element['#return_value']) ? ' checked="checked" ' : ' ';
$output .= drupal_attributes($element['#attributes']) .' />';
if (!is_null($element['#title'])) {
$output = '<label class="option">'. $output .' '. $element['#title'] .'</label>';
return theme('form_element', NULL, $output, $element['#description'], $element['#name'], $element['#required'], form_get_error($element));
}
/**
* Format a set of radio buttons.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: title, value, options, description, required and attributes.
* @return
* A themed HTML string representing the radio button set.
*/
function theme_radios($element) {

Dries Buytaert
committed
if ($element['#title'] || $element['#description']) {
return theme('form_element', $element['#title'], $element['#children'], $element['#description'], $element['#id'], $element['#required'], form_get_error($element));

Dries Buytaert
committed
return $element['#children'];
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
/**
* Format a password_confirm item.
*
* @param $element
* An associative array containing the properties of the element.
* Properties used: title, value, id, required, error.
* @return
* A themed HTML string representing the form item.
*/
function theme_password_confirm($element) {
return theme('form_element', $element['#title'], '<div class="container-inline">'. $element['#children']. '</div>', $element['#description'], $element['#id'], $element['#required'], form_get_error($element));
}
/**
* Build password_confirm element.
*/
function password_confirm_after_build($form, $form_values, &$ref) {
if (isset($form_values['pass1'])) {
$pass1 = trim($form_values['pass1']);
$pass2 = trim($form_values['pass2']);
unset($form_values['pass1'], $form_values['pass2']);
if ($pass1 != $pass2) {
form_set_error('pass1', t('The specified passwords do not match.'));
}
elseif ($form['#required'] && !$pass1) {
form_set_error('pass1', t('Password field is required.'));
}
$ref = $pass1;
}
return $form;
}

Dries Buytaert
committed
* Format a date selection element.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: title, value, options, description, required and attributes.

Dries Buytaert
committed
* A themed HTML string representing the date selection boxes.
*/
function theme_date($element) {

Dries Buytaert
committed
$output = '<div class="container-inline">' . $element['#children'] . '</div>';
return theme('form_element', $element['#title'], $output, $element['#description'], $element['#id'], $element['#required'], form_get_error($element));

Dries Buytaert
committed
* Roll out a single date element.
*/
function expand_date($element) {
// Default to current date

Dries Buytaert
committed
if (!isset($element['#value'])) {
$element['#value'] = array('day' => format_date(time(), 'custom', 'j'),
'month' => format_date(time(), 'custom', 'n'),
'year' => format_date(time(), 'custom', 'Y'));
}
$element['#tree'] = TRUE;
// Determine the order of day, month, year in the site's chosen date format.
$format = variable_get('date_format_short', 'm/d/Y');
$sort = array();
$sort['day'] = max(strpos($format, 'd'), strpos($format, 'j'));
$sort['month'] = max(strpos($format, 'm'), strpos($format, 'M'));
$sort['year'] = strpos($format, 'Y');
asort($sort);
$order = array_keys($sort);
// Output multi-selector for date
foreach ($order as $type) {
switch ($type) {
case 'day':
$options = drupal_map_assoc(range(1, 31));
break;
case 'month':

Dries Buytaert
committed
$options = drupal_map_assoc(range(1, 12), 'map_month');
break;
case 'year':
$options = drupal_map_assoc(range(1900, 2050));
break;
}
$parents = $element['#parents'];
$parents[] = $type;
$element[$type] = array(
'#type' => 'select',
'#value' => $element['#value'][$type],
'#attributes' => $element['#attributes'],
'#options' => $options,
);
}
return $element;
}

Dries Buytaert
committed
/**
* Helper function for usage with drupal_map_assoc to display month names.
*/
function map_month($month) {
return format_date(gmmktime(0, 0, 0, $month, 2, 1970), 'custom', 'M', 0);
}
/**
* Helper function to load value from default value for checkboxes
*/
function checkboxes_value(&$form) {
$value = array();
foreach ((array)$form['#default_value'] as $key) {
$value[$key] = 1;
}
$form['#value'] = $value;
}

Dries Buytaert
committed
* Roll out a single radios element to a list of radios,
* using the options array as index.
*/
function expand_radios($element) {

Dries Buytaert
committed
if (count($element['#options']) > 0) {
foreach ($element['#options'] as $key => $choice) {

Dries Buytaert
committed
$element[$key] = array('#type' => 'radio', '#title' => $choice, '#return_value' => $key, '#default_value' => $element['#default_value'], '#attributes' => $element['#attributes'], '#parents' => $element['#parents'], '#spawned' => TRUE);
}
}
}
return $element;
}
/**
* Format a form item.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: title, value, description, required, error
* @return
* A themed HTML string representing the form item.
*/
function theme_item($element) {

Dries Buytaert
committed
return theme('form_element', $element['#title'], $element['#value'] . $element['#children'], $element['#description'], $element['#id'], $element['#required'], $element['#error']);
}
/**
* Format a checkbox.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: title, value, return_value, description, required
* @return
* A themed HTML string representing the checkbox.
*/
function theme_checkbox($element) {
$checkbox = '<input ';
$checkbox .= 'type="checkbox" ';
$checkbox .= 'class="'. _form_get_class('form-checkbox', $element['#required'], form_get_error($element)) . '" ';

Dries Buytaert
committed
$checkbox .= 'name="'. $element['#name'] .'" ';
$checkbox .= 'id="'. $element['#id'].'" ' ;
$checkbox .= 'value="'. $element['#return_value'] .'" ';

Dries Buytaert
committed
$checkbox .= ($element['#return_value'] == $element['#value']) ? ' checked="checked" ' : ' ';

Dries Buytaert
committed
$checkbox .= drupal_attributes($element['#attributes']) . ' />';
if (!is_null($element['#title'])) {
$checkbox = '<label class="option">'. $checkbox .' '. $element['#title'] .'</label>';
return theme('form_element', NULL, $checkbox, $element['#description'], $element['#name'], $element['#required'], form_get_error($element));
}
/**
* Format a set of checkboxes.
*
* @param $element
* An associative array containing the properties of the element.
* @return
* A themed HTML string representing the checkbox set.
*/
function theme_checkboxes($element) {

Dries Buytaert
committed
if ($element['#title'] || $element['#description']) {
return theme('form_element', $element['#title'], $element['#children'], $element['#description'], 'edit-'. $element['#name'], $element['#required'], form_get_error($element));

Dries Buytaert
committed
return $element['#children'];
}
}
function expand_checkboxes($element) {

Dries Buytaert
committed
$value = is_array($element['#value']) ? $element['#value'] : array();

Dries Buytaert
committed
if (count($element['#options']) > 0) {
if (!isset($element['#default_value']) || $element['#default_value'] == 0) {
$element['#default_value'] = array();

Dries Buytaert
committed
foreach ($element['#options'] as $key => $choice) {
if (!isset($element[$key])) {
$element[$key] = array('#type' => 'checkbox', '#processed' => TRUE, '#title' => $choice, '#return_value' => $key, '#default_value' => isset($value[$key]), '#attributes' => $element['#attributes']);
}
}
}
return $element;
}
function theme_submit($element) {
return theme('button', $element);
}
function theme_button($element) {

Dries Buytaert
committed
return '<input type="submit" class="form-'. $element['#button_type'] .'" name="'. $element['#name'] .'" value="'. check_plain($element['#value']) .'" '. drupal_attributes($element['#attributes']) ." />\n";
}
/**
* Format a hidden form field.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: value, edit
* @return
* A themed HTML string representing the hidden form field.
*/
function theme_hidden($element) {

Dries Buytaert
committed
return '<input type="hidden" name="'. $element['#name'] . '" value="'. check_plain($element['#value']) ."\" " . drupal_attributes($element['#attributes']) ." />\n";
}
/**
* Format a textfield.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: title, value, description, size, maxlength, required, attributes autocomplete_path
* @return
* A themed HTML string representing the textfield.
*/
function theme_textfield($element) {

Dries Buytaert
committed
$size = $element['#size'] ? ' size="' . $element['#size'] . '"' : '';
$class = '';
$extra = '';

Dries Buytaert
committed
if ($element['#autocomplete_path']) {
drupal_add_js('misc/autocomplete.js');
$class = ' form-autocomplete';

Dries Buytaert
committed
$extra = '<input class="autocomplete" type="hidden" id="'. $element['#id'] .'-autocomplete" value="'. check_url(url($element['#autocomplete_path'], NULL, NULL, TRUE)) .'" disabled="disabled" />';
$output = '<input type="text" maxlength="'. $element['#maxlength'] .'" class="'. _form_get_class("form-text$class", $element['#required'], form_get_error($element)) .'" name="'. $element['#name'] .'" id="'. $element['#id'] .'" '. $size .' value="'. check_plain($element['#value']) .'"'. drupal_attributes($element['#attributes']) .' />';
return theme('form_element', $element['#title'], $output, $element['#description'], $element['#id'], $element['#required'], form_get_error($element)). $extra;
}
/**
* Format a form.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: action, method, attributes, children
* @return
* A themed HTML string representing the form.
*/
function theme_form($element) {
// Anonymous div to satisfy XHTML compliancy.

Dries Buytaert
committed
$action = $element['#action'] ? 'action="' . check_url($element['#action']) . '" ' : '';
return '<form '. $action . ' method="'. $element['#method'] .'" '. drupal_attributes($element['#attributes']) .">\n<div>". $element['#children'] ."\n</div></form>\n";
}
/**
* Format a textarea.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: title, value, description, rows, cols, required, attributes
* @return
* A themed HTML string representing the textarea.
*/
function theme_textarea($element) {
$class = 'textarea';
if ($element['#resizable'] !== false) {
drupal_add_js('misc/textarea.js');
$class .= ' resizable';
}

Dries Buytaert
committed
$cols = $element['#cols'] ? ' cols="'. $element['#cols'] .'"' : '';
return theme('form_element', $element['#title'], '<textarea'. $cols .' rows="'. $element['#rows'] .'" name="'. $element['#name'] .'" id="' . $element['#id'] .'" class="'. _form_get_class($class, $element['#required'], form_get_error($element)) .'"'. drupal_attributes($element['#attributes']) .'>'. check_plain($element['#value']) .'</textarea>', $element['#description'], $element['#id'], $element['#required'], form_get_error($element));
}
/**
* Format HTML markup for use in forms.
*
* This is used in more advanced forms, such as theme selection and filter format.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: prefix, value, children and suffix.
* @return
* A themed HTML string representing the HTML markup.
*/
function theme_markup($element) {

Dries Buytaert
committed
return $element['#value'] . $element['#children'];
}
/**
* Format a password field.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: title, value, description, size, maxlength, required, attributes
* @return
* A themed HTML string representing the form.
*/
function theme_password($element) {

Dries Buytaert
committed
$size = $element['#size'] ? ' size="'. $element['#size'] .'" ' : '';
$output = '<input type="password" maxlength="'. $element['#maxlength'] .'" class="'. _form_get_class('form-text', $element['#required'], form_get_error($element)) .'" name="'. $element['#name'] .'" id="'. $element['#id'] .'" '. $size . drupal_attributes($element['#attributes']) .' />';
return theme('form_element', $element['#title'], $output, $element['#description'], $element['#id'], $element['#required'], form_get_error($element));
}
/**
* Format a weight selection menu.
*
* @param $element
* An associative array containing the properties of the element.

Dries Buytaert
committed
* Properties used: title, delta, description
* @return
* A themed HTML string representing the form.
*/
function theme_weight($element) {

Dries Buytaert
committed
for ($n = (-1 * $element['#delta']); $n <= $element['#delta']; $n++) {

Dries Buytaert
committed
$element['#options'] = $weights;
$element['#type'] = 'select';
return form_render($element);
}
/**
* Format a file upload field.
*
* @param $title
* The label for the file upload field.
* @param $name
* The internal name used to refer to the field.
* @param $size
* A measure of the visible size of the field (passed directly to HTML).
* @param $description
* Explanatory text to display after the form item.
* @param $required
* Whether the user must upload a file to the field.
* @return
* A themed HTML string representing the field.
*
* For assistance with handling the uploaded file correctly, see the API
* provided by file.inc.
*/
function theme_file($element) {

Dries Buytaert
committed
return theme('form_element', $element['#title'], '<input type="file" class="'. _form_get_class('form-file', $element['#required'], form_get_error($element)) .'" name="'. $element['#name'] .'"'. ($element['#attributes'] ? ' '. drupal_attributes($element['#attributes']) : '') .' id="'. form_clean_id($element['#id']) .'" size="'. $element['#size'] ."\" />\n", $element['#description'], $element['#id'], $element['#required'], form_get_error($element));
}
function _form_get_class($name, $required, $error) {
return $name. ($required ? ' required' : '') . ($error ? ' error' : '');
}
/**

Dries Buytaert
committed
* Remove invalid characters from an HTML ID attribute string.
*
* @param $id
* The ID to clean
* @return
* The cleaned ID
*/
function form_clean_id($id = NULL) {
$id = str_replace('][', '-', $id);
return $id;
}
/**
* @} End of "defgroup form".
*/