Custom search box for a specific content type

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.

Achieving the above with hook_form_alter

greg.harvey - February 14, 2008 - 15:59

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:

<?php
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.

JS too

greg.harvey - February 14, 2008 - 18:13

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'.

Anonymous must be permitted to advanced search

greg.harvey - February 15, 2008 - 10:57

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.

Even better approach

greg.harvey - February 15, 2008 - 13:00

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

<?php
/**
* 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.

where i write this code

bharanikumariyerphp - July 16, 2008 - 06:03

Hi dears thank u

Where i write this for code,

shall i write in block.tpl

or in my custom module

Easier

greg.harvey - July 16, 2008 - 12:01

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/

need search in custom block

bharanikumariyerphp - July 16, 2008 - 17:33

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,

 
 

Drupal is a registered trademark of Dries Buytaert.