5

I am trying to implement a form that is themed with drupal table drag using subgroups. My form consists of a list of 'employees' that need to be assigned to different 'departments'. The order of the employees does not matter once they are inside a department.

The admin/structure/block table is similar to what I am looking for but with just the select box for region and no weights.

I've looked through the documentation here: http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_add_tabledrag/7 and I've also studied the admin/structure/block table code but after several hours of trying different combinations - I am stuck!

The block module uses custom JS and a template tpl file for outputting the table. I think this doesn't take full advantage of Drupal. Therefore, this solution should make use of theme_table and #ajax (for the region select fields).

2
  • You say you're looking for the the admin/structure/block table with only region and no weights -- without weights how would this be draggable? You'd just be picking an option with selects. Commented Feb 1, 2012 at 15:00
  • @CharlieS Would this not be possible? A table with draggable rows, allowing items to be separated into regions? If it is not theoretically possible, then I don't mind having weights too - I would just ignore them on the form submit.
    – drupaljoe
    Commented Feb 2, 2012 at 0:38

2 Answers 2

1

If you want ajaxed example perhaps you can study the Display Suite UI.

In my opinion the easiest way to do this if you need similar functionality is just to use the block module tpl's and change the data presented inside it (from block region to your custom module regions)

to remove the weights, I think if you remove :

drupal_add_tabledrag('blocks', 'order', 'sibling', 'block-weight', 'block-weight-' . $region); 

it will remove the ability to drag and sort the weight.

some rough examples for "Drupal compliant" way :

note: this is VERY rough code, you will need to adjust it heavily


function theme_example(&$variables) {
  // build the header
  $header = array(
    '', // this will be hidden when table drag run
    '', // this will be hidden when table drag run
    t('Block Region'),
    t('Region Area'),
  );
  // enabled region
  //$regions = region_area_grab_region('enabled');
  // substitute this to what ever your module provides
  // this should be in $form array
  $regions = array('example_one', 'example_two', 'example_three');

  $region = array('example_block_one', 'example_block_two', 'example_block_three');

  // Add table javascript.
  drupal_add_js('misc/tableheader.js');
  drupal_add_js(drupal_get_path('module', 'block') . '/block.js');

  // take notice of the key that will be related to real options
  // in the select box, this should be in $form array
  $options = array();
  foreach ($regions as $key => $region) {
    $options[$region] = $region;
  }

  // add additional class here
  $attributes = array(
    'class' => array('draggable'),
  );


  // building the table rows
  $rows = array();

  // looping for each regions
  foreach ($regions as $region) {

    // this is the heart of the draggable
    // take good notice for the region-manager (the table id), region-area-weight (group of rows class)
    // and regionarea-weight- $region (unique row class), you will need to add this to the form array
    // element NOT in the table row

    // if you want to emulate the block page table drag, comment out the drupal_add_tabledrag
    drupal_add_tabledrag('region-manager', 'order', 'group', 'regionarea-weight', 'regionarea-weight-' . $region , $hidden = FALSE);
    // build the region row

    // replace this with your form element array eg $variables['form']['whatever']
    $elements = regionarea_build_admin_region_form($region, $form, $form_state);

    $row = array();
    $row[] = '';
    $row[] = drupal_render($elements[$region['name']]['weight']); // replace this to actual form array for the weight
    $row[] = $elements[$region['name']]['name']['#value']; // replace this to actual form array for the value / title
    $row[] = drupal_render($elements[$region['name']]['enabled']); // optional
    $row = array_merge(array('data' => $row), $attributes); // merge the array, add draggable class
    $rows[] = $row; // build the row

    // ----------------------------------------------------------------------------------------------------------------- //
    // Usually up to this point is enough for just normal draggable, only continue if you have a sub child to drag
    // ----------------------------------------------------------------------------------------------------------------- //

    // build the block regions
    // now we looping for the sub child AKA regions as in the block region page
    foreach($region['regions'] as $regionkey => $blockregion) {
      // add two table drag, one for weight the other for 'region'
      drupal_add_tabledrag('region-manager', 'match', 'sibling', 'region-select', 'region-' . $blockregion, NULL, FALSE);
      drupal_add_tabledrag('region-manager', 'order', 'sibling', 'region-weight', 'weight-' . $blockregion);

      // replace this with your form element array eg $variables['form']['whatever']['children']
      $elements = regionarea_build_admin_blockregion_form($blockregion, $regionkey, $options, $form, $form_state);

      // build the current row
      $row = array();
      $row[] = '';
      $row[] = drupal_render($elements[$blockregion]['weight']);
      $row[] = $elements[$blockregion]['name']['#value'];
      $row[] = drupal_render($elements[$blockregion]['regions']);

      $row = array_merge(array('data' => $row), $attributes);
      $rows[] = $row;
    }

  }

  // some options to pass to the theme_table
  $element = array(
    '#empty' => t('There are no region area available'),
    '#attributes' => array(
      'id' => 'region-manager',
    )
  );

  // build the theme
  return theme('table', array('header' => $header, 'rows' => $rows, 'empty' => $element['#empty'], 'attributes' => $element['#attributes'])),
}
3
  • Hmm I don't think the blocks module way of implementing this was the best. In drupal, you shouldn't have to write HTML for your own table in a tpl file. Don't you think?
    – drupaljoe
    Commented Feb 2, 2012 at 7:06
  • well that is the easiest way to do this, if you want really drupal "compliant" way it is more complex
    – Jason
    Commented Feb 4, 2012 at 16:53
  • Hi jason, this seems like a good start. Can you edit the code to make a simple working example? I don't think that code will work in that condition.
    – drupaljoe
    Commented Feb 6, 2012 at 5:05
0

As I can see, Commerce module uses the same functionality and the same realization. File commerce_checkout_admin.js is very similar to draggable part in block.js so you have to use Block way. Maybe you can reuse code in block.js if you will follow the same naming.
You can choose between tpl.php and theme_YOUR_FORM to add tabledrag logic.

3
  • I looked at the js code and the comment at the top reads: This code is almost an exact copy of the code used for the block region This means they didn't try to re-invent the process, they just went with the block module method. There should definitely be a simpler way to implement this.
    – drupaljoe
    Commented Feb 3, 2012 at 0:32
  • So, you are making us to invent something? :)
    – kalabro
    Commented Feb 3, 2012 at 8:01
  • That explains the bounty ;)
    – drupaljoe
    Commented Feb 9, 2012 at 0:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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