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
* must be explicitly generated by modules. See the
* <a href="http://drupaldocs.org/api/head/file/contributions/docs/developer/topics/forms_api_reference.html">reference</a>
* and the
* <a href="http://drupaldocs.org/api/file/contributions/docs/developer/topics/forms_api.html">quickstart</a>
* guide for more.
*/
/**
* Check if the key is a property.
*/
function element_property($key) {
}
function element_properties($element) {
return array_filter(array_keys((array) $element), 'element_property');
}
/**
* Check if the key is a child.
*/
function element_child($key) {
}
function element_children($element) {
return array_filter(array_keys((array) $element), 'element_child');
}
/**
* Processes a form array, and produces the HTML output of a form.
* If there is input in the $_POST['edit'] variable, this function
* will attempt to validate it, using <code>drupal_validate_form</code>,

Dries Buytaert
committed
* and then submit the form using <code>drupal_submit_form</code>.
*
* @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());
}
$form['form_token'] = array('#type' => 'hidden', '#value' => md5($_SERVER['REMOTE_ADDR'] . $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 (function_exists('theme_' . $form_id)) {

Dries Buytaert
committed
$form['#theme'] = $form_id;
}
elseif (function_exists('theme_' . $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))) {
// An empty checkbox returns 0, an empty textfield returns '' so we use empty().
// Unfortunately, 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 (is_array($elements['#value'])) {
$value = $elements['#type'] == 'checkboxes' ? array_keys(array_filter($elements['#value'])) : $elements['#value'];
foreach ($value as $v) {
if (!isset($elements['#options'][$v])) {
form_error($elements, $message);
}
}
}
elseif (!isset($elements['#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]);
}
}
189
190
191
192
193
194
195
196
197
198
199
200
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
/**
* 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']))) {
$form += $info;
}

Dries Buytaert
committed
if ($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'])) {
$form['#value'] = 0; // checkbox unchecked
}
}
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
}

Dries Buytaert
committed
if ($_POST[$form['#name']] == $form['#value']) {
$form_submitted = $form_submitted || $form['#form_submitted'];
}
}
}
// Allow for elements to expand to multiple elements. Radios, checkboxes and files for instance.
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 ($form['#input']) {
$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);
# 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 (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;
}
/**
* Renders a HTML form given an form tree. Recursively iterates over each of
* 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
* <code>drupal_get_form()</code>.
*
* @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");

Dries Buytaert
committed
if (!$elements['#children']) {
/* render all the children using a theme function */

Dries Buytaert
committed
if ($elements['#theme'] && !$elements['#theme_used']) {
$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 */

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

Dries Buytaert
committed
if ($content) {
return $elements['#prefix'] . $content . $elements['#suffix'];
}
}
/**
* Function used by uasort in form render to sort form via 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,
'#tree' => FALSE,
'#parents' => $parents

Dries Buytaert
committed
if ($refresh || !isset($cache)) {
$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];
}
/**
* Format a dropdown menu or scrolling selection box.
*
* @param $element
* An associative array containing the properties of the element.
* 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
foreach ($element['#options'] as $key => $choice) {
if (is_array($choice)) {
$select .= '<optgroup label="'. $key .'">';
foreach ($choice as $key => $choice) {

Dries Buytaert
committed
$select .= '<option value="'. $key .'"'. (is_array($element['#value']) ? (in_array($key, $element['#value']) ? ' selected="selected"' : '') : ($element['#value'] == $key ? ' selected="selected"' : '')) .'>'. check_plain($choice) .'</option>';
}
$select .= '</optgroup>';
}
else {

Dries Buytaert
committed
$select .= '<option value="'. $key .'"'. (is_array($element['#value']) ? (in_array($key, $element['#value']) ? ' selected="selected"' : '') : ($element['#value'] == $key ? ' selected="selected"' : '')) .'>'. check_plain($choice) .'</option>';
return theme('form_element', $element['#title'], '<select name="'. $element['#name'] .''. ($element['#multiple'] ? '[]' : '') .'"'. ($element['#multiple'] ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) .' id="' . $element['#id'] .'" '. $size .'>'. $select .'</select>', $element['#description'], $element['#id'], $element['#required'], form_get_error($element));
}
/**
* Format a group of form items.
*
* @param $element
* An associative array containing the properties of the element.
* Properties used : attributes, title, 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.
* 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.
* 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'];
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
/**
* 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.
* Properties used : title, value, options, description, required and attributes.
* @return

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.
* 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.
* 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, '#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.
* 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.
* 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'] . '"' : '';
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.
* 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.
* 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.
* 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.
* 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 $class", $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.
* 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) {
return theme('form_element', $element['#title'], '<input type="file" class="'. _form_get_class('form-file', $element['#required'], form_get_error($element)) .'" name="'. $element['#name'] .'" 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' : '');
}
/**
* 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".
*/