Add tableselect form element

Heine - April 5, 2008 - 10:09
Project:Drupal
Version:7.x-dev
Component:forms system
Category:feature request
Priority:normal
Assigned:Unassigned
Status:patch (reviewed & tested by the community)
Description

The amount of code required to build tables on admin/user/user or admin/content/node is a waste IMO as we could simply create a reusable form element.

Attached patch implements such a form element. It provides:
- Support for tablesort_sql
- Checkboxes or radiobuttons (#multiple => TRUE vs FALSE)
- JS multi-selection via tableselect.js (when #multiple => TRUE and #advanced_select => TRUE)

Most important properties are #header and #options. Structure:

$header = array(
  'col1' => 'Title of field 1',
  'col2' => 'Title of field 2',
);

$options['some_unique_id'] = array(
  'col1' => 'Value of field 1',
  'col2' => 'Value of field 2',
);

A simple example:

<?php
  $header
= array(
   
'title' => t('Title'),
   
'author' => t('Author'),
  );

 
$query = "SELECT n.nid, n.title, u.name FROM {node} n INNER JOIN {users} u ON n.uid = u.uid";
 
$result = pager_query(db_rewrite_sql($query));

  while(
$partial_node = db_fetch_object($result)) {
   
$options[$partial_node->nid] = array(
     
'title' => check_plain($partial_node->title),
     
'author' => check_plain($partial_node->name),
    );
  }
 
$form['nodes'] = array(
   
'#type' => 'tableselect',
   
'#header' => $header,
   
'#options' => $options,
  );
?>

If this patch is accepted, we can convert existing tables to use the element.

AttachmentSize
tselect.patch3.43 KB

#1

Heine - April 5, 2008 - 10:14

Here's a module to test the patch.

AttachmentSize
example.tar_.gz1 KB

#2

moshe weitzman - April 5, 2008 - 17:34

will be very handy for many other modules too. devel's variable editor, views_build_operations module.

instead of a sample module why not convert a form in core?

#3

Wim Leers - April 5, 2008 - 17:57
Status:patch (code needs review)» patch (code needs work)

+1 for the idea/goal.

Initial review: why not use the normal Drupal formatting for FAPI elements here? I.e. instead of
$element[$key] = array('#type' => 'checkbox', '#processed' => TRUE, '#title' => '', '#return_value' => $key, '#default_value' => isset($value[$key]), '#attributes' => $element['#attributes']);

This would be better:

$element[$key] = array(
  '#type' => 'checkbox',
  '#processed' => TRUE,
  '#title' => '',
  '#return_value' => $key,
  '#default_value' => isset($value[$key]),
  '#attributes' => $element['#attributes'],
);

That's much more readable.

#4

Heine - April 5, 2008 - 20:22
Status:patch (code needs work)» patch (code needs review)

Thanks.

Attached patch has the code style change asked for by Wim Leers and one converted core form (admin/user/user).

AttachmentSize
tableselect.patch9.21 KB

#5

moshe weitzman - April 6, 2008 - 00:27
Status:patch (code needs review)» patch (reviewed & tested by the community)

I tested and it works as designed. Gets rid of a nasty theme function as well.

#6

Heine - April 6, 2008 - 05:28
Status:patch (reviewed & tested by the community)» patch (code needs work)

I've had a discussion with chx on the use of the element renderer (and rendering the checkboxes twice). Let's polish a bit.

#7

Heine - April 6, 2008 - 07:51
Status:patch (code needs work)» patch (code needs review)

After a discussion with chx, an updated patch. drupal_render has been modified to store rendered content in the element so parent items can reuse it.

Still using #options, to get element validation. #value is in the format expected, and the validator only looks at the keys in #options, not the values.

chx feels matching keys in #header and #options[foo] are problem and should perhaps be something like:

$table['roles']['rows'][$account->uid] = theme('item_list', $users_roles);
$table['roles']['header'] = t('Roles') ;

but then #header needs to be useable in tablesort_sql.

Right now, #header is not directly useable in tablesort_sql when there's no sort specified, because tablesort_sql relies on a 0 key.

AttachmentSize
tselect.patch9.95 KB

#8

chx - April 6, 2008 - 09:45

I wonder whether tablesort_sql could be also fixed... using current (the array pointer is reset afer assigment)...

#9

Heine - April 6, 2008 - 10:04

Here's a patch with the additional tablesort fixed. It uses 0 when set as the default sort, otherwise current. Added 'sql' => '' to remove another notice.

AttachmentSize
tselect.patch10.73 KB

#10

chx - April 6, 2008 - 16:46

$first = isset($header[0]) ? $header[0] : current($header); is hardly needed. If you have an unindexed list of header elements, then current() --for a reset array-- will return $header[0].

#11

moshe weitzman - April 7, 2008 - 01:06

I tested and this is good to go. If you are going in one more time as chx suggests, I propose adding a little Doxygen to theme_tableselect(). I will RTBC after those minor improvements.

#12

Heine - April 8, 2008 - 03:38

Thanks for the reviews & help. I initially kept [0] as default for explicitly set keys. But this is indeed nonsense; people can set 'sort'.

AttachmentSize
tselect.patch10.98 KB

#13

moshe weitzman - April 8, 2008 - 04:04
Status:patch (code needs review)» patch (reviewed & tested by the community)

thanks for the new doxygen.

#14

chx - April 8, 2008 - 06:46

I agree with the RTBC. This is one nice patch.

#15

catch - April 8, 2008 - 12:12

One space missing in doxygen for theme_tableselect. I can't in good conscience mark it needs work, so here's a patch with the extra space.

Pretty please don't credit on commit.

Also, very nice indeed! I saw those theme functions in user module the other day and it seemed like overkill. Now it won't be :)

AttachmentSize
tselect_2.patch10.98 KB

#16

Heine - June 5, 2008 - 09:34

What does this patch need in order to get in or be rejected?

Benefits:

  • The change to drupal_render allows composit element types to render their children without doing double work.
  • Much easier creation of these kinds of tables (eg admin/content/node, admin/content/comments, tracker even perhaps)

#17

moshe weitzman - July 10, 2008 - 20:46

Did a quick check and this still applies and works. Can we please get some feedback here? Thanks.

#18

Dries - July 11, 2008 - 02:17
Status:patch (reviewed & tested by the community)» patch (code needs work)

I started by reading the PHPdoc of this patch. Based on the PHPdoc, I could not figure out how to use this function or what its purpose is.

Would also be nice if we had tests for this new function.

#19

moshe weitzman - July 11, 2008 - 02:33

Thanks for the review.

I think decided a long time to document fapi properties outside of the code. We settled on http://api.drupal.org/api/file/developer/topics/forms_api.html/5 and http://api.drupal.org/api/file/developer/topics/forms_api_reference.html. We can change our minds about that, but at present virtually no fapi elements are documented in code.

I don't see any tests for form.inc at all. Am I missing them? We can start with this one but I'd love some discussion about how we want to test FAPI elements.

#20

moshe weitzman - July 11, 2008 - 09:37

Heine has written excellent documentation at http://cvs.drupal.org/viewvc.py/drupal/contributions/modules/elements/RE.... Now, where tp put this in Drupal?

#21

moshe weitzman - July 15, 2008 - 21:08
Status:patch (code needs work)» patch (reviewed & tested by the community)

I have shown above that we have documentation waiting for api.drupal.org regarding this new form element. I looked but simply cannot find a suitable place for it in core.

We have zero form testing in core and I don't think this patch is the right place to initiate such an effort. So, I humbly set this to RTBC. I will personally update api.drupal.org if this goes in.

#22

catch - July 16, 2008 - 09:05

It seems like the easiest way to add a test for this would be the admin/user/user pages since there's an implementation of an actual form in the patch - there's an existing issue here (claimed by a new tester) for writing those tests #276583: TestingParty08: Tests for admin/user/user filters.

#23

moshe weitzman - July 16, 2008 - 14:08

Excellent proposal, Catch. I hope that the committers don't think that a test of that page is a prerequisite for this patch but we shall see.

 
 

Drupal is a registered trademark of Dries Buytaert.