I'm trying a functionality with a content type that has several fields as follows; full name being the node title, year born being a cck field (type=integer) and another is a computed field using a computed field that returns the age category of the person. the php code snippet follows;

$currentyear = date("Y");
$ageborn = $node->field_year_born[0]['value'];
$currentage = $currentyear - $ageborn;
switch ($currentage) {
   case ($currentage >= 21 && $currentage <= 30):
      $node_field[0]['value'] = "21-30";
   break;
   case ($currentage >= 31 && $currentage <= 40):
      $node_field[0]['value'] = "31-40";
   break;
   case ($currentage >= 41 && $currentage <= 50):
      $node_field[0]['value'] = "41-50";
   break;
   case ($currentage >= 51 && $currentage <= 60):
      $node_field[0]['value'] = "51-60";
   break;
   case ($currentage > 60):
      $node_field[0]['value'] = ">60";
   break;
}

then i created a views that returns the node's title, year born and the age category. everything goes fine.

now here comes the problem. i created an exposed filter on the age category but the input type is in textfield. i have to know what are the age categories and key in manually in the textfield. i thought of creating a dropdown select list that shows the age categories. how do i do such a feature? views hook?

CommentFileSizeAuthor
#16 title-expose-1.JPG3.56 KBsaiya
#16 title-expose-2.JPG22.78 KBsaiya
#16 title-expose-3.JPG26.78 KBsaiya
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

francoud’s picture

I also need this... no suggestions?

amal850720’s picture

glad to find someone else doing and asking for the same thing. mostly suggest using views_hook. i'm digging that for now.

TechNikh’s picture

did you find a solution for this?

amal850720’s picture

nope. negative.

Jegan2668’s picture

subscribe

spencerbrooks’s picture

I did this by creating a small module that implements hook_form_alter. For example, this is the code I used to turn a text field into a dropdown box of decades (obviously you'll need to replace with your content type):

function decadeselect_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == "views_exposed_form" && $form['#id'] == "views-exposed-form-exposed-filter-search-page-1") {
    
    $form['field_collection_item_decade_value']['#type'] = "select";
    $form['field_collection_item_decade_value']['#size'] = null;
    $form['field_collection_item_decade_value']['#default_value'] = $form['field_collection_item_decade_value']['#options']['All'];
    $form['field_collection_item_decade_value']['#options'] = array(
      'All' => t('<Any>'),
      '2000s' => t('2000s'),
      '1990s' => t('1990s'),
      '1980s' => t('1980s'),
      '1970s' => t('1970s'),
      '1960s' => t('1960s'),
      '1950s' => t('1950s'),
      '1940s' => t('1940s'),
      'Prior to 1940' => t('Prior to 1940')
    );

  }
}
alanpeart’s picture

I can confirm that this approach works. In my case I needed to have a drop-down of node titles as a filter (a fairly common use case I think), so the above code combined with a bit of SQL to get the titles did the job.

LTech’s picture

Could you please explain exactely where to put the code in #6. I'm new to drupal and I want to turn a computed field text area into a drop down views exposed filter.
Thanks so much. (I'm using drupal 7)

LTech’s picture

I worked out how to create a new module. http://www.ubercart/comment/8749/Re-Removing-SKU-product-edit-page was a helpful guide.

I've used the code in #6. It is great except that I get the error:
Notice: Undefined index: #options in age_form_alter() (line 16 ' $form['field_age_value']['#default_value'] = $form['field_age_value']['#options']['All'];
An illegal choice has been detected. Please contact the site administrator.

If I put $form['field_age_value']['#options'] = array(...); before the $form['field_age_value']['#default_value'] line it removes the first part of the error but I am still left with:
An illegal choice has been detected. Please contact the site administrator.

I can't seem to get rid of this. Any ideas what I can do?
Thanks

LTech’s picture

I finally found the solution.
Add the line:
$form['field_age_value']['#options']= t("");
to remove the error:
An illegal choice has been detected. Please contact the site administrator.

kay.beissert’s picture

This solution sounds got to me but I have nodes with a date field (only the Year) and need an exposed filter with three dropdown date ranges (0-15 years, 15-30 years, older than 30 years). Im no php-guy, tried to snip around this code but had no luck. Can someone help me out with a shiny, little code snipped for my exposed filter?

Thanks a lot ;)

cknoebel’s picture

This thread was a huge help. I modified #6 to look up values from a Webform table, which I'm using to populate the exposed filter. The View groups results by "captain" and the code here populates the exposed filter with values for "captain" which lives both on the node in a CCK field and in the Webform table. I guess I could have grabbed it from all the nodes of this content type, but I have other shenanigans going on that led me down this path.

function mymodule_form_alter(&$form, $form_state, $form_id) {
switch($form_id) { 
  case 'views_exposed_form':
      // Over-ride Views exposed filter for Captain so it replaces the text field with a select list populated by captains marked as paid in a Webform table
      if ($form['#id'] == 'views-exposed-form-pledge-team-list-page-1') {      
            // Using dpm with Devel installed to give me array data on the Views form
            //dpm($form);
            $form['field_pledge_team_value']['#type'] = "select";
            $form['field_pledge_team_value']['#size'] = null;
            $captain[''] = t('-- All Captains --');
            $query = db_query("
              SELECT 
                a.nid AS nid,
                a.sid AS sid,
                a.data AS name_first,
                b.data AS name_last,
                c.data AS user_name,
                d.data AS paid
              FROM {webform_submitted_data a}, {webform_submitted_data b}, {webform_submitted_data c}, {webform_submitted_data d}
              WHERE a.sid = b.sid
                AND b.sid = c.sid
                AND c.sid = d.sid
                AND a.cid = '3'
                AND b.cid = '4'
                AND c.cid = '7'
                AND d.cid = '2'
                AND a.nid = '441'
             ");
     
             // Run through the results
             while($result = db_fetch_array($query)) {
               if ($result[paid] == 'paid') {
                 $construct = $result[name_first] . ' ' . $result[name_last];
                 $captain[$construct] = t($construct);
               }
             }
             $form['field_pledge_team_value']['#options'] = $captain;
             $form['submit']['#value'] = t('Search'); 
         }
    break;
  }
}
LTech’s picture

I create a module for a dropdown exposed filter similar to #6 called age_range. It has been working great. I just added another computed field to my content type called age_range_test and even before I put any code in it, it has broken my module. I deleted the field age_range_test but the module for age_range still won't work. Does anyone know why another computed field should affect the module?
How can I get the module to work again? I'm really stuck, any ideas would be really appreciated.
Thanks

sumaiyajaved’s picture

If you have done the above and still it is not working .. try clean cache (admin/settings/performance) or reset computer ... worked for me then.

thanks guys for the help

LTech’s picture

it's working, thanks

saiya’s picture

FileSize
26.78 KB
22.78 KB
3.56 KB

excuse me sir,
referring to #6.
i wanted to change exposed filter from textfield to dropdown list. but im new to drupal. and i dont know how to implement the code.
this is my sample:

1. i created a filter with node title.
title expose1

2. then i create an expose to that title. operator is "Start With"
title expose2

3. the output is to make user just input start letter. so i want to make it as a drop down list. example like this:

0-9
A
B
C
... until Z
title expose3

the problem is, where i can put the code given at #6?

dhills’s picture

I am looking to do the same as most people above, an exposed filter with a dropdown of allowed values instead of a textfield. Unfortunately, I do not know what a hook is or what to do with it, or understand php, how to write it or where to put it. Is there no module to do this directly? If not, can someone point me to resources that a newbie can use to perform such a function?

Thanks!

Anonymous’s picture

Version: 6.x-1.0-beta3 » 7.x-1.x-dev

I have this code (Drupal 7) but it keeps saying "An illegal choice has been detected. Please contact the site administrator." whenever I even touch the options value. Any idea how to fix it?

function MYMODULE_form_views_exposed_form_alter(&$form, &$form_state) {
  if($form['#id'] == 'views-exposed-form-special-page-1')
  {
    $form['field_computed_value_1']['#type'] = 'select';
    $form['field_computed_value_1']['#size'] = null;
    $form['field_computed_value_1']['#default_value'] = No;
    $form['field_computed_value_1']['#options'] = $options; // this variable not relevant, anything seems to cause the error
  }
end user’s picture

I am looking to do the same as most people above, an exposed filter with a dropdown of allowed values instead of a textfield. Unfortunately, I do not know what a hook is or what to do with it, or understand php, how to write it or where to put it. Is there no module to do this directly? If not, can someone point me to resources that a newbie can use to perform such a function?

Have a look here. This module turns a text field (my users enter their city name into it when they create a mode) and turns it into a drop down when exposed in views.

http://drupal.org/node/1549250#comment-5932296

edrupal’s picture

With ref to Kline's issue in post #18 it may be that the $options array doesn't have a null value setting. Try adding something like

$options = array("" => "All");

Ed

Anonymous’s picture

Thanks, I'll give that a shot.

ThirstySix’s picture

it's working, thanks..
Thanks for all..

rodpascoe’s picture

Can anyone help with a Drupal 6.x version of this?

I have tried to use

<?php
function thenps_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == "views_exposed_form") {

$form['distance[search_distance]']['#type'] = "select";
$form['distance[search_distance]']['#size'] = null;
$form['distance[search_distance]']['#default_value'] = $form['distance[search_distance]']['#options']['All'];
$form['distance[search_distance]']['#options'] = array(
'All' => t(''),
'5' => t('5'),
'1' => t('1'),
'25' => t('25'),
'50' => t('50'),
);

}
}

But nothing I try is working. I wondered if it was because the fields were part of an array?

Would love some feedback!

Thanks

wing112707’s picture

Thanks it helps..

rodpascoe’s picture

Can nobody help? :-(

Can anyone help with a Drupal 6.x version of this?

I have tried to use

<?php
function thenps_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == "views_exposed_form") {

$form['distance[search_distance]']['#type'] = "select";
$form['distance[search_distance]']['#size'] = null;
$form['distance[search_distance]']['#default_value'] = $form['distance[search_distance]']['#options']['All'];
$form['distance[search_distance]']['#options'] = array(
'All' => t(''),
'5' => t('5'),
'1' => t('1'),
'25' => t('25'),
'50' => t('50'),
);

}
}

But nothing I try is working. I wondered if it was because the fields were part of an array?

Would love some feedback!

Thanks

stevenx’s picture

#18 and #20
works fine for me.
thanks!

keyswebsites’s picture

You can set an exposed filter to use pre-defined values presented in a dropdown by selecting "grouped" in the filter configuration page.

lias’s picture

Thank you keyswebsites for sharing this simple way to do create a category dropdown from a computed age field! I have been struggling with this and you've provided the "ah-ha!" moment.

creatile’s picture

I try to do the same thing with a date exposed filter,
And it doesn't work.
I get the following message:

Warning: Illegal offset type in isset or empty in _form_validate() (line 1326 of /Users/creatile/Sites/datetest/includes/form.inc).
An illegal choice has been detected. Please contact the site administrator.
Notice: Array to string conversion in devel_watchdog() (line 531 of /Users/creatile/Sites/datetest/sites/all/modules/devel/devel.module).

here is my code

<?php
function views_exposed_month_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
    case 'views_exposed_form':
      if( !empty($form['#id']) && $form['#id'] == 'views-exposed-form-events-page') {

  $now = date('Y-m-d');
 
  //dpm($form);

    $form['field_date_value']['#type'] = "select";
    $form['field_date_value']['#size'] = null;
	$form['field_date_value']['value']['#date_format'] = 'j-m-Y';
    
    $form['field_date_value']['#name'] = 'field_date_value[value][date]';
    $form['field_date_value']['#id'] = 'edit-field-date-value-value-date';
    $form['field_date_value']['#options'] = array(
    	'All' => t(''),
      '01-12-2013' => t('Décembre 2013'),
      '01-01-2014' => t('Janvier 2014')

    );
    
    $form['field_date_value']['#default_value'] = $form['field_date_value']['#options']['All'];
    
  }
   break;
   }
}
gabrielZ’s picture

ashwinsh’s picture

Point #12 Works for me, Thank you knoebel.

kumkum29’s picture

Hello,

i have followed your differents posts to change a textfield of a view exposed filter to a list options.
It's ok for me, but I get a <optgroup...> in the beginning of my list.
What I must change in my code for hide this <optgroup>?

	if ($form['#id'] == 'views-exposed-form-nameview-page-1') {
			$query = db_select('menu_node', 'mn');
			$query->join('node', 'n', 'n.nid = mn.nid');
			$query
				->fields('mn', array('mlid'))
				->fields('n', array('title'))
				->condition('n.status', 1)
			$results = $query->execute();
			$node_options = array(
				'' => '- Any -',
			);
			foreach ($results as $record) {
				$node_mlid = $record->mlid;
				$node_title = $record->title;
				$node_options[$node_mlid] = $node_title;
			}
			
			$form['p1']['#type'] = 'select';
			$form['p1']['#size'] = null;
			$form['p1']['#options'] = array(
				//'' => '- Any -',
				$node_options
			);
	}

Thanks for your help.

////////////////////////////// UPDATE
I have found the solution. In the options, i have an array inside an array.
I have simplified the code and it's ok : $form['p1']['#options'] = $node_options;

Johann Wagner’s picture

Thanks gabrielZ #30, Better Exposed Filters works like a charm.

Anonymous’s picture

I too wan't something like this in #16 but I don't know any coding. Is there a module for this yet?
It's really useful and there should be.

eebanos’s picture

Using the code provided in the comment #18
function MYMODULE_form_views_exposed_form_alter(&$form, &$form_state) {
if($form['#id'] == 'views-exposed-form-special-page-1')
{
$form['field_computed_value_1']['#type'] = 'select';
$form['field_computed_value_1']['#size'] = null;
$form['field_computed_value_1']['#default_value'] = No;
$form['field_computed_value_1']['#options'] = $options;
}

USE WITH CAUTION!!!
It seems that the error cames from the AJAX validation used in the form to avoid injection into the database:

Just add this line: $form['field_computed_value_1']['#validated'] = TRUE;

Source:
https://drupal.stackexchange.com/questions/15989/resolve-the-error-an-il...
http://drupal.stackexchange.com/questions/31846/illegal-choice-has-been-...
http://drupal.stackexchange.com/questions/96669/how-to-avoid-an-illegal-...

rajeshsaikrishna’s picture

Please go through the following steps to display the select list as links

//hook_theme

function mymodule_theme($existing, $type, $theme, $path){
    return array(
        'list_items' => array(
            'template' => 'list_items', //tpl to display them as list
            'path' => $path . '/templates', 
            'type' => 'module',
            'variables' => array(
                'list' => NULL,
                'current' => NULL
            ),
        ),
    );
}

/*
hook_form_alter
*/

function mymodule_form_alter(&$form, &$form_state, $form_id) {
    if($form_id == 'views_exposed_form') {
     $current = '';
     $ranges = explode(':',$form['date_filter']['value']['#date_year_range']);
    foreach($ranges as $key => $range) {
       $ranges[$key] = date('Y', strtotime($range.' years', strtotime(date('Y-m-d H:i:s'))));
    }    
    $startYear = $ranges[0];
    $endYear = $ranges[1];    
    if($ranges[0] > $ranges[1]) {
        $endYear = $ranges[0];
        $startYear = $ranges[1];
    }    
    $items = array();
    $endYear = (int)$endYear;
    $startYear = (int)$startYear;
    if(empty($_REQUEST['date_filter']['value']['year'])) {
    $items[] = 'All years';
    } else {
       $items[] = l('All years', current_path(),array('query' => array("date_filter[value][year]" => '')) );
    }
    
    for($i=$endYear; $i>=$startYear; $i--) {
        if($_REQUEST['date_filter']['value']['year'] == $i) {
         $items[$i] = $i;
         $current = 'active';
        } else {
         $items[$i] = l($i, current_path(), array('query' => array("date_filter[value][year]" => $i)));
         $current = '';            
        }         
        }
       $list = theme('list_items', array('list' => $items, 'current' => $_REQUEST['date_filter']['value']['year']));
       $form['html'] = array(
        '#type' => 'markup',
        '#markup' => $list,
    );
    }
}

//templates/list_items.tpl.php

            <ol>
                <?php foreach($list as $key => $value) { 
                    if($current == $key || empty($current)) {
                ?>
                <li class="active"><?php print $value; ?></li>
                    <?php } else { ?> 
                <li><?php print $value; ?></li>
                <?php } } ?>
            </ol>

//mymodule.info
name = Filters customization
description = Filters customization
version = VERSION
core = 7.x
dependencies[] = date


MrsWho’s picture

I was able to turn a list of nodes into an exposed filter using the Views Reference Filter module.

Vali Hutchison’s picture

Like a few others I was getting the "An illegal choice has been detected. Please contact the site administrator." error message when converting a text filter to a select filter.

Managed to fix this by using a null value for the default select option rather than 'All'.

E.g.

$options = array('' => '- Any -');

harishpatel86’s picture

Some correction in #6 post. For remove "An illegal choice has been detected. Please contact the site administrator." error message.

function decadeselect_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == "views_exposed_form" && $form['#id'] == "views-exposed-form-exposed-filter-search-page-1") {

$form['field_collection_item_decade_value']['#type'] = "select";
$form['field_collection_item_decade_value']['#size'] = null;
$form['field_collection_item_decade_value']['#default_value'] = $form['field_collection_item_decade_value']['#options']['All'];
$form['field_collection_item_decade_value']['#options'] = array(
'' => '- Any -',
'2000s' => t('2000s'),
'1990s' => t('1990s'),
'1980s' => t('1980s'),
'1970s' => t('1970s'),
'1960s' => t('1960s'),
'1950s' => t('1950s'),
'1940s' => t('1940s'),
'Prior to 1940' => t('Prior to 1940')
);

}
}

gaurishankar’s picture

#39 working for me. But needs minor correction here : REMOVE line $form['field_collection_item_decade_value']['#default_value'] = $form['field_collection_item_decade_value']['#options']['All'];

Shivamverma’s picture

Simply try this one Helps you regarding Issue Illegal Choice has been detected ----->

$form['field_location_dependent_locality']['#options'] = array("" => "All",t('duhv'), t('sfjns'), t('sdknsk'));

zawlinnoo’s picture

In case, if you don't want to add default value and avoid "An illegal choice has been detected. Please contact the site administrator.", use this.

$form['field_name']['#validated'] = TRUE;

that will be updated with AJAX on select.

christinlepson’s picture


function hook_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
{
  $is_desired_form = strpos($form['#id'], 'views-exposed-form-example-view') !== FALSE;

  // If we have the desired exposed form form
  if ($form_id == "views_exposed_form" && $is_desired_form) {

    // Change the filter from type text to select.
    $form['example_filter']['#type'] = 'select';
    // Set the size to NULL
    $form['example_filter']['#size'] = NULL;

    // Create your custom options as an associative array of value => label
    $options = [
      "" => '-All-',
      "value1" => "Label One",
      "value2" => "Label Two",
      "value3" => "Label Three",
      "value4" => "Label Four",
    ];

    // Set your custom options on your select filter
    $form['example_filter']['#options'] = $options;
  }
}

I made a blog post for this issue if anyone is stuck

colan’s picture

Version: 7.x-1.x-dev » 8.x-2.x-dev
Category: Support request » Feature request

There's been enough interest in this over the years through many major Drupal versions. As such, I'm in favour of supporting this natively.

We could do what Views Autocomplete Filters is doing, but implement it as a select list instead. Drupal 7 Views drop-down exposed filter for a text field may be helpful here, even though it's for Drupal 7.

Oh, and if you're thinking of using Views Autocomplete Filters to get an autocomplete field instead, it doesn't yet support Computed Fields. If you're interested in that, create an issue in that queue, and link to it from here. Thanks! This actually works: You just need patches from #2986201: "Add some fields to view" option is always empty and #3083093: Correct handling for autocomplete with(out) dependent filters.

colan’s picture

colan’s picture