blog-banner

Drupal 7 - Creating Editable Table with Form API

  • Drupal
  • EDITABLE
  • FAPI
  • form

Drupal Form API Introduction:

Let's think that we have a custom table to show a list of records. Sometimes you might have to provide editable options for columns. One simpler solution is to have an edit link and open up a form and let the user update the records. But a much more simple user experience will need inline editing of columns. Simply using a theme('table') with textfields might not work since theme_table will run on the render array, your form elements will actually be rendered out to the screen, but the form won't have any knowledge of the values (as they are not technically children of the form).

Implementation:

To overcome this limitation, define a new theme function,

  1. /**
  2.  * Implements hook_theme().
  3.  */
  4. function MODULE_quiz_theme($existing, $type, $theme, $path) {
  5.   return array(
  6.     'MODULE_textfield_table' => array(
  7.       'render element' => 'element'
  8.     ),
  9.   );
  10. }

then write the actual theme function that loops the elements and calls theme('table').

  1. function theme_MYMODULE_textfield_table($vars) {
  2.   $element = $vars['element'];
  3.  
  4.   $rows = array();
  5.   foreach (element_children($element) as $key) {
  6.     $rows[] = array(
  7.       array('data' => 'label'),
  8.       array('data' => $element[$key]['#extra_data']['fied1']),
  9.       array('data' => $element[$key]['#extra_data']['field2']),
  10.       array('data' => render($element[$key]))
  11.     );
  12.   }
  13.  
  14.   $header = array(t('Field Label'), t('Field1'), t('Field2'), t('Edit'));
  15.   return theme('table', array('header' => $header, 'rows' => $rows));
  16. }

Note that the render($element[$key] is the actual textfield that is going to be rendered. Then use the respective theme name inside our form,

  1. $form['things'] = array(
  2.   '#tree' => TRUE,
  3.   '#theme' => 'MYMODULE_textfield_table'
  4. );
  5.  
  6. foreach ($records as $record) {
  7.   $form['things'][] = array(
  8.     '#type' => 'textfield',
  9.     '#default_value' => $record->field3,
  10.     '#extra_data' => array('field1' => $record->field1, 'field1' => $record->field2)
  11.   );

Multiple editable fields:

You could similarly create a tabular form with a multi-field editing option as well. For eg,

  1. $form['things'] = array(
  2.   '#tree' => TRUE,
  3.   '#theme' => 'MYMODULE_textfield_table'
  4. );

let's assume we have rows of data in $rows,

  1. foreach ($rows as $row) {
  2.     $form['things'][$index]['#topic'] = t('Some text');
  3.     $form['things'][$index]['min_marks'] = array(
  4.       '#type' => 'textfield',
  5.       '#default_value' => $row->min_mark,
  6.       '#size' => 10
  7.     );
  8.     $form['things'][$index]['max_marks'] = array(
  9.       '#type' => 'textfield',
  10.       '#default_value' => $row->max_mark,
  11.       '#size' => 10
  12.     );
  13. }
in theme function,
 
  1. foreach (element_children($element) as $key) {
  2.   $rows[] = array(
  3.     array('data' => $element[$key]['#topic']),
  4.     array('data' => $element[$key]['min_marks']),
  5.     array('data' => $element[$key]['max_marks']),
  6.   );
  7. }
You will get rows of data with two input text boxes along with the label 'Some text' in the first column. In the submit handler, you can receive the values from form_state['values'] as usual and do the needed work.
 
References:
https://drupal.stackexchange.com/questions/27264/drupal-form-themed-as-table-not-posting-data-correctly-or-displaying-correctly

 

 

Get awesome tech content in your inbox