Drupal Views Filters: Making Exposed Searches User-Friendly

One of the main new features of the Archdiocese of Saint Louis' website (to launch on February 22!) is the much-improved parish and school searching capabilities. There are many facets to these sections of the site; everything is built using the combination of nodes built with CCK, Views, and Mapstraction (for Google Map interfaces).

Parish Search by Name

One of the main annoyances with most implementations of parish and school searching that I've found (and I've tested almost every U.S. Archdiocese's website for this functionality) is the fact that searches are extremely rigid - if you don't type in the exact terms for the title of the parish in the parish database, you won't get any results.

For instance, type in "St. Luke," and you might get a result for St. Luke parish. However, type in "Saint Luke," and you get nothing. Or, what if you type in "Saints Joachim and Anne," but the parish is in the database as "Sts. Joachim & Anne"?

To message search data, we used a few regex filters on the user input, and Drupal allowed us to do this pretty easily by hooking into the exposed form on the parish and school search pages.

Hooking into Views' Exposed Forms

First, you'll have to create a custom module for your Drupal site. Inside that custom module, you'll use a hook_form_alter() to alter the user input of the views exposed form just before it's submitted to the search. Here's our form_alter():

<?php
/**
 * Implementation of hook_form_alter().
 */
function custom_form_alter(&$form, $form_state, $form_id) {
  if (
$form_id == 'views_exposed_form') {
   
// Add custom validation form for parish search
   
if ($form['#parameters']['1']['view']->name == 'parish_directory') {
     
$form['#validate'][] = 'custom_parish_form_switcheroo';
    }
  }
}
?>

We are using a "parish_directory" view, so we tell hook_form_alter to only apply our custom function, 'custom_parish_form_switcheroo,' to the parish name search form.

And here's our custom function, which takes the form data as entered by the user, applies some regular expression replacements (using PHP's preg_replace()), and then sends that data to the search filter:

<?php
/**
 * Makes parish search easier.
 */
function custom_parish_form_switcheroo($form, &$form_state) {
 
// Convert abbreviations (like "St.", "Sts.", "St", "St")
  // Also, sometimes there is a "/" right before the "St." part, so strip that
 
$form_state['values']['name'] = preg_replace('/^(\/)?st(s)?(\.)? /i', '$1Saint$2 ', $form_state['values']['name']);
 
// Change ampersand to "and" ("Joachim & Ann" becomes "Joachim and Ann")
 
$form_state['values']['name'] = preg_replace('/&/i', 'and', $form_state['values']['name']);
 
// Strip "'s" (eg, "St. Sabina's" turns into "St. Sabina")
 
$form_state['values']['name'] = preg_replace("/'s$/i", '', $form_state['values']['name']);
}
?>

Using these rules, we are able to allow people to search for "St., "Saint," "Sts.," "Saints," "St," etc... they can also type in "Saint Sabina's," and get the proper result. basically, we're allowing users to not have to worry as much about data purity.

In an ideal world, Views would provide a built-in 'did you mean' filter, but until then, we'll have to improve user experience in Views searching using baby steps...

I would like to thank Joel Stein for his excellent help in setting up this feature on the Archdiocesan website!

Comments

Carson Weber's picture

What is a good website that provides free online video tutorials on Drupal?

Open Source Catholic's picture

http://gotdrupal.com/
http://www.drupaltherapy.com/

And if you have a little money: http://www.lynda.com/ has some good series.

Advancing the faith.

Matt Korger's picture

I've found Google Maps to be difficult at times. Joomla has similar add ons. Even when searching an exact mailable address, Google maps can botch the search and return the address not found. For example

State Rd. 16, La Crosse, WI - no results
Highway 16, La Crosse, WI - no results
Wisconsin 16, La Crosse, WI - Ding Ding, we have a winner!

The USPS provides aliases in a directory listing so that there is an association between these street names but Google does not take advantage of it. Google used to use TeleAtlas Navteq data but recently ditched it(probably because it cost a fortune).
http://www.readwriteweb.com/archives/google_maps_ditches_teleatlas_in_fa...

Open Source Catholic's picture

I was more speaking of the actual searching built into the new site (not live yet), rather than Google results. Drupal's views module allows you to hook into the submitted form data pretty easily and filter it however you'd like (in our case, using regular expressions).

Advancing the faith.

Matt Korger's picture

Ah, yes, I love regex. These are very nice, very powerful too. In my database work I always have to double check myself because sometimes I might replace "st" with "saint" instead of "st "(space) with "saint". Also this works well for your case but I've seen weird things like "saint st ans" in data, where this regex would make it "saint saint ans". For search results it's not bad because neither would produce the desired affects(correct search), but if you were running an update statement on a database it gets tricky since someone will view the results and think the update broke their data.

DJ Ortley's picture

Something that might be a tad bit more useful to work with than regular expressions would be to use the Levenshtein distance.

PHP has it built in (http://php.net/manual/en/function.levenshtein.php), PostgreSQL has a module that you can install to work with it and I believe MySQL has a module as well.

Of course, you're going to have to break strings up into lexical elements and do some normalization. So it would probably work well with a hash of some sort instead of any full text searches. I'm not sure how your data is being stored.

I don't know if soundex/metaphone/etc.. algorithms are that useful or not. Anybody have experience with these?

Also, I would wonder if 'St.', 'Saints', and 'Saint' should be considered stop words when considering titles of Catholic Churches. :) (that was a bit tongue in cheek.)

-DJ

Anonymous's picture

By any chance, do you know how to set up an exposed filter so that the exposed filter block appears on all pages of the website, but when the filter is used it then displays the modified view? Unless I'm on the same site as the view for the exposed filter, the block will take me to the homepage.

Open Source Catholic's picture

I haven't ever tried dong something like that; I don't know if that would be possible, unless you maybe created a view with a block with exposed filters, then set up a redirect that would send the exposed filter information to a page view.

Advancing the faith.

Christopher Stevens's picture

Thanks for sharing! This is just what I needed. :)