First, apologies if this ended up in the wrong place; the "forms component" seemed the closest match for submitting a Forms API bug.
I MUST be doing something wrong . . . or this is a bug in the Forms API.
I'm presently running a 5.1 Drupal install. Here's the problem I'm encountering - it's somewhat straight forward:
I try to set default values for a checkboxes field in a multistep form and the default values don't get applied.
This only appears to happen when:
1) The checkboxes field in NOT in the first form presented (i.e. not switch case 1), AND (I think)
2) The checkboxes field is also introduced in that subsequent case.
Here's a complete sample testform module that exhibits the behavior (apologies for the longish, and, likely ugly, sample - newbie programmer):
function testform_form($form_values=NULL) {
$form['#multistep'] = TRUE;
$form['#redirect'] = FALSE;
if (isset($form_values['step'])) {
$current_step = ++$form_values['step'];
} else {
$current_step = 1;
}
$form['step'] = array(
'#type' => 'hidden',
'#value' => $current_step,
);
switch($current_step) {
case 1:
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#description' => t('test field');
);
$form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
break;
case 2:
$options = array('10' => t('Bobby'), '12' => t('Ralph'), '20' => t('George'));
$defaults['test'][] = '12';
$form['details'] = array (
'#type' => 'fieldset',
'#title' => t('Details'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['details']['admin'] = array (
'#type' => 'checkboxes',
'#title' => t('Only admin can view'),
'#default_value' => $defaults['test'],
'#options' => $options,
);
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#size' => 30,
'#maxlength' => 64,
'#description' => t('Enter the name for this group of settings'),
);
$form['submit'] = array('#type' => 'submit', '#value' => t('Continue'));
break;
}
return $form;
}
function testform_page() {
return drupal_get_form('testform_form');
}
function testform_submit($form_id, $form_values) {
switch($form_values['step']) {
case 1:
break;
case 2:
break;
}
}
function testform_menu() {
global $user;
$items = array();
$items[] = array('path' => 'testform',
'title' => t('Test Form'),
'callback' => t('testform_page'),
'access' => user_access('access content') && ($user->uid > 0),
'type' => MENU_CALLBACK
);
return $items;
}
If I use this same method of setting the default values WITHOUT putting it in a multistep form . . . NO PROBLEM; it sets the values in what I believe is the correct fashion (cue: bang forehead against wall):
function testform_form($form_values=NULL) {
$options = array('10' => t('James'), '12' => t('Bobby'), '20' => t('George'));
$defaults['test'][] = '12';
$form['details'] = array (
'#type' => 'fieldset',
'#title' => t('Details'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['details']['admin'] = array (
'#type' => 'checkboxes',
'#title' => t('Only admin can view'),
'#default_value' => $defaults['test'],
'#options' => $options,
);
$form['submit'] = array('#type' => 'submit', '#value' => t('Continue'));
return $form;
}
function testform_page() {
return drupal_get_form('testform_form');
}
function testform_submit($form_id, $form_values) {
}
function testform_menu() {
global $user;
$items = array();
$items[] = array('path' => 'testform',
'title' => t('Test Form'),
'callback' => t('testform_page'),
'access' => user_access('access content') && ($user->uid > 0),
'type' => MENU_CALLBACK
);
return $items;
}
Somebody please, please, please tell me where I've gone wrong if this isn't a bug.
Comments
Comment #1
criticny commentedComment #2
criticny commentedComment #3
criticny commentedI've removed some of these comments, as they were slightly misleading and suggested a non-solution.
If you're desperate (as I was/am), there's a completely ugly HACK that'll do the job of a "checkboxes" field until this is resolved - see the following comment.
Hope that saves someone out there the pain I had with this!
Comment #4
criticny commentedNow I'm just plain embarrassed . . . can I not delete or edit my follow-ups!? Argh
the hack won't work as a function. but it will if you just drop it into your code so . . . tired of this now.
Comment #5
TBarregren commentedThank you! I used your workaround in revision 1.10 of the RelatedContent module. Take a look at
_relatedcontent_form_add_table(). It works like a charm.It is worth pointing out for everyone else who is strugling with this very annoying bug, that it is the use of
#attributesinstead of the more proper#default_valuethat is the trick/hack. Very clever.Comment #6
ashsc commentedI'm not sure if this relates to what you're doing but I found the following code in the api concerning checkboxes. It is an example of how they're implemented and shows how defaults are set. This is the same for D4.7->D6 as far as I can tell. I'm using D6:
It would suggest that your code should look like this:
I'm using this code and it seems to work for me. I found it here. I hope this helps somebody! I was looking for this info too. I'm sorry if I'm off topic.
Comment #7
MiMe commentedThis has not been fixed with Drupal 5.12, it's still a BUG and it's been bugging me for a day now... so thanks to criticnc that coed works like a charm!
I tested examples from the forms_api_reference for select (#multiple => TRUE), radios and checkboxes... none of them worked in a multistep form, this is a VERY annoying bug indeed.
Comment #8
wim leersThis is a bug in D6 FAPI as well, see http://drupal.org/node/311651.
Comment #9
sutharsan commentedBased on critincy's code I made a function out of it. It is used in a multistep form where the user can go forward _and_ backwards through the forms. Where going backwards, the checkbox default is set for a second time.
Usage example:
But, instead of making workarounds, this should be solved in core.
Comment #10
seanrSutharsan's right, of course. This bug has been around a while and strikes me as a fairly big one. Is anyone actively wortking on patching core? I unfortunately have no idea where to start.
Here's my D6 workaround for a multistep node form:
It's really not recursive, but it works well enough for the standard node forms (I don;t think I've seen too many node forms with nested fieldsets)
Comment #11
dpearcefl commentedIs this still an issue in modern Drupal?
Comment #12
dpearcefl commentedComment #13
stephenrobinson commentedstill having issues in Drupal 7.31