Great module.
The ability to merge cells, to create tds' that span multiple columns would be great.
As an example, having an information row at the bottom of a table which spans all columns is a common feature, but currently not possible.
On a 3 column table, you would end up with HTML output like so:

<tr>
<td colspan="3">
<p>Text goes here</p>
</td>
</tr>
CommentFileSizeAuthor
#4 2.png22.16 KBrunzipel
#4 1.png85.29 KBrunzipel
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

hockey2112’s picture

I am also very interested in this feature. Has it been given any consideration?

btopro’s picture

dobe’s picture

Issue summary: View changes

I achieved this quick and dirty by modifieing the theme. I had migrated specifcation tables from a wordpress site using tablepress. So all the fields that you wanted to have a colspan on the next field would have "#colspan#" for the data.

<?php
/**
 * Theme function for table view
 */
function mytheme_tablefield_view($variables) {
  $attributes = array(
    'id' => 'tablefield-' . $variables['delta'],
    'class' => array(
      'tablefield'
    ),
  );

  // If the user has access to the csv export option, display it now.
  $export = '';
  if ($variables['export'] && user_access('export tablefield')) {
    $url = sprintf('tablefield/export/%s/%s/%s/%s/%s', $variables['entity_type'], $variables['entity_id'], $variables['field_name'], $variables['langcode'], $variables['delta']);
    $export = '<div id="tablefield-export-link-' . $variables['delta'] . '" class="tablefield-export-link">' . l(t('Export Table Data'), $url) . '</div>';
  }


  foreach ($variables['rows'] as $row => $columns) {
    foreach ($columns as $col => $cell) {
      preg_match("/(?:#colspan#)/", $cell['data'], $match);
      // Is #colspan# in the data.
      if(!empty($match)) {
        $keys =  array_keys($variables['rows'][$row]);
        $search = array_search($col,$keys);
        $prev = $keys[intval($search)-1];
        $colspan = isset($variables['rows'][$row][$prev]['colspan']) ? $variables['rows'][$row][$prev]['colspan'] : 1;
        $variables['rows'][$row][$prev]['colspan'] = $colspan + 1;
        unset($variables['rows'][$row][$col]);
      }
    }
  }

  return '<div id="tablefield-wrapper-' . $variables['delta'] . '" class="tablefield-wrapper">'
  . theme('table',
    array(
      'header' => $variables['header'],
      'rows' => $variables['rows'],
      'attributes' => $attributes,
    )
  )
  . $export
  . '</div>';
}
?>

So basically with the code above you would put #colspan# and the cell to the left would merge. I am sure you could do this with rowspans as well but this code doesn't do that currently. I wish I had more time to work on this but I am on a time schedule atm.

runzipel’s picture

FileSize
85.29 KB
22.16 KB

Thanks to @dobe, withe the help of @kafae here is a little improvement of the dirtyness above:

tags:
#rowspan# merges cell with above
#colspan# merges cell with left
#remove# for "lost" cells

table output
table input


/**
 * Theme function for table view
 */
function theme_tablefield_view($variables) {
  $attributes = array(
    'id' => 'tablefield-' . $variables['delta'],
    'class' => array(
      'tablefield'
    ),
  );

  // If the user has access to the csv export option, display it now.
  $export = '';
  if ($variables['export'] && user_access('export tablefield')) {
    $url = sprintf('tablefield/export/%s/%s/%s/%s/%s', $variables['entity_type'], $variables['entity_id'], $variables['field_name'], $variables['langcode'], $variables['delta']);
    $export = '<div id="tablefield-export-link-' . $variables['delta'] . '" class="tablefield-export-link">' . l(t('Export Table Data'), $url) . '</div>';
  }

 $previous_row = false;

 foreach ( $variables['rows'] as $row => $columns) {
   foreach ($columns as $col => $cell) {
     preg_match("/(?:#colspan#)/", $cell['data'], $match);
     // Is #colspan# in the data.
     if(!empty($match)) {
       $keys =  array_keys($variables['rows'][$row]);
       $search = array_search($col,$keys);
       $prev = $keys[intval($search)-1];
       $colspan = isset($variables['rows'][$row][$prev]['colspan']) ? $variables['rows'][$row][$prev]['colspan'] : 1;
       $variables['rows'][$row][$prev]['colspan'] = $colspan + 1;
       unset($variables['rows'][$row][$col]);
     }
     preg_match("/(?:#rowspan#)/", $cell['data'], $match);
     // Is #rowpsan# in the data.
     if(!empty($match)) {
        if( $previous_row !== false ) {
          $keys =  array_keys($variables['rows'][$row]);
          $search = array_search($col,$keys);
          $col = $keys[intval($search)];
          
          $prev_row = $previous_row;
          while ( true ) {
            if( isset( $variables['rows'][ $prev_row ][$col] ) ) {
              $rowspan = isset($variables['rows'][ $prev_row ][$col]['rowspan']) ? $variables['rows'][ $prev_row ][$col]['rowspan'] : 1;
              $variables['rows'][$prev_row][$col]['rowspan'] = $rowspan + 1;
              break;    
            }
            $prev_row--;
          }
          unset($variables['rows'][$row][$col]);
        }
     }
     // remove lost cells #remove#
     preg_match("/(?:#remove#)/", $cell['data'], $match);
     if(!empty($match)) {
       unset($variables['rows'][$row][$col]);
     }
   }
   $previous_row = $row;
 }
vitalie’s picture

This looks like a custom override to the theme function that can be done in a custom module. I do not think this feature, in the form it is now, will make it into the tablefield module.

dobe’s picture

While you are correct about the theme override. What is being shown here is proof of concept on a way to achieve this feature. Which is certainly a lot closer than having no solution for users who are looking to be able to do something theoretically simple. If you don't want to include it that is fine. But the request for the feature still exists.

vitalie’s picture

@dobe I am sorry, that's exactly what I wanted to say. It's great that this proof of concept exists and the issue is still active as you can see. This could be developed further into a helper module that could be included into tablefield. Current editor's UI experience is quite demanding, wouldn't you say?

lolandese’s picture

Closed #2848439: Merge two cells into one on the first row as a duplicate of this one.

lolandese’s picture

Version: 7.x-2.2 » 7.x-3.x-dev
kunago’s picture

Thank you for great work. It is easy to make this work with 7.x-3.x version of this module. Just create an overwrite function in your template.php. I am including an example: https://pastebin.com/MzdkpKB5

kunago’s picture

If you find the rowspan part memory intensive like I did, there is another way to achieve similar result, by cell borders. Steps would be like following:

  1. you need to remove all the table styling at first, especially that set on table rows; simply make sure all your border styling is gone
  2. to seperate rows, place the styling on table data/cell; I put "border-top: 1x solid #ccc
  3. when a table data/cell does contain "#rowspan#", remove the string and add a special class for that cell, e.g. "no-border"
  4. adjust your CSS not to display cell border with that class

Result is similar (although not as nice and clean) and you don't put stress on your CPU while generating complicated or long tables.

cristianalcaraz’s picture

Hi!

I've made a version for the Drupal 8 2.x branch using the code provided by @runzipel Thanks!
I hope someone finds it useful :)

<?php
/**
 * Preprocess function for table view
 * @param $variables
 */
function template_preprocess_table(&$variables) {
    $previous_row = FALSE;
    foreach( $variables['rows'] as $row_key => $row):
      $colspan = 2;
      foreach($row['cells'] as $col_key => $cell):
        if(!isset($spancol[$col_key])):
          $spancol[$col_key]['rowspan'] = 2;
          $spancol[$col_key]['spancol'] = FALSE;
        endif;
        preg_match("/(?:#colspan#)/", $cell['content'], $match);
        // Is #colspan# in the data.
        if(!empty($match)):
          $keys = array_keys($variables['rows'][$row_key]['cells']);
          $search = array_search($col_key, $keys);
          $prev = $keys[intval($search) - 1];
          $attributes = clone $variables['rows'][$row_key]['cells'][$prev]['attributes'];
          $attributes['colspan'] = $colspan;
          $variables['rows'][$row_key]['cells'][$prev]['attributes'] = $attributes;
          unset($variables['rows'][$row_key]['cells'][$col_key]);
          $colspan++;
        else:
          $colspan = 2;
        endif;
        preg_match("/(?:#rowspan#)/", $cell['content'], $match);
        // Is #rowpsan# in the data.
        if(!empty($match)):
          if($previous_row !== FALSE):
            $keys = array_keys($variables['rows'][$row_key]['cells']);
            $search = array_search($col_key, $keys);
            $col = $keys[intval($search)];

            $prev_row = $previous_row;
            while(true):
              if(isset($variables['rows'][$prev_row]['cells'][$col])):
                $attributes = clone $variables['rows'][$prev_row]['cells'][$col]['attributes'];
                $attributes['rowspan'] = $spancol[$col_key]['rowspan'];
                $variables['rows'][$prev_row]['cells'][$col]['attributes'] = $attributes;
                $spancol[$col_key]['rowspan']++;
                $spancol[$col_key]['spancol'] = $col;
                break;
              endif;
              $prev_row--;
            endwhile;
            unset($variables['rows'][$row_key]['cells'][$col_key]);
          endif;
        elseif($col_key == $spancol[$col_key]['spancol']):
          $spancol[$col_key]['rowspan'] = 2;
          $spancol[$col_key]['spancol'] = FALSE;
        endif;
        // remove lost cells #remove#
        preg_match("/(?:#remove#)/", $cell['content'], $match);
        if(!empty($match)):
          unset($variables['rows'][$row_key]['cells'][$col_key]);
        endif;
      endforeach;
      $previous_row = $row_key;
    endforeach;
}
?>
leymannx’s picture

I've created an installable D8 patch for a sub-module based on the snippets provided in this thread. TableField Cellspan: https://www.drupal.org/project/tablefield/issues/2985110

I'd like to thank everybody for their contributions which helped to create this patch.

lolandese’s picture

Status: Active » Fixed

See #2985110: Colspan/Rowspan sub-module "TableField Cellspan".

The 7.x issue should proceed over there under the status "Patch (to be ported)".

lolandese’s picture

Version: 7.x-3.x-dev » 8.x-2.x-dev

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.