Build tables with Forms API

kkaefer - August 26, 2006 - 19:39
Project:Drupal
Version:7.x-dev
Component:forms system
Category:feature request
Priority:normal
Assigned:kkaefer
Status:patch (code needs work)
Description

Having dealt with some tables in Drupal, I found them quite difficult to construct. That’s why I have written a Forms API implementation of tables.

Now, you can create tables directly in Forms API without the need for theme(‘table’) in custom theme functions.

<?php
$form
= array(
 
'system' => array(
   
'#type' => 'table_table',
   
'#header' => array(
     
0 => NULL,
     
1 => array('data' => 'Name', 'field' => 'name', 'sort' => 'asc'),
    ),
   
0 => array(
     
'status' => array (
       
'#type' => 'checkbox',
       
'#default_value' => '1',
      ),
     
'name' => 'table',
    ),
   
1 => array(
     
'status' => array (
       
'#type' => 'table_cell',
       
'status' => array (
         
'#type' => 'checkbox',
         
'#default_value' => '1',
        ),
      ),
     
'name' => 'taxonomy',
    ),
  ),
);
?>

In #type => 'table_table', you can specify the header of the table in the #header attribute. It takes a regular header structure as returned by tablesort_init(). Table sorting is fully supported (with pager_query and so on). You can now populate the rest of your #type => 'table_table with the rows. These rows (0, 1 in the example above) contain the cells (‘status’ and ‘name’ in the example).

There are three possibilities: If the cell is a string, it is expanded to array('#value' => $cell) and put into a table cell automatically. If it is an array (thus an arbitrary form element such as checkbox, radio or textfield), it is wrapped by a table cell. If it is a table cell, nothing specifically happens.

This behavior implies that you can place arbitrary form elements inside a table cell without writing specific theme functions that handle these. They are automatically generated by Forms API.

Attached is a module that implements the table. I’d like some people to check my code and if this approach makes sense. The module does also include a sample table at admin/settings/table that maps the SQL table ‘system’ to a table that can be browsed.

AttachmentSize
table.module4.79 KB

#1

kkaefer - August 26, 2006 - 19:43

I forgot to say that I will go on and convert this module to a patch for Drupal core that replaces theme('table') and converts all tables to this model removing the need for specific theme functions.

#2

kkaefer - August 26, 2006 - 19:48

Now minus the var_export.

AttachmentSize
table_0.module4.76 KB

#3

dman - August 26, 2006 - 20:56

I agree with the theory, and tried it earlier this year
The result was a nice big demo and something very similar to what you did.
(I called the elements formtable, tr and td. It's not as tied to the tablebuilder as yours, it chooses Form API - like syntax instead ... but hence doesn't support tablesort.)
My implimentation (80% docs) is attached.
I'm using it in several places already.

Everything I glanced at in your code made sense (note glanced, it's past my bedtime), but the expand function looks a bit inelegant.

maybe I'll sleep on it.

AttachmentSize
formtable.module_0.txt8.1 KB

#4

nevets - August 26, 2006 - 21:34

It sounds like you propose to remove them theme_table() function to which I say ouch. Not everything the uses that function is a form.

#5

pwolanin - August 26, 2006 - 22:06

I like the general idea a lot, but why not just extend FAPI so that drupal_render() knows to render the elements in each row and then call theme('table')?

#6

kkaefer - August 27, 2006 - 09:15

I had a conversation with chx yesterday evening and he told me that this data model (rows instead of columns) could result in quite some difficulties using #type => checkboxes.

@nevets you can build your tables using this model even without drupal_get_form(). Just construct the array in the same way and use drupal_render() to get the HTML representation.

#7

nedjo - August 27, 2006 - 20:19

I like the idea and the implementation, but I doubt that it warrants a new core module. Maybe a .inc file? The table_elements() return value could then be added instead to system_elements(). We've already got tablesort.inc. Maybe that should be changed to table.inc, and these functions included there.

#8

kkaefer - August 28, 2006 - 07:29

Oh, I never intended it to be a module. That is just for development/reviewing purposes becasue it makes it easier to show what it does without the need to reroll patches all the time (see #2). If this is considered for inclusion in core, I will happily provide a patch. Note that this definitely won't make it into 4.8/5.0.

#9

chx - August 28, 2006 - 18:34

Minor correction. The pain is with radio buttons and no matter what you do, if you use #type radio instead of #type radios you need advanced mojo.

'table_row' => array(), this is unnecessary. hook_elements is for defaults, if you have no defaults, omit it, noone checks whether a specific type is defined in any hook_elements.

#10

nedjo - August 30, 2006 - 00:37

hook_elements is for defaults, if you have no defaults, omit it

It's true that defaults is our only current core use. But e.g. in formbulder.module we need a way to answer the question "What are all the defined form element types (so we can offer a UI for building them)?". It's best IMO if we return all eliment types, whether or not they have defaults.

And we seem to do this already in system_elements:

<?php
  $type
['item'] = array();
?>

#11

drumm - September 1, 2006 - 06:22
Status:patch (code needs review)» patch (code needs work)

THis should not be a separate module.

I wrote one of these awhile ago http://cvs.drupal.org/viewcvs/drupal/contributions/sandbox/drumm/extra_e...

#12

dman - September 1, 2006 - 10:42

I like Drumms version.

#13

dmitrig01 - February 17, 2007 - 20:47
Version:x.y.z» 6.x-dev

+1

#14

gordon - April 27, 2007 - 07:21

I have started developing a much more enhanced version which when finished will integrate into the formapi.

see http://cvs.drupal.org/viewcvs/drupal/contributions/sandbox/gordon/table_...

#15

Pancho - January 9, 2008 - 12:08
Version:6.x-dev» 7.x-dev

Feature freeze requires this to be sent to D7.

#16

pwolanin - January 9, 2008 - 17:30

maybe you could get some inspiration/code from: http://drupal.org/node/103171

#17

moshe weitzman - January 22, 2008 - 19:15

subscribe. we'll *have* to get this in for D7

#18

moshe weitzman - April 18, 2008 - 19:07

I did some quick testing of drumm's form element and still works in 5 (it was built for 4.7). I only had to change form_render => druapl_render(). See his code at http://cvs.drupal.org/viewvc.py/drupal/contributions/sandbox/drumm/extra.... I think this is a nice, small implementation.

#19

Susurrus - April 18, 2008 - 22:05

subscribing

#20

BioALIEN - April 21, 2008 - 03:32

Lots of different implementations by various developers. Can we revive this and get a consensus on the best patch to take forward?

#21

douggreen - August 20, 2008 - 23:48

See #297893: #theme Form elements into tables ... I don't know if my patch is a duplicate of this, or something kinda different.

 
 

Drupal is a registered trademark of Dries Buytaert.