0

I got a new content type in my own module for Drupal 6. I want the user to create lists with some entries. For this, I tried to build a draggable table with an AHAH button to add a new row to this table.

In hook_form(), I add some items with the following code.

$form['listsWrapper'] = array(
 '#weight' => 5,
 '#tree' => true,
 '#prefix' => '<div id="lists-wrapper">',
 '#suffix' => '</div>',
);

$form['listsWrapper']['tableItem'] = array(
 '#type' => 'item',
 '#value' => '',
);

$entries = array();
$entries[] = array( 'name' => 'TestName #1' );
$entries[] = array( 'name' => 'TestName #2' );
$entries[] = array( 'name' => 'TestName #3' );
$entries[] = array( 'name' => 'TestName #4' );

foreach ($entries as $key => $value) {
  $form['listsWrapper']['lists'][] = array(
   'entry' => array(
     '#type' => 'textfield', 
     '#default_value' => $value['name'],
     '#maxlength' => 255,
    ),
    'weight' => array(
     '#type' => 'weight',
     // '#default_value' => $key,
     '#attributes' => array('class' => 'weight-group'),
    ),
    'parent' => array(
     '#type' => 'textfield',
     '#attributes' => array('class' => 'parent'),
     '#size' => 10
    ),
    'source' => array(
     '#type' => 'textfield',
     '#default_value' => $key,
     '#attributes' => array('class' => 'source'),
     '#size' => 10
    ),
  );
}

# ahah callback button
$form['listsWrapper']['more'] = array(
 '#type' => 'submit', 
 '#value' => t('Eine weitere Liste / einen weiteren Listeneintrag hinzufügen'), 
 '#weight' => 1, 
 '#submit' => array(), 
 '#ahah' => array(
  'path' => ahah_helper_path(array('listsWrapper')), 
  'wrapper' => 'lists-wrapper', 
  'method' => 'replace', 
 ),
);

In the theme function for this form, I add a table drag behavior to these elements.

function theme_cm_node_form($form) {
  $output = '';

  if(isset($form['listsWrapper'])) {
    drupal_add_tabledrag('draggable-lists-table', 'match', 'parent', 'parent', 'parent', 'source', TRUE, 1);
    drupal_add_tabledrag('draggable-lists-table', 'order', 'sibling', 'weight-group', NULL, NULL, TRUE);

    $header = array(t('Listeneintrag'), t('Gewichtung'));
    $rows = array();
    $lists = array();
    $entries = array();

    foreach (element_children($form['listsWrapper']['lists']) as $key) {
      $element = &$form['listsWrapper']['lists'][$key];

      if ($element['parent']['#value'] == '') {
        //parent
        $i = 0;
        while(isset($lists[$element['weight']['#value']+$i])) $i++;
        $pos = $element['weight']['#value']+$i;

        $lists[$pos] = $key;

      }
      else {
        //entry
        $i = 0;
        while (isset($entries[ $element['parent']['#value'] ][ $element['weight']['#value']+$i ])) {
          $i++;
        }

        $pos = $element['weight']['#value']+$i;
        $entries[ $element['parent']['#value'] ][$pos] = $key;
      }
    }

    ksort($lists);

    foreach ($lists as $list) {
      $element = &$form['listsWrapper']['lists'][$list];
      $row = array();

      $row[] = drupal_render($element['entry']);
      $row[] = drupal_render($element['weight']) . drupal_render($element['parent']) . drupal_render($element['source']);
      $rows[] = array('data' => $row, 'class' => 'draggable');

      ksort($entries[$list]);
      foreach ($entries[$list] as $entry) {
        $elementEntry = &$form['listsWrapper']['lists'][$entry];
        $row = array();

        $row[] = theme('indentation', 1) . drupal_render($elementEntry['entry']);
        $row[] = drupal_render($elementEntry['weight']) . drupal_render($elementEntry['parent']) . drupal_render($elementEntry['source']);
        $rows[] = array('data' => $row, 'class' => 'draggable');
      }
    }    

    if(!count($rows)) {
      $rows[] = array(array('data' => t('Derzeit sind noch keine Listeneinträge erstellt.'), 'colspan' => 2));
    }

    $form['listsWrapper']['tableItem']['#value'] = theme('table', $header, $rows, array('id' => 'draggable-lists-table'));
  }

  $output .= drupal_render($form);

  return $output;
}

Now I got something like this.

my draggable table

I can rearrange the rows and indent them (so they become a entry instead of a new list). My problem is that the theme function isn't called after my AHAH callback, so my form looks like this.

my table after ahah callback

How can I invoke the theme function after my ahah callback? Do I have to invoke the JavaScript functions which will hide the weight field and so on again?

  • All I know is that in Drupal 7 it always happened to me automagically. And given that 6 will soon reach it's end of support, isn't it time to upgrade? Just asking. – Mołot Sep 2 '13 at 7:07
  • Yes of course, I'd love to work with drupal 7. But my company is using D6, so this module have to work there. – JaGo Sep 2 '13 at 7:14
  • I was sure this was backported. Sad to see it isn't. Unless you are not using 6.28 - it wasn't there in 6.18 as far as I remember. Could you show how does your ahah function look like? Can't you re-apply theming function in it and return themed part? – Mołot Sep 2 '13 at 7:20
  • I'm using Drupal 6.28 For my ahah functions I use the ahah_helper module to do the ahah callbacks. Maybe that's the problem? – JaGo Sep 2 '13 at 8:05
1

I bypassed my problem by using jQuery Nestable. I got a hidden form element and on every change in my Nestable list I put a json string in the hidden field. Much easier than using drupal tabledrag and ahah (also looks a bit better in the user front end). Here is what i got now:

jQuery Nestable list

Works fine for me.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.