#default_value for select form elements does not work.

jrigby - July 16, 2008 - 23:19

Hello,

I'm trying to set the default value for a select form element created programatically but whatever I try fails. What is the proper method for setting the default selected option for a select when using drupal_render()?

Here's a simplified version of the code (I want 'two' selected by default):

<?php
$form
['my_select'] = array(
 
'#type' => 'select',
 
'#default_value' => 1,
 
'#options' => array(
   
0 => t('one'),
   
1 => t('two'),
   
2 => t('three'),
   
3 => t('four'),
  )
);

drupal_render($form['my_select']);
?>

I've also tried the following for #default_value:

  • array(1)
  • array(1=>'two')
  • array(1=>t('two'))
  • two
  • array(two)

Looking further I found that the function form_select_options() in the forms API completely ignores #default_value (although it is passed) when adding select="select" to the option. It does however read in #value, and if I replace #default_value with #value it renders correctly, however the formsapi documentation specifically says not to use this for what I'm trying to do - http://api.drupal.org/api/file/developer/topics/forms_api_reference.html... .

Here's the function that renders the options
From includes/form.inc

<?php
function form_select_options($element, $choices = NULL) {
  if (!isset(
$choices)) {
   
$choices = $element['#options'];
  }
 
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
  // isset() fails in this situation.
 
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
 
$value_is_array = is_array($element['#value']);
 
$options = '';
  foreach (
$choices as $key => $choice) {
    if (
is_array($choice)) {
     
$options .= '<optgroup label="'. $key .'">';
     
$options .= form_select_options($element, $choice);
     
$options .= '</optgroup>';
    }
    elseif (
is_object($choice)) {
     
$options .= form_select_options($element, $choice->option);
    }
    else {
     
$key = (string)$key;
      if (
$value_valid && (!$value_is_array && (string)$element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) {
       
$selected = ' selected="selected"';
      }
      else {
       
$selected = '';
      }
     
$options .= '<option value="'. check_plain($key) .'"'. $selected .'>'. check_plain($choice) .'</option>';
    }
  }
  return
$options;
}
?>

Thanks,
Jeff

Jeff, your simplified

yuriy@yuba - July 16, 2008 - 23:42

Jeff, your simplified version of the code looks correct and should be working properly. Instead of refreshing the page, try just clicking the url and pressing ENTER. (ie. reload without the reload).

Browsers save some form information and display it again on page reload (F5). It could very well be that your #default_value was previously not working, the browser saved the value at key 0, you fixed the problem and refreshed using F5, the browser remembers your old choice and loads that up. I've fallen for this numerous times myself.
---
Yuriy Babenko
www.yubastudios.com
My Drupal tutorials: http://yubastudios.com/blog/tag/tutorials

Cache is turned off

jrigby - July 17, 2008 - 00:05

Thanks for the suggestion Yuriy.

I've actually turned off the cache with the same results and if I look at the source code none of the options have the selected attribute.

Jeff

Maybe it has to do with how

yuriy@yuba - July 17, 2008 - 00:21

Maybe it has to do with how you're rendering the form...

Try this:

<?php
function my_form()
{
$form = array();
$form['my_select'] = array(
 
'#title' => t('test select'),
 
'#type' => 'select',
 
'#default_value' => 1,
 
'#options' => array(
   
0 => t('one'),
   
1 => t('two'),
   
2 => t('three'),
   
3 => t('four'),
  )
);
return
$form;
}
?>

and then somewhere (let's say page.tpl.php for simplicity's sake):

<?php
print drupal_get_form('my_form');
?>

---
Yuriy Babenko
www.yubastudios.com
My Drupal tutorials: http://yubastudios.com/blog/tag/tutorials

drupal_render_form

jrigby - July 17, 2008 - 14:39

I actually can't render the complete form as I am dynamically loading these elements in an existing form. This would cause nested form elements.

Something to check, look at

nevets - July 17, 2008 - 01:02

Something to check, look at the generated HTML. What does the html for the select look like, in particular the option tag for what should be the default item?

re: Something to check, look at

jrigby - July 17, 2008 - 14:40

It does not add the selected attribute.

on the other side ..

najibx - July 27, 2008 - 18:33

How can I used the selected list to be kept selected such as this via Onchange Jump Menu?
http://drupal.org/node/91924

Currently : '#default_value' => '',

No effect if I change default_value to this?

'#default_value' => '$term->name',

This '#default_value' =>

nevets - July 27, 2008 - 18:43

This '#default_value' => '$term->name',<.code> should be <code>'#default_value' => $term->name, (No single quotes around $term->name).

done that. :-(

najibx - July 28, 2008 - 22:29

Thanks, but it's still no luck. nevets, I have seen some of your posts in other thread, I see u are very good at Form API !

Does the onChange, might caused this? Possibly onchange does not recognise default_value ? I read somewhere regarding

'#attributes' => array(
'onChange' => "self.location.href=document.getElementById('$formname').options[document.getElementById('$formname').selectedIndex].value"),
);

I did clear cache, run update, with no succes either.

How about form_select_options() ? Would this be helpful?

Greatly thanks ~

Looking at the code again

nevets - July 28, 2008 - 22:36

Looking at the code again you want $term->tid (the value returned, not what is shown), But I wonder if $term->tid even has a value, once you leave the while loop $term is not even set.

The actual value of

najibx - July 29, 2008 - 00:28

The actual value of pulldownlist is as below.

<option value="/management-news/101">Vol. MN08-05 2008 May 21</option>

$term->tid does have a value, but the actual value I am looking for is "management-news/101" which is $term->name?

    while ($term = db_fetch_object($vocabulary)) {
     $options[url("management-news/$term->tid")] = $term->name;
    }

I also tried :

'#default_value' => 'management-news/$term->tid',
'#default_value' => management-news/$term->tid,

Try double quotes around the

nevets - July 29, 2008 - 01:57

Try double quotes around the value (instead of single quotes). And I need to stop reading so fast, complete value would be url("management-news/$term->tid") (in general the index to $options)

still

najibx - July 29, 2008 - 06:47

Not so sure what you mean there ..
but i tried

'#default_value' => url("management-news/$term->tid"),
'#default_value' => "management-news/$term->tid",

In addition to this, I got another problem. When one of the nodes is selected, the respective volume number (in the pulldownlist) must be selected too. Is there other way to work around this ... How about form_select_options() ?

Ok, here is a complete

nevets - July 29, 2008 - 14:53

Ok, here is a complete working example (It uses the last term found as the default)

<?php
$output
= drupal_get_form('Company_dropdown_form', $form);
return
$output;

function
Company_dropdown_form() {
   
$vid=1;
   
$formname="Company";
 
   
$vocabulary = db_query("SELECT td.name, td.tid FROM {term_data} td WHERE td.vid=%d ORDER BY td.name", $vid);
   
// Initialise the country array
   
$options[] = t('List by ' . $formname);
   
//Populate array with url / name
   
while ($term = db_fetch_object($vocabulary)) {
     
$options[url("taxonomy/term/$term->tid")] = $term->name;
     
$last = url("taxonomy/term/$term->tid");
    }
   
//Build dropdown select
    //If we try to build OnChange directly it gets mangled, so put in array to confuse the forms api
   
$form['category'] = array(
     
'#type' => 'select',
     
'#name' => $formname,
     
'#id' => $formname,
     
'#title' => '',
     
'#default_value' => $last,
     
'#options' => $options,
     
'#description' => '',
     
'#multiple' => $multiple = FALSE,
     
'#required' => $required = FALSE,
     
'#attributes' => array('onChange' => "top.location.href=document.getElementById('$formname').options[document.getElementById('$formname').selectedIndex].value"),
    );
        return
$form;
}
?>

 
 

Drupal is a registered trademark of Dries Buytaert.