I wanted to make a custom search box on my site that would only search a single content type, with results identical to if the user had done an advanced search and selected one content type only. The code below works perfectly for me. Replace "your_content_type" with the content type to which you'd like to restrict the search.

<form action="/search/node" method="post" id="search-form" class="search-form">
<div class="form-item">
<input type="text" class="input-text" value="" size="25" name="keys" />
<input type="submit" value="Search" name="op" title="Search" alt="Search" />
<input type="hidden" value="<?php print drupal_get_token('search_form'); ?>" name="form_token" />
<input type="hidden" value="search_form" id="edit-search-form" name="form_id" /> 
<input type="hidden" name="type[your_content_type]" id="edit-type-your_content_type" value="your_content_type" />
</div>
</form>

Good luck. I hope someone finds this useful.

Note that there are some modules which can also let you search within a type although the interface/setup would be different: Search Type and Views Fastsearch.

Comments

greg.harvey’s picture

You can change the default search block to duplicate this behaviour and then retain it on the search page with hook_form_alter within a module like this:

function your_module_form_alter($form_id, &$form) {
  switch ($form_id){
    case 'search_block_form':
      $form['type-your_content_type']['#value'] = 'your_content_type';
      $form['type-your_content_type']['#type'] = 'hidden';
      $form['type-your_content_type']['#name'] = 'type[your_content_type]';
      $form['#id'] = 'search-form'; 
      $form['form_id']['#id'] = 'edit-search-form';
      $form['form_id']['#value'] = 'search_form';
      $form['#token'] = 'search_form';
      $form['form_token']['#default_value'] = drupal_get_token('search_form');
      $form['basic']['inline']['keys'] = $form['search_block_form_keys'];
      $form['basic']['inline']['keys']['#class'] = 'form-text';
      unset($form['search_block_form_keys']);
      $form['basic']['inline']['submit'] = $form['submit'];
      unset($form['submit']);
      break;
    case 'search_form':
      $form['type-your_content_type']['#value'] = 'your_content_type';
      $form['type-your_content_type']['#type'] = 'hidden';
      $form['type-your_content_type']['#name'] = 'type[your_content_type]'; 
      break;
  }
}

This effectively auto-checks Advanced options, even if they are not displayed.

greg.harvey’s picture

I also wrote this little piece of JavaScript to strip off the potentially unwanted "type:your_content_type" string(s) in the resulting search box:

function hidefilters(field_id) {
  val = document.getElementById(field_id).value;
  newval = val.replace(/( [a-zA-Z]*:[a-zA-Z0-9_-]*).*/, '');
  document.getElementById(field_id).value = newval;
}
hidefilters('edit-keys');

Important note: if you expose the search block on the same page as the search form and set their ids to the same, then you need to change the block keys field ID to something different or the above won't work. There will be two input fields with the id of 'edit-keys'.

conceeche’s picture

Gred, can you tell in which file I have to insert this function?

thanks

Conce

greg.harvey’s picture

There's a far better way. You can use form_set_value() ... this is the start of a brain fart on the matter:
http://twitter.com/greg_harvey/status/15957787351

But I haven't taken it any further. Others maybe have. It ought to be a module.
Doing this with JavaScript is not the correct approach, anyway.

greg.harvey’s picture

IMPORTANT NOTE! Since this approach hard-codes Advanced Search options in to hidden fields in the search form, to use the above approach, all users needing to search *must* have access to Advanced Search options. Sounds obvious, but thought I'd mention it.

Obviously, if it is not desired to expose Advanced Search options to some roles, you can always use hook_form_alter to unset the options in the search form for those roles.

greg.harvey’s picture

Fellow Drupaler and developer on the project I'm working on today, Marek, suggested this in your module:

/**
 * Rewrite search query to search only within product node types
 */
function your_module_db_rewrite_sql($query, $primary_table, $primary_field, $args) {
  if ($query == '' && $primary_table == 'n' && $primary_field = 'nid' && empty($args)) {
    return array('where' => " n.type IN ('your_content_type') ");
  }
}

Much better than faffing around with blocks, hook_form_alter and JavaScript! =)

One proviso though. In this simple form this is only viable if you only *ever* want your users to be able to search one content type. You could, of course, wrap it in a role look-up, so restrict anonymous users to searching in one (or more) content type(s) and allow all other roles to search all content.

bharanikumariyerphp’s picture

Hi dears thank u

Where i write this for code,

shall i write in block.tpl

or in my custom module

greg.harvey’s picture

My code is unnecessary. Easiest way to deal with this is install this module:
http://drupal.org/project/search_config

It puts advanced options in admin/settings/search to allow you to configure the search forms and indexes. =)

--
http://www.drupaler.co.uk/

bharanikumariyerphp’s picture

Dear

How to add the search box into custom block, assume event is the custom block,

I that am displaying the posted events,

i want to add the search box into this custom event block,

How to i add that search box into the custom block,

also one thing that search must search only the events posted, not other content type,

crabcakes’s picture

I realize the original post was old but I am having the following problem in 6.13 and views2

http://drupal.org/node/611942

Any idea?

drupal_flash’s picture

I am trying a start a blogging site similar to http://www.tripadvisor.com/. Where i can search for the blogs posted by the other users, things like i could customize the searching criteria - lets take the example - someone wants to find a blog for a ritz restaurant london - they can start their search with the restaurants - then it will expand into - which city - type of restaurant - i could not find much of the help from the web - i am just a beginner in drupal but have a little experience in ASP search form

itzramona’s picture

I have a similar requirement, and was wondering if you found a solution to your scenario?

puya’s picture

I think the Search Type module might just be the thing for you..

khanz’s picture

Try Custom search it's a pretty good module..

http://drupal.org/project/custom_search

------------
Volvo, Video, Velcro. (I came, I saw, I stuck around.)

asb’s picture

Sadly, custom_search does neither allow to hide the search form on search results pages, nor to hide the advanced search parameter :-(

AlexandreSantos’s picture

thanks man,

this work for me.

rajesh_1988’s picture

Hi all,
I created one content type module(using code address book).using this i can create list of person of address book content type.
i have created one view page to display address book .this view give me list of all my post of address book content type.here i want to create search box.

Can any body tell me how can i do this.
i have created address_book.module address_book.info and address_book.install file.
is this code useful for me? how can i use this?

ubdr’s picture

How can we display a search form, that have filters for each field of the required content type only in drupal 7?

winawer’s picture

We have 3 ways:

1. Install custom_search module.

2. Do it with exposed filters of views. here is video tutorial for it:
http://www.youtube.com/watch?v=cAtFDkFsm_Q&feature=relmfu

3. Do it with code. here is tutorial for it:
http://envisioninteractive.com/drupal/build-a-drupal-7-content-type-sear...

stoptime’s picture

Seems to work perfectly in D7 - thanks!