5

I use a tableselect to output a list of terms and per row I want a drop down (select):

$header = array(
      'name' => array('data' => t('Name')),
      'weight' => array('data' => t('Weight')),
    );

    $options = array();

    foreach ($terms as $term) {
      $options[$term->tid] = array(
        'name' => array(
          'data' => array(
            '#title' => $term->name,
            '#type' => 'link',
            '#href' => sprintf('/taxonomy/term/%d', $term->tid),
          ),
        ),
        'weight' => array(
          'data' => array(
            '#type' => 'select',
            '#options' => range(1,25),
          ),
        ),
      );
    }

    $form['term_list']['list'] = array(
      '#type' => 'tableselect',
      '#header' => $header,
      '#options' => $options,
    );

Problem is that I don't see the value of the drop down (select) when I debug

function example_block_save($delta = '', $edit = array()) {
  debug($edit, null, true);
}

here is what I get

[term_list] => Array
        (
            [list] => Array
                (
                    [5] => 5
                    [4] => 0
                    [6] => 0
                )

        )

when I check the code I can see that the select has no name, I'm guessing that's why I don't see it in the debug.

  • I'm not sure you can embed arbritrary form elements in cells directly with the #tableselect form element type. Instead, it's used to select from a list, with #options representing a key=>value set of selections (like a select element, where the keys represnet the data value that is passed when your form is submitted). To embed form elements, you probably need to render them seperately by doing something like $element = theme_form_element($element);. That means you'll need to do your own special processing of $_POST, though. see bit.ly/PzilAr and bit.ly/L3qpD9 – cam8001 Jul 9 '12 at 10:24
  • cam8001: The embedded elements are rendered fine visually. However, they do not appear to be rendered completely as they do not appear to have all the attributes commonly seen with form elements. It's an "almost there but not quite" situation. – user7667 Jul 10 '12 at 14:58
0

give default value property to select element e.g select form element returns value if select has been checked

add this attribute

'#default_value'= 1; 

to every select list and your data to select list must be an array with key and value

$element=array(
'#type'=>'select',
'#default_value'=>1,
'#options'=>array(
         0 => t('No'),
         1 => t('Yes'),
    )

);

maybe then you have to render this element array with theme_form_element to your data variable. sorry but i havent enough time to test this solution

  • Please provide a working example using the code in the OP. Thanks :) – user7667 Jul 10 '12 at 14:52
  • i ve updated my answer :) – werqious Jul 10 '12 at 15:47
0

What you're looking for is this:

'weight' => array(
  'data' => array(
    '#type' => 'select',
    '#title' => 'Weight',
    '#options' => drupal_map_assoc(range(1,25)),
    '#title_display' => 'invisible',
    '#attributes' => array(
        'name' => 'term-weight['.$term->tid.']',
    ),
  ),

The #title_display set to invisible makes sure the "Weight" label doesn't appear in every row.

Typically if you're creating a weight select you'd use:

'weight' => array(
    '#type' => 'weight',
    '#title' => 'Weight',
    '#delta' => 100,
    '#default_value' => 0,
)

But for some reason that doesn't work in a tableselect.

Also, be sure to use drupal_map_assoc() if you're going to use a range like that since the option keys will be automatically assigned and they always start with 0.

There is no #name attribute for select fields but you will need to give the select a name by using #attributes. That is the only way you'll get the values to come through your validation and submission handlers.

However, they do not come through to $form_state['values']. Instead you'll have to get them from $form_state['input']. So if you use the name I gave the field in my example you'd loop through $form_state['input']['term-weight'] to get the values. You can add the values to your $form_state['values'] using a form validator like this:

function my_tableselect_form_with_weight_field_validate($form, &$form_state){
  foreach($form_state['input']['term-weight'] as $tid => $weight){
    $form_state['values']['term-weight'][$tid] = $weight;
  }
}

I don't know what the equivalent would be for the block hooks. I found this question when trying to find a solution for adding a table drag to a tableselect and the code I provided works for what I'm trying to do. I'm hoping this will help anyone else who may have a similar issue.

0

Thanks to this post on Hexblot, I think I've found a solution that works, in case anyone else is still out there trying to get this working.

The trick is to add an extra form field to contain your values from the select input.

$form['weight'] = array(
  '#type' => 'value'
);
$form['term_list']['list'] = array(
  '#type' => 'tableselect',
  // etc...
);

Then add your select input to each row.

  'weight' => array(
    'data' => array(
      '#title' => 'Weight',
      '#title_display' => 'invisible',
      '#name' => 'weight['.$tid.']',
      '#type' => 'select',
      '#options' => range(1,25),
    ),
  ),

The important part is the use of the '#name' attribute to create an array of select inputs. Oddly enough it seems to work fine whether I use ['data']['#name'] or ['data']['#attributes']['name']. Basically, you're leveraging PHP's own internal POST data -> array conversion handling instead of relying on Drupal to parse it all for you. Then I guess Drupal picks it up on the other side. Doesn't feel super clean, but it works.

Just in case anyone needs it, I also struggled a bit using default or placeholder values in a select embedded in a tableselect, so I'll also add that if you need that functionality, you need to use '#value' instead of '#default_value'. '#empty_option' also didn't work, so I ended up having to implement it like this:

    'data' => array(
      '#title' => 'My Select',
      '#title_display' => 'invisible',
      '#type' => 'select',
      '#options' => array('' => '- None -') + range(1,25),
      '#value' => $default_value,
      '#empty_value' => '',
      '#name' => 'my-select['.$tid.']',
    ),
-1

I had the similar problem. I tried with the following element added to the array.

'#name' => 'status',

It should be like...

   'weight' => array(
      'data' => array(
        '#name' => 'weight',
        '#type' => 'select',
        '#options' => range(1,25),
      ),
    ),

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.