I'm looking for a module that will turn a text field that is used to collect say a city name through a text field when a node is created into a drop down list when that field is exposed in views.

Also I need the module to only list each entry once. So say I have a field called (city name) and there are 20 nodes with the city name Vancouver I only need to show this once in the drop down.

I was going to use the Auto-complete Widget module but after testing seems it doesn't work with Contextual filters and I think a drop down would be better for people with JS turned off.

I've included a screenshot of what I'm looking for.

http://www.getubercart.com/dropdown.jpg

Comments

Sagar Ramgade’s picture

Hi,

You need to implement hook_form_alter in your module to alter your views exposed form. It will change the textfield to select list and set options fetched from the database.

Acquia certified Developer
Need help? Please use my contact form

end user’s picture

I would but know nothing about php. Saw a few examples of modules people wrote but they were dor D6/V2.

Should have stated I'll pay $50 for the module.

end user’s picture

Job has been completed.

Thank You.

end user’s picture

For those who have the same need of turning a text field into a drop down when exposed in views here's the modules. You will need to change

$field_id = 'field_exact_location';

to the name of your content types text field.

There are the module files. You can name the module to suit your needs.

dd_city.info file

name = Dropdown City
description = Provides dropdown filter for city field
core = 7.x

files[] = drop_city.module

dd_city.module

<?php

function dd_city_form_views_exposed_form_alter(&$form, &$form_state) {
  $field_id = 'field_exact_location';

  // Only alter forms with the necessary field
  if (isset($form[$field_id .'_value'])) {
    // Build a query to get all node ids having the specified field
    $query = new EntityFieldQuery();
    $results = $query->entityCondition('entity_type', 'node')
                      ->fieldCondition($field_id, 'value', 'NULL', '!=')
                      ->fieldOrderBy($field_id, 'value', 'ASC')                   
                      ->execute();
                       
    // Attach the field values to the nodes
    $nodes = $results['node'];
    field_attach_load('node', $nodes, FIELD_LOAD_CURRENT, array('field_id' => $field_id));
 
    // Add a default so the filter is optional
    $options = array('' => '<select>');
   
    // Buld the options array based on the query results, overwriting duplicate entries
    foreach($nodes as $nid => $node) {
      $value = $node->field_exact_location['und'][0]['value'];
      $options[$value] = $value;
    }
 
    // Alter the field
    $form[$field_id .'_value']['#type'] = 'select';
    $form[$field_id .'_value']['#options'] = $options;
    $form[$field_id .'_value']['#size'] = 1;
  }
}

Create the files, upload them to your modules directory and activate the module.

d3vo’s picture

I got your module to work perfect with a regular text field. But Im trying to use the Address module for D7 and i cant seem to get it right. I get the drop down using the code below but there is nothing in it. I get an error of

    Notice: Undefined index: node in dd_state_form_views_exposed_form_alter() (line 16 of C:\Users\d3vo\Sites\acquia-drupal\sites\all\modules\dd_state\dd_state.module).
    Warning: Invalid argument supplied for foreach() in dd_state_form_views_exposed_form_alter() (line 23 of C:\Users\d3vo\Sites\acquia-drupal\sites\all\modules\dd_state\dd_state.module).

I am looking to pull the state (administrative_area) into a dropdown filter selection.
MODULE CODE

<?php

function dd_state_form_views_exposed_form_alter(&$form, &$form_state) {
  $field_id = 'field_address';

  // Only alter forms with the necessary field
  if (isset($form[$field_id .'_administrative_area'])) {
    // Build a query to get all node ids having the specified field
    $query = new EntityFieldQuery();
    $results = $query->entityCondition('entity_type', 'node')
                      ->fieldCondition($field_id, 'administrative_area', 'NULL', '!=')
                      ->fieldOrderBy($field_id, 'administrative_area', 'ASC')                  
                      ->execute();
                      
    // Attach the field values to the nodes
    $nodes = $results['node'];
    field_attach_load('node', $nodes, FIELD_LOAD_CURRENT, array('field_id' => $field_id));

    // Add a default so the filter is optional
    $options = array('' => '<select>');
  
    // Buld the options array based on the query results, overwriting duplicate entries
    foreach($nodes as $nid => $node) {
      $value = $node->field_address['und'][0]['value'];
      $options[$value] = $value;
    }

    // Alter the field
    $form[$field_id .'_administrative_area']['#type'] = 'select';
    $form[$field_id .'_administrative_area']['#options'] = $options;
    $form[$field_id .'_administrative_area']['#size'] = 1;
  }
}

Any help would be greatly appreciated.
Regards

impleri’s picture

Just in case anyone's wondering, the following function works, based on above.

<?php
function MYMODULE_form_views_exposed_form_alter(&$form, &$form_state) {
 
$field_id = 'field_address'; // change for the field in question

  // Only alter forms with the necessary field
 
if (isset($form[$field_id .'_administrative_area'])) {
   
// Build a query to get all node ids having the specified field
   
$query = new EntityFieldQuery();
   
$results = $query->entityCondition('entity_type', 'node')
    ->
fieldCondition($field_id, 'administrative_area', '', '!=')
    ->
fieldOrderBy($field_id, 'administrative_area', 'ASC')
    ->
execute();
    
   
// Attach the field values to the nodes
   
$nodes = $results['node'];
   
field_attach_load('node', $nodes, FIELD_LOAD_CURRENT, array('field_id' => $field_id));

   
// Add a default so the filter is optional
   
$options = array('' => '---');
    
   
// Buld the options array based on the query results, overwriting duplicate entries
   
foreach($nodes as $nid => $node) {
     
$value = $node->{$field_id}['und'][0]['administrative_area'];
     
$options[$value] = $value;
    }

   
// Alter the field
   
$form[$field_id .'_administrative_area']['#type'] = 'select';
   
$form[$field_id .'_administrative_area']['#options'] = $options;
   
$form[$field_id .'_administrative_area']['#size'] = 1;
  }
}
?>
LNakamura’s picture

@end user's solution (in the comment titled "For those who have the same") works great for me for one of my scenarios, but I have another which requires a multiselect drop down. I can convert the drop down to multiselect, but then my form stops working - even if I only choose one of the options :-/ Has anyone tried something like this before? (By "stops working", I mean that I get no results when I submit the form.)

WhereverPanda’s picture

Hi, I've been working with Drupal for some time, but I'm still rubbish at the very back end bits. All I would like to know is, if I want to expose the content's titles as a dropdown list, what would I use in the field $field_id = 'field_exact_location'; ?

any help would be greatly appreciated
Thanks!

1kenthomas’s picture

Please edit original title to reflect this. Thanks.

junkbox’s picture

thanks for that, needed it for another entity type but easily changed it.

Keyboard Error or No Keyboard Present. Think F1 to Continue.

benchesters’s picture

https://drupal.org/comment/reply/1549250#comment-form

Hi Junkbox - I noticed you said you changed the code that this kind gentleman posted here so this would work on an entity instead of a node. Was wondering if you could perhaps share with me what you did as I cannot seem to get this working! If not, no worries.

Thanks

Ben

criznach’s picture

Thanks for sharing! (I wrote it if anyone has questions about it)

fuerst’s picture

When you need to have grouped-by values (duplicates filtered) you may use this function instead:

<?php
function dd_city_form_views_exposed_form_alter(&$form, &$form_state) {
 
$field_id = 'field_whatever';

 
// Only alter forms with the necessary field
 
if (isset($form[$field_id .'_value'])) {   
   
// Build a query to get grouped by values of the field
   
$query = db_select('field_data_' . $field_id, 'fd');
   
$query->addField('fd', $field_id . '_value', 'field');
   
$query->groupBy($field_id . '_value');

   
// Execute query
   
try {
     
$result = $query->execute();
    }
    catch (
Exception $e) {
     
// Error handling: Just a message and no change of the field
     
drupal_set_message(t('SQL Query failed when rewriting field %field from TEXT field to SELECT field.', array('%field' => $field_id)), 'warning');
      return;
    }
   
   
// Start with a default so the filter is optional
   
$options = array('' => t('any'));

   
// Build the options array based on the grouped field values
   
foreach($result as $row) {
     
$options[$row->field] = $row->field;
    }
   
   
// Alter the field
   
$form[$field_id .'_value']['#type'] = 'select';
   
$form[$field_id .'_value']['#options'] = $options;
   
$form[$field_id .'_value']['#size'] = 1;
  }
}
?>
Summit’s picture

Hi,
Isn't using Field text (list) enough for D7?
greetings, Martijn