Esempio n. 1
2
 /**
  * #pre_render callback to transform children of an element into #rows suitable for theme_table().
  *
  * This function converts sub-elements of an element of #type 'table' to be
  * suitable for theme_table():
  * - The first level of sub-elements are table rows. Only the #attributes
  *   property is taken into account.
  * - The second level of sub-elements is converted into columns for the
  *   corresponding first-level table row.
  *
  * Simple example usage:
  * @code
  * $form['table'] = array(
  *   '#type' => 'table',
  *   '#header' => array(t('Title'), array('data' => t('Operations'), 'colspan' => '1')),
  *   // Optionally, to add tableDrag support:
  *   '#tabledrag' => array(
  *     array(
  *       'action' => 'order',
  *       'relationship' => 'sibling',
  *       'group' => 'thing-weight',
  *     ),
  *   ),
  * );
  * foreach ($things as $row => $thing) {
  *   $form['table'][$row]['#weight'] = $thing['weight'];
  *
  *   $form['table'][$row]['title'] = array(
  *     '#type' => 'textfield',
  *     '#default_value' => $thing['title'],
  *   );
  *
  *   // Optionally, to add tableDrag support:
  *   $form['table'][$row]['#attributes']['class'][] = 'draggable';
  *   $form['table'][$row]['weight'] = array(
  *     '#type' => 'textfield',
  *     '#title' => t('Weight for @title', array('@title' => $thing['title'])),
  *     '#title_display' => 'invisible',
  *     '#size' => 4,
  *     '#default_value' => $thing['weight'],
  *     '#attributes' => array('class' => array('thing-weight')),
  *   );
  *
  *   // The amount of link columns should be identical to the 'colspan'
  *   // attribute in #header above.
  *   $form['table'][$row]['edit'] = array(
  *     '#type' => 'link',
  *     '#title' => t('Edit'),
  *     '#url' => Url::fromRoute('entity.test_entity.edit_form', ['test_entity' => $row]),
  *   );
  * }
  * @endcode
  *
  * @param array $element
  *   A structured array containing two sub-levels of elements. Properties used:
  *   - #tabledrag: The value is a list of $options arrays that are passed to
  *     drupal_attach_tabledrag(). The HTML ID of the table is added to each
  *     $options array.
  *
  * @return array
  *
  * @see theme_table()
  * @see drupal_process_attached()
  * @see drupal_attach_tabledrag()
  */
 public static function preRenderTable($element)
 {
     foreach (Element::children($element) as $first) {
         $row = array('data' => array());
         // Apply attributes of first-level elements as table row attributes.
         if (isset($element[$first]['#attributes'])) {
             $row += $element[$first]['#attributes'];
         }
         // Turn second-level elements into table row columns.
         // @todo Do not render a cell for children of #type 'value'.
         // @see http://drupal.org/node/1248940
         foreach (Element::children($element[$first]) as $second) {
             // Assign the element by reference, so any potential changes to the
             // original element are taken over.
             $column = array('data' => &$element[$first][$second]);
             // Apply wrapper attributes of second-level elements as table cell
             // attributes.
             if (isset($element[$first][$second]['#wrapper_attributes'])) {
                 $column += $element[$first][$second]['#wrapper_attributes'];
             }
             $row['data'][] = $column;
         }
         $element['#rows'][] = $row;
     }
     // Take over $element['#id'] as HTML ID attribute, if not already set.
     Element::setAttributes($element, array('id'));
     // Add sticky headers, if applicable.
     if (count($element['#header']) && $element['#sticky']) {
         $element['#attached']['library'][] = 'core/drupal.tableheader';
         // Add 'sticky-enabled' class to the table to identify it for JS.
         // This is needed to target tables constructed by this function.
         $element['#attributes']['class'][] = 'sticky-enabled';
     }
     // If the table has headers and it should react responsively to columns hidden
     // with the classes represented by the constants RESPONSIVE_PRIORITY_MEDIUM
     // and RESPONSIVE_PRIORITY_LOW, add the tableresponsive behaviors.
     if (count($element['#header']) && $element['#responsive']) {
         $element['#attached']['library'][] = 'core/drupal.tableresponsive';
         // Add 'responsive-enabled' class to the table to identify it for JS.
         // This is needed to target tables constructed by this function.
         $element['#attributes']['class'][] = 'responsive-enabled';
     }
     // If the custom #tabledrag is set and there is a HTML ID, add the table's
     // HTML ID to the options and attach the behavior.
     if (!empty($element['#tabledrag']) && isset($element['#attributes']['id'])) {
         foreach ($element['#tabledrag'] as $options) {
             $options['table_id'] = $element['#attributes']['id'];
             drupal_attach_tabledrag($element, $options);
         }
     }
     return $element;
 }
Esempio n. 2
-1
 /**
  * Performs pre-render tasks on field_ui_table elements.
  *
  * This function is assigned as a #pre_render callback in
  * field_ui_element_info().
  *
  * @param array $element
  *   A structured array containing two sub-levels of elements. Properties
  *   used:
  *   - #tabledrag: The value is a list of $options arrays that are passed to
  *     drupal_attach_tabledrag(). The HTML ID of the table is added to each
  *     $options array.
  *
  * @see drupal_render()
  * @see drupal_pre_render_table()
  */
 public function tablePreRender($elements)
 {
     $js_settings = array();
     // For each region, build the tree structure from the weight and parenting
     // data contained in the flat form structure, to determine row order and
     // indentation.
     $regions = $elements['#regions'];
     $tree = array('' => array('name' => '', 'children' => array()));
     $trees = array_fill_keys(array_keys($regions), $tree);
     $parents = array();
     $children = Element::children($elements);
     $list = array_combine($children, $children);
     // Iterate on rows until we can build a known tree path for all of them.
     while ($list) {
         foreach ($list as $name) {
             $row =& $elements[$name];
             $parent = $row['parent_wrapper']['parent']['#value'];
             // Proceed if parent is known.
             if (empty($parent) || isset($parents[$parent])) {
                 // Grab parent, and remove the row from the next iteration.
                 $parents[$name] = $parent ? array_merge($parents[$parent], array($parent)) : array();
                 unset($list[$name]);
                 // Determine the region for the row.
                 $region_name = call_user_func($row['#region_callback'], $row);
                 // Add the element in the tree.
                 $target =& $trees[$region_name][''];
                 foreach ($parents[$name] as $key) {
                     $target =& $target['children'][$key];
                 }
                 $target['children'][$name] = array('name' => $name, 'weight' => $row['weight']['#value']);
                 // Add tabledrag indentation to the first row cell.
                 if ($depth = count($parents[$name])) {
                     $children = Element::children($row);
                     $cell = current($children);
                     $indentation = array('#theme' => 'indentation', '#size' => $depth);
                     $row[$cell]['#prefix'] = drupal_render($indentation) . (isset($row[$cell]['#prefix']) ? $row[$cell]['#prefix'] : '');
                 }
                 // Add row id and associate JS settings.
                 $id = drupal_html_class($name);
                 $row['#attributes']['id'] = $id;
                 if (isset($row['#js_settings'])) {
                     $row['#js_settings'] += array('rowHandler' => $row['#row_type'], 'name' => $name, 'region' => $region_name);
                     $js_settings[$id] = $row['#js_settings'];
                 }
             }
         }
     }
     // Determine rendering order from the tree structure.
     foreach ($regions as $region_name => $region) {
         $elements['#regions'][$region_name]['rows_order'] = array_reduce($trees[$region_name], array($this, 'reduceOrder'));
     }
     $elements['#attached']['js'][] = array('type' => 'setting', 'data' => array('fieldUIRowsData' => $js_settings));
     // If the custom #tabledrag is set and there is a HTML ID, add the table's
     // HTML ID to the options and attach the behavior.
     // @see drupal_pre_render_table()
     if (!empty($elements['#tabledrag']) && isset($elements['#attributes']['id'])) {
         foreach ($elements['#tabledrag'] as $options) {
             $options['table_id'] = $elements['#attributes']['id'];
             drupal_attach_tabledrag($elements, $options);
         }
     }
     return $elements;
 }