I am using drupal 6 with views 2. I want to create a single textfield which should search multiple fields. The results should be 'Or' operator based. e.g. given 'science' as textfield value, it should match in multiple columns of given table (i.e search in organization, name, etc). The result should show all records where organization contains 'science' OR name contains 'science'.

In views, the filter uses 'And' operator. Is there a way to change the operator to 'Or'? If it is possible through another module as in 'views or' module, i would prefer the module to be in stable version as it would be deployed as production site.

Expecting early response...

Comments

padmashree’s picture

I want this functionality for 'Users' also which is different than Node. I mean, I should able to search multiple user columns (name, organization,etc) through single textfield. This type of view is created by choosing 'user' as view type at first step of creating a view.

geerlingguy’s picture

Project: View » Views (for Drupal 7)
Version: » 6.x-3.x-dev

I think you meant 'Views' ;-)

dawehner’s picture

Currently you can only use multiple columns with a single textfield if you write code for your own.

Alternative to this kind of custom stuff you could also use some kind of search module like the apachesolr module.
This indexes multiple fields so if you search for it you get different results.
Together with the apachesolr_views module there is no problem to use all kind of flexibility of views.

geerlingguy’s picture

Version: 6.x-3.x-dev » 7.x-3.x-dev

I've been scouring the web and drupal.org for clues as to how I can write some code for a custom handler/filter that does this, but I'm running into dead ends pretty much everywhere; the only ways that seem like they would work would be hacks, and I'd rather avoid that if possible.

Views 3 has built in OR functionality for its filters, so I was thinking of making three fields in an OR group, and somehow merging them, but I can't do that either...

merlinofchaos’s picture

When I do this manually, I use a textfield and some custom code to put all the data I need into that one field. Then a simple search on just that field works. It's kind of like creating a cheap keyword index attached to the node. Works a lot better than trying to OR stuff together.

geerlingguy’s picture

Do you do this through a custom field added to the view through PHP (basically, generating the data to be searched on-the-fly), or do you have a separate field attached to an entity that you search (like a field combining [first] [last] [email] [phone])?

geerlingguy’s picture

I've tried my hand at hook_views_query_alter, and I find that it allows me to get most of the way there.

In my use-case, I want to search a user's realname, email address, and a profile field, 'field_profile_phone', with one text field.

Implementing hook_views_query_alter() has allowed me to (so far) add in the user's email address... I'm going to also work on adding a relationship to the user's phone field... I'll report back with any progress made.

/**
 * Implements hook_views_query_alter().
 *
 * Allow users to search by a user's full name, email address, or phone number.
 */
function custom_views_query_alter(&$view, &$query) {
  if ($view->name == 'my_view_name') {
    // Get the keyword used for the search.
    $keyword = isset($_GET['name']) ? $_GET['name'] : '';
    $query->where[1]['conditions'][] = array(
      'field' => 'users_flag_content.mail',
      'value' => '%' . $keyword . '%',
      'operator' => 'LIKE',
    );
  }
}

In my case, I used dpm($query) to explore the query a bit, and find the tables I could use to create conditions. In the views UI, I had set up two views filter groups, the first one standard filters like 'node.status = 1', etc., and the second a simple realname exposed filter using an OR union. Then, in the code above, I also add the condition to join to the users table on the mail field.

Seems to be performant enough in my case, though I will definitely be moving towards using Apache Solr for searching in the future (can't wait to see what Views 3 + Solr has in store!). Just don't have the time for that now.

merlinofchaos’s picture

I use a separate field attached to the entity.

geerlingguy’s picture

In lieu of adding duplicate data to the database, at the expense of a little speed in the views query, I've used hook_views_query_alter() to accomplish search on multiple fields by adding another JOIN/table and two WHERE clauses to the query. See the final code below:

/**
 * Implements hook_views_query_alter().
 */
function custom_views_query_alter(&$view, &$query) {
  // Allow users to search by a user's full name, email address, or phone number
  // in the list_subscribers view.
  if ($view->name == 'list_subscribers') {
    // Get the keyword used for the search.
    $keyword = isset($_GET['name']) ? $_GET['name'] : '';

    // Add a WHERE clause for the user's mail.
    $query->add_where(1, 'users_flag_content.mail', '%' . $keyword . '%', 'LIKE');

    // Strip dashes and parentheses from the entered text if first character is
    // a parentheses or number user is entering a phone number.
    if (!empty($keyword[0])) {
      if (is_numeric($keyword[0]) || $keyword[0] == '(') {
        $keyword = preg_replace('/\D/', '', $keyword);
      }
    }
    // Add a new LEFT JOIN and WHERE clause for the user's phone number.
    $join = new views_join();
    $join->construct('field_data_field_profile_phone', 'users_flag_content', 'uid', 'entity_id');
    $query->table_queue['users_flag_content__field_data_field_profile_phone'] = array(
      'table' => 'field_data_field_profile_phone',
      'num' => 1,
      'alias' => 'users_flag_content__field_data_field_profile_phone',
      'join' => $join,
      'relationship' => 'users_flag_content',
    );
    $query->add_where(1, 'users_flag_content__field_data_field_profile_phone.field_profile_phone_number', '%' . $keyword . '%', 'LIKE');
  }
}

If someone would like, I could write more details about the process and purpose of the code in a blog post, or in docs somewhere. I find questions about multiple-field search all over the web, with very few (and mostly hackish) answers that don't reliably work from Views version to version.

dawehner’s picture

What you actually want is to implement all this logic in a real handler. It's much more flexible and reusable.

geerlingguy’s picture

@dereine - In looking around for documentation and good examples, I found very little... Most of the articles and docs I could find were for Views 2, and some things have changed in Views 3. I would like to use a handler for this, as I'm going to need to add this behavior to a few other fields here and there.

Can you point me in the right direction? Even if you could just give me some class references to look up and how they should work together, I may be able to make more progress.

dawehner’s picture

@dereine - In looking around for documentation and good examples, I found very little... Most of the articles and docs I could find were for Views 2, and some things have changed in Views 3

Okay caught. You didn't tried to get it working ... because this kind of api didn't changed at all between views2 and views3 :)

The normal filter class is probably a good starting point: views/handlers/views_handler_filter.inc Additional some more complex examples would perhaps help you as well. The complicatest one i can think of is views/modules/search/views_handler_filter_search...

Something like views/modules/views_handler_filter_node_status.inc could give you some informations as well.

geerlingguy’s picture

Okay, sounds good! I will dig into those examples and work through things.

kars-t’s picture

Status: Active » Fixed

Hi

I am closing this issue to clean up the issue queue. Feel free to reopen the issue if there is new information and the problem still resides. If not please make sure you close your issues that you don't need any more.

Maybe you can get support from the local user group. Please take a look at this list at groups.drupal.org.

Status: Fixed » Closed (fixed)
Issue tags: -views, -OR

Automatically closed -- issue fixed for 2 weeks with no activity.