[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/multicolumncheckboxesradios/ -> multicolumncheckboxesradios.module (source)

   1  <?php
   2  // $Id: multicolumncheckboxesradios.module,v 1.39 2010/09/08 23:04:57 mattyoung Exp $
   3  /**
   4   * @file multicolumncheckboxesradios.module
   5   * Extends checkboxes/radios form element to have multi-column display option
   6   * See README.txt for details
   7   */
   8  
   9  
  10  
  11  
  12  function multicolumncheckboxesradios_widget_settings_alter(&$v, $op, $widget) {
  13    $widget_types = array_merge(array(
  14      'optionwidgets_buttons',
  15      'content_taxonomy_options',
  16      'nodereference_buttons',
  17      'userreference_buttons',
  18      'select_or_other_buttons',
  19    ), variable_get('multicolumncheckboxesradios_extra_widget_types', array()));
  20  
  21    if (in_array($widget['type'], $widget_types) || in_array($widget['widget_type'], $widget_types)) {
  22      switch ($op) {
  23        case 'form':
  24          $v['multicolumncheckboxesradios'] = array(
  25            '#type' => 'fieldset',
  26            '#title' => t('Multicolumn checkbox/radio buttons widget display settings'),
  27            '#description' => t('Adjust settings to display checkbox/radio buttons widget in columns.'),
  28            '#collapsible' => TRUE,
  29            '#collapsed' => FALSE,
  30            '#weight' => 2,
  31          );
  32          $v['multicolumncheckboxesradios']['mccr_width'] = array(
  33            '#type' => 'select',
  34            '#title' => t('Columns'),
  35            '#options' => array(0 => t('Multi-column off'), 1 => '1', 2 => '2', 3 => '3', 4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9'),
  36            '#default_value' => isset($widget['mccr_width']) ? $widget['mccr_width'] : 1,
  37            '#description' => t('The number of columns desired.'),
  38          );
  39          $v['multicolumncheckboxesradios']['mccr_row-major'] = array(
  40            '#type' => 'checkbox',
  41            '#title' => t('Row-major'),
  42            '#default_value' => isset($widget['mccr_row-major']) ? $widget['mccr_row-major'] : 0,
  43            '#description' => t('Select this to display check boxes/radios button across the screen first, then down.'),
  44          );
  45          $v['multicolumncheckboxesradios']['mccr_indent'] = array(
  46            '#type' => 'select',
  47            '#title' => t('Indent'),
  48            '#options' => array(0 => '0', 1 => '1', 2 => '2', 3 => '3', 4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8'),
  49            '#default_value' => isset($widget['mccr_indent']) ? $widget['mccr_indent'] : 0,
  50            '#description' => t('The number of indentation desired.'),
  51          );
  52          $v['multicolumncheckboxesradios']['mccr_caption'] = array(
  53            '#type' => 'textfield',
  54            '#title' => t('Caption'),
  55            '#default_value' => isset($widget['mccr_caption']) ? $widget['mccr_caption'] : '',
  56            '#description' => t('Table caption for the multicolumn checkboxes/radios.'),
  57          );
  58          $v['multicolumncheckboxesradios']['mccr_column-heading'] = array(
  59            '#type' => 'textarea',
  60            '#title' => t('Column heading'),
  61            '#default_value' => isset($widget['mccr_column-heading']) ? $widget['mccr_column-heading'] : '',
  62            '#description' => t('The column heading each on a separate line.'),
  63          );
  64          $v['multicolumncheckboxesradios']['mccr_row-heading'] = array(
  65            '#type' => 'textarea',
  66            '#title' => t('Row heading'),
  67            '#default_value' => isset($widget['mccr_row-heading']) ? $widget['mccr_row-heading'] : '',
  68            '#description' => t('The row heading each on a separate line.'),
  69          );
  70          break;
  71        case 'save':
  72          $v = array_merge($v, array('mccr_width', 'mccr_row-major', 'mccr_indent', 'mccr_caption', 'mccr_column-heading', 'mccr_row-heading'));
  73          break;
  74      }
  75    }
  76  }
  77  
  78  
  79  
  80  function multicolumncheckboxesradios_elements() {
  81    return array(
  82      'checkboxes' => array(
  83        '#multicolumn' => FALSE,
  84        '#process' => array('multicolumncheckboxesradios_element_process'),
  85      ),
  86      'radios' => array(
  87        '#multicolumn' => FALSE,
  88        '#process' => array('multicolumncheckboxesradios_element_process'),
  89      ),
  90    );
  91  }
  92  
  93  
  94  
  95  /**
  96   * Form element process function to add multi-column markup to checkboxes/radios
  97   *
  98   * @param $element
  99   * @return the processed element
 100   */
 101  function multicolumncheckboxesradios_element_process($element, $edit, &$form_state, $form) {
 102    // only do this if it's coming from CCK, otherwise, let the normal form element through
 103    if (empty($element['#multicolumn']) && isset($form['#field_info'])) {
 104      $widget = &$form['#field_info'][$element['#parents'][0]]['widget'];
 105      $temp = $widget['mccr_column-heading'];
 106      if (!empty($temp)) {
 107        $column_heading = explode("\r", trim($temp));
 108      }
 109      $temp = $widget['mccr_row-heading'];
 110      if (!empty($temp)) {
 111        $row_heading = explode("\r", trim($temp));
 112      }
 113      $element['#multicolumn'] = array(
 114        'width' => $widget['mccr_width'],
 115        'row-major' => $widget['mccr_row-major'],
 116        'indent' => $widget['mccr_indent'],
 117        'caption' => $widget['mccr_caption'],
 118        'column-heading' => $column_heading,
 119        'row-heading' => $row_heading,
 120      );
 121    }
 122  
 123    // if multicolumn option is not set or width parameter is not set, do nothing
 124    if (empty($element['#multicolumn']) || empty($element['#multicolumn']['width'])) {
 125      return $element;
 126    }
 127  
 128  
 129    $item_total = count($element['#options']) + (!empty($element['#multicolumn']['indent']) ? $element['#multicolumn']['indent'] : 0);
 130  
 131    // in case there are fewer items than the width, then the width is just the
 132    // item_total in one row
 133    $width = min($item_total, $element['#multicolumn']['width']);
 134    // if we end up with no elements, do nothing
 135    if ($width < 1) {
 136      return $element;
 137    }
 138  
 139  
 140    // copy and unset the checkboxe/radios child elements, we will rearrange them
 141    $keys = array_keys($element['#options']);
 142    $element_total = count($keys);
 143    $copy = array();
 144    for ($i = 0 ; $i < $element_total ; ++$i) {
 145      $copy[$keys[$i]] = $element[$keys[$i]];
 146      unset($element[$keys[$i]]);
 147    }
 148  
 149    $space = array(
 150          '#type' => 'markup',
 151          '#value' => '&nbsp;',
 152    );
 153  
 154    if (!empty($element['#multicolumn']['indent'])) {
 155      $indent = $element['#multicolumn']['indent'];
 156      $spaces = array();
 157      for ($i = 0 ; $i < $indent ; ++$i) {
 158        $spaces["multicolumncheckboxesradios-space-$i"] = $space;
 159      }
 160      $copy = $spaces + $copy;
 161    }
 162  
 163  
 164    if (empty($element['#multicolumn']['row-major'])) {
 165      $rows = _multicolumncheckboxesradios_chunk_transpose($copy, $width);
 166    }
 167    else {
 168      $rows = array_chunk($copy, $width, TRUE);
 169    }
 170  
 171    // fill the last row tail end with space if it's shorter than $width
 172    $last_row = &$rows[count($rows) - 1];
 173    while (($last_row_size = count($last_row)) < $width) {
 174      $last_row["multicolumncheckboxesradios-tail-space-$last_row_size"] = $space;
 175    }
 176  
 177    // prepend the row heading in each row
 178    $has_row_heading = !empty($element['#multicolumn']['row-heading']);
 179    if ($has_row_heading) {
 180      $i = 0;
 181      $row_count = count($rows);
 182      foreach ($element['#multicolumn']['row-heading'] as $h) {
 183        if ($i < $row_count) {
 184          $rows[$i] = array("multicolumncheckboxesradios-row-heading-$i" => array('#type' => 'markup', '#value' => $h)) + $rows[$i];
 185        }
 186        else {
 187          $rows[$i] = array("multicolumncheckboxesradios-row-heading-$i" => array('#type' => 'markup', '#value' => $h));
 188        }
 189        ++$i;
 190      }
 191      for ( ; $i < $row_count ; ++$i) {
 192        $rows[$i] = array("multicolumncheckboxesradios-row-heading-$i" => $space) + $rows[$i];
 193      }
 194    }
 195  
 196  
 197    $markup = '';
 198    $table_class = 'class="multicolumncheckboxesradios-table"';
 199    $has_column_heading = !empty($element['#multicolumn']['column-heading']);
 200    if ($has_column_heading) {
 201      $table_class = 'class="multicolumncheckboxesradios-table sticky-enabled"';
 202      drupal_add_js('misc/tableheader.js');
 203  
 204      $markup = _multicolumncheckboxesradios_make_heading_markup($element['#multicolumn']['column-heading'],
 205                                                                 'multicolumncheckboxesradios-column-heading',
 206                                                                 'multicolumncheckboxesradios-column-heading-first',
 207                                                                 'multicolumncheckboxesradios-column-heading-last');
 208      if ($has_row_heading) {
 209        $markup = '<th class="multicolumncheckboxesradios-heading-corner">&nbsp;</th>' . $markup;
 210      }
 211  
 212      $markup = '<thead><tr>' . $markup . '</tr></thead>';
 213    }
 214  
 215    $caption = trim($element['#multicolumn']['caption']);
 216    if (!empty($caption)) {
 217      $markup = '<caption>' . $caption . '</caption>' . $markup;
 218    }
 219  
 220    $element['multicolumncheckboxesradios-table-open'] = array(
 221      '#type' => 'markup',
 222      '#value' => '<table ' . $table_class . '>' . $markup . '<tbody>',
 223    );
 224  
 225  
 226    $flip = array('even' => 'odd', 'odd' => 'even');
 227    $class = 'even';
 228    foreach ($rows as &$row) {
 229      $class = $flip[$class];
 230      $keys = array_keys($row);
 231      $row_size = count($keys);
 232      switch ($row_size) {
 233        case 1:
 234          if ($has_row_heading) {
 235            $row[$keys[0]]['#prefix'] = "<tr class=\"$class\"><td class=\"multicolumncheckboxesradios-row-heading\">";
 236            $row[$keys[0]]['#suffix'] = '</td></tr>';
 237          }
 238          else {
 239            $row[$keys[0]]['#prefix'] = "<tr class=\"$class\"><td class=\"multicolumncheckboxesradios-column-first multicolumncheckboxesradios-column multicolumncheckboxesradios-column-last\">";
 240            $row[$keys[0]]['#suffix'] = '</td></tr>';
 241          }
 242          break;
 243        case 2:
 244          if ($has_row_heading) {
 245            $row[$keys[0]]['#prefix'] = "<tr class=\"$class\"><td class=\"multicolumncheckboxesradios-row-heading\">";
 246            $row[$keys[0]]['#suffix'] = '</td>';
 247            $row[$keys[1]]['#prefix'] = "<td class=\"multicolumncheckboxesradios-column-first multicolumncheckboxesradios-column multicolumncheckboxesradios-column-last\">";
 248            $row[$keys[1]]['#suffix'] = '</td></tr>';
 249          }
 250          else {
 251            $row[$keys[0]]['#prefix'] = "<tr class=\"$class\"><td class=\"multicolumncheckboxesradios-column-first multicolumncheckboxesradios-column\">";
 252            $row[$keys[0]]['#suffix'] = '</td>';
 253            $row[$keys[1]]['#prefix'] = '<td class="multicolumncheckboxesradios-column multicolumncheckboxesradios-column-last">';
 254            $row[$keys[1]]['#suffix'] = '</td></tr>';
 255          }
 256          break;
 257        default:
 258          if ($has_row_heading) {
 259            $row[$keys[0]]['#prefix'] = "<tr class=\"$class\"><td class=\"multicolumncheckboxesradios-row-heading\">";
 260            $row[$keys[0]]['#suffix'] = '</td>';
 261            $row[$keys[1]]['#prefix'] = '<td class="multicolumncheckboxesradios-column-first multicolumncheckboxesradios-column">';
 262            $row[$keys[1]]['#suffix'] = '</td>';
 263  
 264            $end_index = $row_size - 1;
 265            for ($i = 2 ; $i < $end_index ; ++$i) {
 266              $row[$keys[$i]]['#prefix'] = '<td class="multicolumncheckboxesradios-column">';
 267              $row[$keys[$i]]['#suffix'] = '</td>';
 268            }
 269  
 270            $row[$keys[$end_index]]['#prefix'] = '<td class="multicolumncheckboxesradios-column multicolumncheckboxesradios-column-last">';
 271            $row[$keys[$end_index]]['#suffix'] = '</td></tr>';
 272          }
 273          else {
 274            $row[$keys[0]]['#prefix'] = "<tr class=\"$class\"><td class=\"multicolumncheckboxesradios-column-first multicolumncheckboxesradios-column\">";
 275            $row[$keys[0]]['#suffix'] = '</td>';
 276  
 277            $end_index = $row_size - 1;
 278            for ($i = 1 ; $i < $end_index ; ++$i) {
 279              $row[$keys[$i]]['#prefix'] = '<td class="multicolumncheckboxesradios-column">';
 280              $row[$keys[$i]]['#suffix'] = '</td>';
 281            }
 282            $row[$keys[$end_index]]['#prefix'] = '<td class="multicolumncheckboxesradios-column multicolumncheckboxesradios-column-last">';
 283            $row[$keys[$end_index]]['#suffix'] = '</td></tr>';
 284          }
 285          break;
 286      }
 287    }
 288  
 289    foreach ($rows as &$row) {
 290      foreach ($row as $k => &$v) {
 291        $element[$k] = $v;
 292      }
 293    }
 294  
 295    $element['multicolumncheckboxesradios-table-close'] = array(
 296      '#type' => 'markup',
 297      '#value' => '</tbody></table>',
 298    );
 299  
 300    // default stylesheet
 301    drupal_add_css(drupal_get_path('module', 'multicolumncheckboxesradios') .'/multicolumncheckboxesradios.css');
 302  
 303    return $element;
 304  }
 305  
 306  
 307  /**
 308   * Break the 1D array into 2D chunk array, always satify the $width value by
 309   * varying the height of each chunk, then transpose it.
 310   *
 311   * @param array $items element to break up
 312   * @param int $width the width
 313   * @return array the result in 2D array
 314   */
 315  function _multicolumncheckboxesradios_chunk_transpose($items, $width) {
 316    $result = array();
 317  
 318      if ($width == 1) {
 319          foreach ($items as $k => &$v) {
 320              $result[] = array($k => $v);
 321          }
 322      }
 323    else {
 324        $keys = array_keys($items);
 325  
 326        $total = count($items);
 327        $counter = 0;
 328        $a = array();
 329        for ($i = 0 ; $i < $width ; ++$i) {
 330          $height = ceil(($total - $counter) / ($width - $i));
 331          $a[$i] = array_slice($keys, $counter, $height);
 332          $counter += $height;
 333        }
 334  
 335        // transpose
 336        array_unshift($a, NULL);
 337        $b = call_user_func_array('array_map', $a);
 338        // transpose can result in NULL value at the end, clear them
 339        $last_row = &$b[count($b) - 1];
 340  
 341        while (end($last_row) == NULL) {
 342          array_pop($last_row);
 343        }
 344  
 345        foreach ($b as $i => &$key_row) {
 346          $key_row = (array) $key_row;
 347          foreach ($key_row as $key) {
 348            $result[$i][$key] = $items[$key];
 349          }
 350        }
 351    }
 352    return $result;
 353  }
 354  
 355  
 356  /**
 357   * Take an array of string, produce a string of HTML markup of each string as
 358   * <div class="regular first">item-first</div><div class="regular">item-n</div>...
 359   * <div class="regular last">item-last</div>
 360   *
 361   * @param array $items string items
 362   * @param string $class_regular class name normally
 363   * @param string $class_first class name in the first position
 364   * @param string $class_last class name in the last position
 365   * @return string the HTML markup
 366   */
 367  function _multicolumncheckboxesradios_make_heading_markup($items, $class_regular, $class_first, $class_last) {
 368    $i = 1;
 369    $total = count($items);
 370    $result = '';
 371    foreach ($items as $item) {
 372      $class_string = $class_regular;
 373      if ($i == 1) {
 374        $class_string .= ' ' . $class_first;
 375      }
 376      if ($i == $total) {
 377        $class_string .= ' ' . $class_last;
 378      }
 379      $result .= "<th class=\"$class_string\">$item</th>";
 380      ++$i;
 381    }
 382    return $result;
 383  }


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7