| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 | <?php/** * @file * All theme functions for the Hierarchical Select module. *//** * @ingroup themeable * @{ *//** * Return a themed Hierarchical Select form element. * * @param array $variables *   An associative array containing the properties of the element. *   Properties used: title, description, id, required * * @return string *   A string representing the form element. * * @ingroup themeable */function theme_hierarchical_select_form_element($variables) {  $element = $variables['element'];  $value = $variables['value'];  $output = '<div class="form-item hierarchical-select-wrapper-wrapper"';  if (!empty($element['#id'])) {    $output .= ' id="' . $element['#id'] . '-wrapper"';  }  $output .= ">\n";  $required = !empty($element['#required']) ? '<span class="form-required" title="' . t('This field is required.') . '">*</span>' : '';  if (!empty($element['#title'])) {    $title = $element['#title'];    if (!empty($element['#id'])) {      $output .= ' <label for="' . $element['#id'] . '">' . t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) . "</label>\n";    }    else {      $output .= ' <label>' . t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) . "</label>\n";    }  }  $output .= " $value\n";  if (!empty($element['#description'])) {    $output .= ' <div class="description">' . $element['#description'] . "</div>\n";  }  $output .= "</div>\n";  return $output;}/** * Format a hierarchical select. * * @param array $variables *   An associative array containing the properties of the element. * @return string *   A themed HTML string representing the form element. */function theme_hierarchical_select($variables) {  $element = $variables['element'];  $output = '';  // Update $element['#attributes']['class'].  if (!isset($element['#attributes']['class'])) {    $element['#attributes']['class'] = array();  }  $hsid = $element['hsid']['#value'];  $level_labels_style = variable_get('hierarchical_select_level_labels_style', 'none');  $classes = array(   'hierarchical-select-wrapper',   "hierarchical-select-level-labels-style-$level_labels_style",   // Classes that make it possible to override the styling of specific   // instances of Hierarchical Select, based on either the ID of the form   // element or the config that it uses.   'hierarchical-select-wrapper-for-name-' . $element['#id'],   (isset($element['#config']['config_id'])) ? 'hierarchical-select-wrapper-for-config-' . $element['#config']['config_id'] : NULL,  );  $element['#attributes']['class'] = array_merge($element['#attributes']['class'], $classes);  $element['#attributes']['id'] = "hierarchical-select-$hsid-wrapper";  $element['#id'] = "hierarchical-select-$hsid-wrapper"; // This ensures the label's for attribute is correct.  return '<div ' . drupal_attributes($element['#attributes']) . '>' . drupal_render_children($element) . '</div>';}/** * Format the container for all selects in the hierarchical select. * * @param array $variables *   An associative array containing the properties of the element. * @return string *   A themed HTML string representing the form element. */function theme_hierarchical_select_selects_container($variables) {  $element = $variables['element'];  $output = '';  $output .= '<div class="hierarchical-select clearfix">';  $output .= drupal_render_children($element);  $output .= '</div>';  return $output;}/** * Format a select in the .hierarchial-select div: prevent it from being * wrapped in a div. This simplifies the CSS and JS code. * * @param array $variables *   An associative array containing the properties of the element. * @return string *   A themed HTML string representing the form element. */function theme_hierarchical_select_select($variables) {    $element = $variables['element'];  element_set_attributes($element, array('id', 'name', 'size'));  _form_set_class($element, array('form-select'));  return '<select' . drupal_attributes($element['#attributes']) . '>' . _hierarchical_select_options($element) . '</select>';}/** * Format an item separator (for use in a lineage). */function theme_hierarchical_select_item_separator($variables) {  $output = '';  $output .= '<span class="hierarchical-select-item-separator">';  $output .= '›';  $output .= '</span>';  return $output;}/** * Format a special option in a Hierarchical Select select. For example the * "none" option or the "create new item" option. This theme function allows * you to change how a special option is indicated textually. * * @param array $variables *   A special option. * @return string *   A textually indicated special option. */function theme_hierarchical_select_special_option($variables) {  $option = $variables['option'];  return '<' . $option . '>';}/** * Forms API theming callback for the dropbox. Renders the dropbox as a table. * * @param array $variables *   An element for which the #theme property was set to this function. * @return string *   A themed HTML string. */function theme_hierarchical_select_dropbox_table($variables) {  $element = $variables['element'];  $output = '';  $class = 'dropbox';  if (form_get_error($element) === '') {    $class .= ' error';  }  $title     = $element['title']['#value'];  $separator = $element['separator']['#value'];  $is_empty  = $element['is_empty']['#value'];  $separator_html = '<span class="hierarchical-select-item-separator">' . $separator . '</span>';  $output .= '<div class="' . $class . '">';  $output .= '<table>';  $output .= '<caption class="dropbox-title">' . $title . '</caption>';  $output .= '<tbody>';  if (!$is_empty) {    // Each lineage in the dropbox corresponds to an entry in the dropbox table.    $lineage_count = count(element_children($element['lineages']));    for ($x = 0; $x < $lineage_count; $x++) {      $db_entry = $element['lineages']["lineage-$x"];      $zebra = $db_entry['#zebra'];      $first = $db_entry['#first'];      $last  = $db_entry['#last'];      // The deepest level is the number of child levels minus one. This "one"      // is the element for the "Remove" checkbox.      $deepest_level = count(element_children($db_entry)) - 1;      $output .= '<tr class="dropbox-entry ' . $first . ' ' . $last . ' ' . $zebra . '">';      $output .= '<td>';      // Each item in a lineage is separated by the separator string.      for ($depth = 0; $depth < $deepest_level; $depth++) {        $output .= drupal_render($db_entry[$depth]);        if ($depth < $deepest_level - 1) {          $output .= $separator_html;        }      }      $output .= '</td>';      $output .= '<td class="dropbox-remove">' . drupal_render($db_entry['remove']) . '</td>';      $output .= '</tr>';    }  }  else {    $output .= '<tr class="dropbox-entry first last dropbox-is-empty"><td>';    $output .= t('Nothing has been selected.');    $output .= '</td></tr>';  }  $output .= '</tbody>';  $output .= '</table>';  $output .= '</div>';  return $output;}/** * Themeing function to render the level_labels settings as a table. */// TODO: rename $form to $element for consistency (and update hook_theme() after that), make the comment consistent./** * @todo Please document this function. * @see http://drupal.org/node/1354 */function theme_hierarchical_select_common_config_form_level_labels($variables) {  $form = $variables['form'];  // Recover the stored strings.  $strings = $form['#strings'];  $output = '';  $header = array(t('Level'), t('Label'));  $rows = array();  $output .= drupal_render($form['status']);  $output .= '<div class="level-labels-settings">';  if (isset($form['labels']) && count(element_children($form['labels']))) {    foreach (element_children($form['labels']) as $depth) {      $row = array();      $row[]['data'] = ($depth == 0) ? t('Root level') : t('Sublevel !depth', array('!depth' => $depth));      $row[]['data'] = drupal_render($form['labels'][$depth]);      $rows[] = $row;    }    // Render the table.    $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('style' => 'width: auto;')));  }  else {    // No levels exist yet in the hierarchy!    $output .= '<p><strong>';    $output .= t('There are no levels yet in this !hierarchy!', array('!hierarchy' => $strings['hierarchy']));    $output .= '</strong></p>';  }  $output .= '</div>';  // Render the remaining form items.  $output .= drupal_render_children($form);  return $output;}/** * Themeing function to render the per-level editability settings as a table, * (these are the item_types and allowed_levels settings). */// TODO: rename $form to $element for consistency (and update hook_theme() after that), make the comment consistent./** * @todo Please document this function. * @see http://drupal.org/node/1354 */function theme_hierarchical_select_common_config_form_editability($variables) {  $form = $variables['form'];  // Recover the stored strings.  $strings = $form['#strings'];  $output = '';  $header = array(t('Level'), t('Allow'), t('!item_type', array('!item_type' => drupal_ucfirst($strings['item_type']))));  $rows = array();  $output .= drupal_render($form['status']);  $output .= '<div class="editability-per-level-settings">';  if (isset($form['item_types']) && count(element_children($form['item_types']))) {    foreach (element_children($form['item_types']) as $depth) {      $row = array();      $row[]['data'] = ($depth == 0) ? t('Root level') : t('Sublevel !depth', array('!depth' => $depth));      $row[]['data'] = drupal_render($form['allowed_levels'][$depth]);      $row[]['data'] = drupal_render($form['item_types'][$depth]);      $rows[] = $row;    }    // Render the table and description.    $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('style' => 'width: auto;'), 'caption' => '<em>' . t('Per-level settings for creating new !items.', array('!items' => $strings['items']))));    $output .= '<div class="description">';    $output .= t(      'The %item_type you enter for each level is what will be used in      each level to replace a "<create new item>" option with a      "<create new %item_type>" option, which is often more      intuitive.',      array(        '%item_type' => $strings['item_type'],      )    );    $output .= '</div>';  }  else {    // No levels exist yet in the hierarchy!    $output .= '<p><strong>';    $output .= t('There are no levels yet in this !hierarchy!', array('!hierarchy' => $strings['hierarchy']));    $output .= '</strong></p>';  }  $output .= '</div>';  // Render the remaining form items.  $output .= drupal_render_children($form);  return $output;}/** * Themeing function to render a selection (of items) according to a given * Hierarchical Select configuration as one or more lineages. * * @param $selection *   A selection of items of a hierarchy. * @param $config *   A config array with at least the following settings: *   - module *   - save_lineage *   - params */function theme_hierarchical_select_selection_as_lineages($variables) {  $selection = $variables['selection'];  $config = $variables['config'];  $output = '';  $selection = (!is_array($selection)) ? array($selection) : $selection;  // Generate a dropbox out of the selection. This will automatically  // calculate all lineages for us.  $selection = array_keys($selection);  $dropbox = _hierarchical_select_dropbox_generate($config, $selection);  // Actual formatting.  foreach ($dropbox->lineages as $id => $lineage) {    if ($id > 0) {      $output .= '<br />';    }    $items = array();    foreach ($lineage as $level => $item) {      $items[] = $item['label'];    }    $output .= implode('<span class="hierarchical-select-item-separator">›</span>', $items);  }  // Add the CSS.  drupal_add_css(drupal_get_path('module', 'hierarchical_select') . '/hierarchical_select.css');  return $output;}/** * @} End of "ingroup themeable". *///----------------------------------------------------------------------------// Private functions./** * This is an altered clone of form_select_options(). The reason: I need to be * able to set a class on an option element if it contains a level label, to * allow for level label styles. * TODO: rename to _hierarchical_select_select_options(). */function _hierarchical_select_options($element) {  if (!isset($choices)) {    $choices = $element['#options'];  }  // array_key_exists() accommodates 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 = isset($element['#value']) && is_array($element['#value']);  $options = '';  foreach ($choices as $key => $choice) {    $key = (string) $key;    if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) {      $selected = ' selected="selected"';    }    else {      $selected = '';    }    // If an option DOES NOT have child info, then it's a special option:    // - label_\d+ (level label)    // - none ("<none>")    // - create_new_item ("<create new item>")    // Only when it's a level label, we have to add a class to this option.    if (!isset($element['#childinfo'][$key])) {      $class = (preg_match('/label_\d+/', $key)) ? ' level-label' : '';    }    else {      $class = ($element['#childinfo'][$key] == 0) ? 'has-no-children' : 'has-children';    }    $options .= '<option value="' . check_plain($key) . '" class="' . $class . '"' . $selected . '>' . check_plain($choice) . '</option>';  }  return $options;}
 |