I have created a form with an embedded table for inputs, where one of the table columns contains a select field; the rest are textfields. The textfields all work fine, but the rendering of cells with the select field fails to create any <input>
tag in its rendering. So naturally the form fails to act on any changes the user makes to this field.
In the following snippet, I have omitted a lot of data pre-processing. To give some context, I have created a $result
array that has 4 or 5 rows of node data. Some of that get extracted to other variables to form the defaults for each form item.
This is the form.
function mymodule_walker_registration_form($form, &$form_state) {
$form['table'] = array(
'#theme' => 'mymodule_form_table',
'#header' => array(
array('data' => t('Walker\'s name'), 'class' => array('col-c3')),
array('data' => t('Date of birth'), 'class' => array('col-c4')),
array('data' => t('Age range'), 'class' => array('col-c5')),
),
'rows' => array(
'#tree' => TRUE,
),
);
foreach ($result as $walker_nid) {
// a bit of data processing omitted: exctract various variables for use as defaults
$form['table']['rows'][$row_number] = array(
// Text field for the walker name
'c3' => array(
'#type' => 'textfield',
'#default_value' => $walker_name,
'#size' => 32,
'#maxlength' => 32,
'#required' => TRUE,
),
// Text field for the walker date of birth
'c4' => array(
'#type' => 'date_text',
'#default_value' => $walker_dob,
'#date_format' => 'j/n/Y',
'#required' => FALSE,
),
// Select field for the walker age type ('scout', 'explorer', 'adult')
'c5' => array(
'#type' => 'select',
'#title' => 'Walker age range',
'#options' => drupal_map_assoc($age_ranges),
'#default_value' => $walker_age,
'#required' => TRUE,
),
);
}
// The submit buttons
// The 'Register team' button
$form['e80progress_register'] = array(
'#type' => 'submit',
'#title' => t('Register team'),
'#value' => t('Register walkers (get walker numbers)'),
'#submit' => array('e80progress_team_registration_register'),
);
// The 'cancel' button
$form['e80progress_cancel'] = array(
'#type' => 'submit',
'#value' => t('Cancel'),
'#attributes' => array('onclick' => 'if(!confirm("You will lose any changes. Are you sure you want to cancel?")){return false;}'),
'#submit' => array('e80progress_team_registration_cancel'),
'#limit_validation_errors' => array(),
);
return $form;
}
The hook_theme()
implementation is nothing special.
function mymodule_theme() {
return array(
'mymodule_form_table' => array(
// The renderable element is the form.
'render element' => 'form',
),
);
}
The issue comes in processing the table. I know that the select element gets this far.
function theme_mymodule_form_table(&$variables) {
// Get the useful values.
$form = $variables['form'];
$rows = $form['rows'];
$header = $form['#header'];
// Setup the structure to be rendered and returned.
$content = array(
'header' => $header,
'rows' => array(),
);
// Traverse each row. @see element_chidren().
foreach (element_children($rows) as $row_index) {
$row = array();
// Traverse each column in the row. @see element_children().
foreach (element_children($rows[$row_index]) as $col_index) {
// Render the column form element.
$row[] = array('data' => drupal_render($rows[$row_index][$col_index]), 'class' => array("col-$col_index"));
}
// Add the row to the table.
$content['rows'][] = $row;
}
// Theme the table and return.
return theme('table', $content);
}
The only element that does not render correctly is the select cell. Visually, it is perfect. Functionally, it omits the <input>
tag. This is how that cell renders:
<div class="form-item form-type-select form-item-rows-r1-c5">
<label for="edit-rows-r1-c5">Walker age range
<span class="form-required" title="This field is required."></span>
</label>
<select id="edit-rows-r1-c5" name="rows[r1][c5]" class="form-select required">
<option value="Scout 12 years or older" selected="selected">Scout 12 years or older</option>
<option value="Explorer">Explorer</option>
<option value="Network">Network</option>
<option value="Adult with DBS">Adult with DBS</option>
</select>
</div>
How do I make drupal_render()
or some other function to include the <input>
tag into that cell of the table?
drupal_get_form('walker_registration_form');
? Eg, outside of a table ... If it looks ok, then look to your theme function, if it looks broken, then look to your form function for errors.