Support from Acquia helps fund testing for Drupal Acquia logo

Comments

sun’s picture

Status: Active » Needs review
FileSize
4.14 KB

Thankfully, I already prepared that core patch to be fully self-documenting. :)

sun’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests, +Needs documentation

Committed to HEAD, since I badly need this functionality for another project. Needs tests and documentation (i.e., d.o issue reference).

sun’s picture

Title: Add element #type table » Add element #type table (with tableselect and tabledrag support)
Status: Needs work » Needs review
FileSize
4.22 KB

Attached patch extends the existing #type 'table' with tableselect support by merging in the corresponding #process and #theme code of #type 'tableselect' of Drupal core.

This means that #type 'table' now fully supports

- simple tables
- tables with checkboxes, radios
- tables with "Select all" in the header
- tables with tabledrag

sun’s picture

FileSize
5.36 KB

Forgot the #value_callback.

yched’s picture

Neato.

Note that tabledrag is a bit tricky though - because on failed validation, you want to redisplay the table in the updated order. Field UI is dealing with for its own tables in field_ui_table_pre_render().

sun’s picture

I'm looking at field_ui.admin.inc, but can't find what you're referring to...?

But that's indeed nice, too. Looks like the thing you wrote for Field UI additionally handles

- tabledrag regions
- tabledrag parenting/indentations

and also, I've just realized that this current Edge code doesn't add a weight field to the table when tabledrag is attached... whereas all of this bears the question of how much automation is expected from a #type table in the first place.

So overall, lots of room for improvement + rethinking, but I guess it's wise to make progress in smaller steps. :)

yched’s picture

Yup, field_ui_table_pre_render() builds the tree from parenting and weight values ($row['parent_wrapper']['parent']['#value'], $row['weight']['#value']), and deduces rendering order. This relies on the the hardcoded presence of the 'parent' and 'weight' elements, though.

Handling of region rows is more complex still (relies on PHP callbacks per 'row type' + JS code...), and is probably best left aside.

sun’s picture

FileSize
5.99 KB

Fixed #process function callback of MODULE_process_TYPE() clashes with theme process functions.

tstoeckler’s picture

Just a plug to note that currently http://drupal.org/project/table exists. There's also http://drupal.org/project/elements. Since Table hasn't seen commits since last March, maybe at least contact @kkaefer to mark it obsolete. On the other hand, development could also move there, and Edge would simply introduce a dependency on Table. Either way, efforts should be consolidated.

tstoeckler’s picture

Also, now looking at the code, I saw that 'colspan' is currently not supported for a cell. I'll see if I can roll a patch, and open a new issue, if so.

sun’s picture

Was that a RTBC for #8 ? ;) Still contains some @todos, but we can fix them along the way.

tstoeckler’s picture

Actually by 'the code' I meant HEAD, I just mentioned it here, because this is the AFAIK the (one-and-)only issue for #type table.

sun’s picture

Thanks for clarifying ;)

It's likely that we're going to fix that column attributes/handling problem with a new concept of #wrapper_attributes, which I already wanted to introduce for form elements in core (because it's impossible to set attributes on the wrapping DIV.form-item container).

Dave Reid’s picture

If we're adding new FAPI elements, might you consider adding them to http://drupal.org/project/elements?

tstoeckler’s picture

Here's my Dreditor review. I have yet to try out the code. Will do that, though, in the next couple days.

+++ edge.module	6 Jan 2011 20:38:48 -0000
@@ -13,8 +13,20 @@ function edge_element_info() {
+    '#value_callback' => 'edge_type_table_value',

Not your fault, but:

do {
 $me = ":'(";
} while ('This is nowhere to be found on http://api.drupal.org')
+++ edge.module	6 Jan 2011 20:38:48 -0000
@@ -85,6 +97,139 @@ function edge_css_alter(&$css) {
+ *   The data that will appear in the $element_state['values'] collection

You mean $form_state['values'] right?

+++ edge.module	6 Jan 2011 20:38:48 -0000
@@ -85,6 +97,139 @@ function edge_css_alter(&$css) {
+    // @todo Why?

You can read my mind... :) (The comment below that is explaining that the keys of #default_value are used, not the values).

+++ edge.module	6 Jan 2011 20:38:48 -0000
@@ -85,6 +97,139 @@ function edge_css_alter(&$css) {
+    // Advanced selection behaviour make no sense for radios.

Typo: make -> makes

+++ edge.module	6 Jan 2011 20:38:48 -0000
@@ -85,6 +97,139 @@ function edge_css_alter(&$css) {
+    // Add a "Select all" checkbox column to the header.
+    if ($element['#js_select']) {

Is this naming consistent with somewhere in core? If not, maybe rename #js_select with #select_all?

+++ edge.module	6 Jan 2011 20:38:48 -0000
@@ -85,6 +97,139 @@ function edge_css_alter(&$css) {
+    // Add an empty header column for radio buttons or a "Select all" checkbox
+    // is not desired.

The sentence doesn't make sense. or -> when?

+++ edge.module	6 Jan 2011 20:38:48 -0000
@@ -85,6 +97,139 @@ function edge_css_alter(&$css) {
+        // Determine option label; either an assumed 'title' column, or the
+        // first available column containing a #title or #markup.

Just popped into my mind, might make sense, might not: What about a #title_key attribute, which defaults to 'title'. That would be more (/as ?) flexible and remove the need for the code below (finding an element with #title set).

+++ edge.module	6 Jan 2011 20:38:48 -0000
@@ -85,6 +97,139 @@ function edge_css_alter(&$css) {
+          '#attributes' => $element['#attributes'],

Is there any specific reason we're applying the top-level attributes to each checkbox/radio? There probably is, but I don't see it.

+++ edge.module	6 Jan 2011 20:38:48 -0000
@@ -85,6 +97,139 @@ function edge_css_alter(&$css) {
+        if ($element['#multiple']) {
+          $element[$key]['select']['#default_value'] = isset($value[$key]) ? $key : NULL;
+          $element[$key]['select']['#parents'] = $element_parents;
+        }
+        else {
+          $element[$key]['select']['#default_value'] = ($element['#default_value'] == $key ? $key : NULL);
+          $element[$key]['select']['#parents'] = $element['#parents'];
+          $element[$key]['select']['#id'] = drupal_html_id('edit-' . implode('-', $element_parents));
+        }

It seems as though checkboxes automatically get an HTML ID, but radios don't. If that's so, isn't that a core bug?

Powered by Dreditor.

tstoeckler’s picture

Now I've tried it out. It's pretty awesome, because it's literally a one-line change in your code and you get a whole lot for it.

Two things:
1. The #element_validate callback checks that you have select at least one row. Why is that? I don't see a reason for that. Maybe if #required => TRUE or something...

2. If you don't key your table-row-elements with proper string-names, but just use an indexed array, the first value will be 0 (integer). So that means if the row is checked the value will be '0' (string) and if unchecked the value will be 0 (integer) (like all unchecked rows), which both cast as false to boolean. I don't know if we should do anything about that, but I wanted to mention it, because it will probably confuse people down the road.

tstoeckler’s picture

For reference, the last thing mentioned in #15 is: #453400: "-wrapper" HTML ID not output for #type checkboxes/radios
(Might be good to add a @todo or something in the code?)

tstoeckler’s picture

Ehh, actually that's a Drupal 6 issue. #17 is bogus.

Lars Toomre’s picture

I have started working on two custom forms (in D6 for now) that I hope to contribute back to the Drupal community. The first allows selective pruning of the dblog table on possible combinations of time and count values. The second does the same for the aggregator tables.

@sun your code here and that of @yched in the field_ui module are great examples of integrating sortable forms into themeable tables with possible js support. Using these two examples (and possibly others), does it make sense to make an effort to add a new #table element to the FAPI for Drupal 8? If so, I am interested in contributing to the effort as this is an element I believe many contributor modules could well use.

yched’s picture

FWIW : considerations about 'empty cells' in #1248940-3: "Manage fields" screens : broken table layout

sun’s picture

In #1260860: Rework language list admin user interface I learned that we also need to do something about #header.

I.e., it's nice that you can position an injected/altered-in column like this:

  $form['table'][$row]['injected-column']['#weight'] = 5;

but to do the same for #header...

  array_splice($form['languages']['#header'], -1, 0, t('Interface translation'));
sun’s picture

FileSize
7.12 KB

Attached patch is the latest code, also incorporating all comments on this issue.

And FWIW, I just simply committed that for now.

Status: Needs review » Needs work
Issue tags: -Needs tests, -Needs documentation

The last submitted patch, edge.tableselect.23.patch, failed testing.

sun’s picture

Issue summary: View changes

Updated issue summary.

sun’s picture

Issue summary: View changes

Updated issue summary.