Drupal and Custom Combo Boxes

Working with forms is often one of the most challenging tasks for a front-end developer. Select boxes specifically are very difficult. Most form elements can be fully customized using CSS only, but the select element is not one of these cases. These can be barely modified, and, although there are some techniques to replace them with hidden input fields, this is not the right approach when you are working on a Drupal project.

The straight-forward approach to adopt for this problem is to search for a community module that fulfills our needs. Drupal’s community provides a module for almost any need; in fact, there is one available to create custom dropdowns (JQuery Dropdown). At the time we needed to customize dropdowns, and this module presented a major issue that made it impossible to use. A pure JavaScript approach came up as a solution.

There are plenty of JQuery plugins to replace HTML selects out there, although we couldn’t find one that could be considered really complete (Bonus tip: some plugins may not work with your current version of JQuery. To update it, use the JQuery Update  module). We ended up choosing one based on the fairly simple HTML replacement markup that it presented.

Soon enough we discovered that was not a completely satisfactory solution. The plugin crashed with other dropdown-related modules such as Hierarchical Select and required to put a lot of extra hours to stabilize it. Another major disadvantage to this approach was the loss of performance that our site underwent. The problem with this path was that any JavaScript-based solution will take any select combobox and transform it to its HTML replacement version on execution time. Extrapolate that to a situation where you have twenty or more (like in the Blocks admin page) dropdowns in which content is being loaded dynamically and you will find yourself sitting at your desktop waiting minutes for this page to load, especially in IE, which surely will throw a couple warning messages about a suspicious script taking too long to execute.

To overcome these issues we saw no other alternative but to design and build our own custom dropdown module which wouldn’t really transform selects but give the markup we needed already through the override of the theme_select() function.

The module was structured as following:

  • PHP logic that gives out the needed HTML markup plus the original select invisible.
  • JS logic that defines the dropdown behaviors as click, hover and change events.
  • CSS basic styles for the dropdown to work cross-browser.
  • CSS skin for the dropdown.

This final approach resolved our performance problem but some final issues arose.
The module was built under the assumption that every select coming from Drupal, no matter if it was created inside a core or community/custom module, should pass through the theme_select() function. However, we discovered that big and solid modules such as Hierarchical Select or Ubercart didn’t really follow this Drupal best practice. Integration work had to be performed but the advantage this time was that this work was done inside the module, meaning this effort will work on this project and on any other project that requires this combination of modules.

Although the module still misses some highly-desirable features such as keyboard integration, it is a solid candidate to be contributed to the Drupal community.