Home | Topics | drupal

Drupal 6 Views 2 custom handler for a dynamic select list

Printer-friendly versionPDF version

The current Drupal project has a network directory, that uses manual entries of data. During a multiple-step migration we have a temporary system where we instead synchronise data from a separate system (ColdFusion and a combination of SQL server and Oracle).

We decided to extend the users table instead of making use of the profile table. It's just a matter of performance optimisation. There is a new field "vCountryName" that contains information about the country of a network partner. Now that we have extended the users table we need to provide data and handlers for this and other fields. This is done in a custom module and a new table. But for ease of explaining the code I have in the example below just put it directly in the users table!

The "function user_views_data()" exists in user.views.inc file in the "views" sub-directory "module". We have extended the following field:

// vCountryName
  $data['users']['vCountryName'] = array(
    'title' => t('v Country Name'), // The item it appears as on the UI,
    'help' => t('Country Name value that comes from external database'), // The help that appears on the UI,
    'field' => array(
      'handler' => 'views_handler_field_user',
      'click sortable' => TRUE,
    'sort' => array(
      'handler' => 'views_handler_sort',
    'argument' => array(
      'handler' => 'views_handler_argument_string',
    'filter' => array(
      'handler' => 'views_handler_filter_country',
      'title' => t('v Country Name'),
      'help' => t('Country Name. This filter do not check if the user exists. Only useful for string comparisons.')

We are telling Views that the field will use a standard handler for a user field called views_handler_field_user. We also tell that it can be sortable by a standard handler called views_handler_sort. Same goes with argument. The filtering is where we are doing some customisation. We want to sort the countries that are currently existing amongst the users alphabetically and by exposing this filter the person making a search can select from this dynamic list.

For the " function user_views_handlers()" we extended in the "'handlers' => array(" the following:

'views_handler_filter_country' => array(
        'parent' => 'views_handler_filter_string',

Moving from this exampe to reality we would do this  in a custom_module. http://treehouseagency.com has a good blog post for more information about views handlers in general.

Next is to create the handler that overrides an already existing handler (it is OO, so it is quite easy to do the overriding behaviours). The file is called "views_handler_filter_country.inc" or "custom_module_filter_country.inc" where custom_module is the name of your module. In my explanation I re-factored the code so that it looks like we are extending the views module itself. Remember to add reference to it in the info file of your custom_module! Other similar overrides can be found at: /views/modules/user/. Here is the complete inc file:


 * Filter handler for countries
class views_handler_filter_country extends views_handler_filter_string     {
    function value_form(&$form, &$form_state) {
        $select_values = countryList();
        $form['value'] = array(
            '#type' => 'select',
            '#title' => t('Countries'),
            '#options' => $select_values,
        return $form;

    function countryList() {
        $q = "SELECT DISTINCT vCountryName FROM `users` WHERE 1 ORDER BY `vCountryName` ASC";
        $r = db_query($q);
        $list = array();
        while($row = db_result($r)) {
            $list[$row] = $row;
        return $list;

The function countryList() goes through the users table, the field vCountryName and picks each country (once, hence using SELECT DISTINCT) and sorts it in ascending (alphabetical) order. Your select distinct statement would contain the content_type_profile table or your own special table that your module installs. Up to you! The important thing is that the select list is dynamic. If a new user from a new country joins, his country will appear on the select list!

For identifying each option we had to add a $row in the array to make it an associative array.

$list[$row] = $row; 

When making the filter of this new field vCountryName we "Expose" it so that users can enter data. The select list of countries will appear. Important is that the Filter Identifier is the same "vCountryName". The HTML will look like this:

<select name="vCountryName" class="form-select" id="edit-vCountryName" ><option value="Albania">Albania</option><option value="Armenia">Armenia</option><option value="Austria">Austria</option><option value="Belgium">Belgium</option><option value="Bosnia and Herzegovina">Bosnia and Herzegovina</option><option value="Bulgaria">Bulgaria</option><option value="Chile">Chile</option><option value="China">China</option><option value="Croatia">Croatia</option><option value="Cyprus">Cyprus</option><option value="Czech_Republic">Czech_Republic</option><option value="Denmark">Denmark</option><option value="Egypt">Egypt</option><option value="Estonia">Estonia</option><option value="Finland">Finland</option><option value="France">France</option><option value="Germany">Germany</option><option value="Greece">Greece</option><option value="Hungary">Hungary</option><option value="Iceland">Iceland</option><option value="Ireland">Ireland</option><option value="Israel">Israel</option><option value="Italy">Italy</option><option value="Japan">Japan</option><option value="Korea, Republic of">Korea, Republic of</option><option value="Latvia">Latvia</option><option value="Lithuania">Lithuania</option><option value="Luxembourg">Luxembourg</option><option value="Macedonia, the Former Yugoslav Republic of">Macedonia, the Former Yugoslav Republic of</option><option value="Malta">Malta</option><option value="Moldova, Republic of">Moldova, Republic of</option><option value="Montenegro">Montenegro</option><option value="Netherlands">Netherlands</option><option value="Norway">Norway</option><option value="Philippines">Philippines</option><option value="Poland">Poland</option><option value="Portugal">Portugal</option><option value="Reunion">Reunion</option><option value="Romania">Romania</option><option value="Russian Federation">Russian Federation</option><option value="Serbia">Serbia</option><option value="Slovakia">Slovakia</option><option value="Slovenia">Slovenia</option><option value="Spain">Spain</option><option value="Sweden">Sweden</option><option value="Switzerland">Switzerland</option><option value="Syrian Arab Republic">Syrian Arab Republic</option><option value="Tunisia">Tunisia</option><option value="Turkey">Turkey</option><option value="Ukraine">Ukraine</option><option value="United Kingdom">United Kingdom</option><option value="United States">United States</option></select>
Short URL
Asymptotix on Twitter

Are the key legislative pillars such as Basel II & III, UCITS IV and Solvency II forcing you to re-examine how you identify, measure and manage risk and capital?

Asymptotix work closely with our partners to help clients develop a more proactive, systematic and integrated approach to governance and risk management to deliver proper value.

Asymptotix can offer the support you need to deliver on time. Read more...

Is the goal of your website to sell services or products, educate, or collect data?

A positive customer experience is vital to conversion, no matter what your conversion goals may be. Our designers and developers will create a positive experience to maximize your conversions and deliver the optimal return on your investment. We strive to find the perfect balance between the web site’s design and functionality.

Asymptotix implements interactive solutions for European companies. From corporate websites to social communities, our clients will tell you an investment in building a scalable online experience will deliver long-term tangible benefits.

Based in Luxembourg we can help you all over Europe. Our multi-lingual team can work with projects and speak your language! Read more...