6

I am trying to add a form that forces you to select an option from a dropdown. The documentation says:

If #required is TRUE and there is no #default_value, an empty option is added to the select control to force the user to make an active choice.

http://api.drupal.org/api/drupal/developer%21topics%21forms_api_reference.html/7#empty_value

OK that sounds great. That is what I want. So I have the following code to add the select list to my form.

$form['test'] = array(
    '#type' => 'select',
    '#options' => array (
      1 => 'Very poor',
      2 => 'Not that bad',
      3 => 'Average',
      4 => 'Good',
      5 => 'Perfect',
    ),
    '#required' => TRUE,
    '#title' => 'Rating',
  );

It is a select list, it is required and there is no default value. I however do not see a empty option...

What am I doing wrong?

Updated

The element above is now the only thing going into my array. When I dpm() the $form I get the following back:

dpm

Update 2

Below is what theme developer is seeing:

theme devel

Update 3

I have set up a clean instance of drupal 7.22 and installed my custom code and the same thing is happening. I used the minimal profile. Must be something I am doing wrong else where...

Update 4

I have tested the full code on a different environment (7.19) and the same thing is happening. So it looks like there is something fundamentally wrong with the modules themselves. Will try and anonymize the problem so I can post here.

Update 5

I have the following two files in my module.

stack_test.module

<?php

function stack_test_menu(){
  $items['stacktest'] = array(
    'title' => 'Stack Test',
    'page callback' => 'stack_test_form',
    'access callback' => TRUE,
    'type' => MENU_NORMAL_ITEM,
    'menu_name' => 'main-menu',
  );
  return $items;
}

function  stack_test_form(){
  $countryList = array (
    1 => t('Very poor'),
    2 => t('Not that bad'),
    3 => t('Average'),
    4 => t('Good'),
    5 => t('Perfect'),
  );
  $form['test'] = array(
    '#type' => 'select',
    '#options' => $countryList,
    '#required' => TRUE,
    '#title' => 'Rating',
  );
  return $form;
}

Then I have my stack_test.info file:

name = Stack Test
description = Test Module
package = Stack Exchange
core = 7.x

files[] = stack_test.module

Update 6

Creating a select list in a content type with validation required works as expected and '- Select a value -' is displayed at the top of the list.

Update 7

The code in Update 5 should work now. I have created a mini module just with that in and I get the same results.

  • Hard as I try, I cannot see an error in your code. The error might be elsewhere ? The empty option is added by form_process_select, which is an implementation of hook_process_HOOK (api.drupal.org/api/drupal/modules%21system%21theme.api.php/…) - is it possible that on your site this process function is bypassed ? Maybe try to put some dpms in that function (it's in includes/form.inc) and see if anything shows up there. – Alice Heaton Apr 22 '13 at 14:43
  • 1
    When I test your code in a random form of mine, I get a drop-down titled 'Rating' and a "-Select-" option at the top, which should serve your purpose. It's not a blank, it's a prompt to select something. What is it that you're seeing? – Boriana Ditcheva Apr 22 '13 at 14:45
  • What is your minor Drupal version ? (7.14, 7.22, etc ?) – AyeshK Apr 22 '13 at 20:54
  • @AyeshK I am running 7.20. So an update to core would be a good idea. – user13134 Apr 23 '13 at 7:33
  • @AliceHeaton form_process_select is not being hit – user13134 Apr 23 '13 at 8:34
6

It looks like you're not running your form through drupal_get_form()...that would account for the additional form processing functions not running, but you'll still get a rendered HTML element out at the other end so it could be difficult to tell the difference.

Just change the page callback for your router item, and add the form as arguments:

function stack_test_menu(){
  $items['stacktest'] = array(
    'title' => 'Stack Test',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('stack_test_form'),
    'access callback' => TRUE,
    'type' => MENU_NORMAL_ITEM,
    'menu_name' => 'main-menu',
  );
  return $items;
}

Clear the caches and give your test page another try.

The same goes for your original problem - A form is essentially just a render array, and when you return that directly from a page callback it's run through drupal_render(). That function will do what it can to render the form element, and it knows how to do it to a certain degree, but the form processing functions add a lot of extra stuff in there, which drupal_render() won't do.

Moral of the story - always use drupal_get_form() to build the output for a form :)

  • You are genius! Everyone was simply assumed it was passed thru drupal_get_form(). – AyeshK Apr 23 '13 at 9:59
2

You need to add "#empty_option" property to the select box to set your default empty option for selectbox. It will add the first option for the select box.

    $form['test'] = array(
    '#type' => 'select',
    '#options' => array (
      1 => 'Very poor',
      2 => 'Not that bad',
      3 => 'Average',
      4 => 'Good',
      5 => 'Perfect',
    ),
    '#required' => TRUE,
    '#title' => 'Rating',
    '#empty_option' => '--Test--',
  );
  • Sadly the same thing is happening with that option – user13134 Apr 23 '13 at 7:35
  • empty_option property will modify the default option '--select--' for the select list. I have checked code and its showing for me. – Jayendra Kainthola Apr 23 '13 at 9:03
  • I agree it should work. Something else must be going on – user13134 Apr 23 '13 at 9:09
1

I copied your code to my own module and it works.

The default (none) value of the field is "- Select -".

Do you have any other code that could be interfering?

Also, tet that it printed to the screen generally should run through the translate function t().

Like this:

$form['test'] = array(
  '#type' => 'select',
  '#title' => t('Rating'),
  '#options' => array(
    1 => t('Very poor'),
    2 => t('Not that bad'),
    3 => t('Average'),
    4 => t('Good'),
    5 => t('Perfect'),
  ),
  '#required' => TRUE,
);
  • You clearly know that t() doesn't make any change, right ? – AyeshK Apr 22 '13 at 20:53
  • I know that t() doesn't fix the bug in the question (there is no bug in the code in the question, as I said). I was just mentioning that it is good practice for t() to be used. – rooby Apr 23 '13 at 0:09
  • @rooby, I grabbed as simple example from online rather than put in our exact production code. My local code does use the t() function. – user13134 Apr 23 '13 at 7:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.