Thursday, October 04, 2007

Replacing the search bar

In this particular case, a customer already has a enterprise search engine so it wouldn't make sense of having two search engines crawling the same content. Therefore my task was to redirect the user with his search query to the page of that search engine. The fist thing that sprung into my mind on how to do this, was to modify the masterpage and remove the current searchbar with my own.

So I created the following HTML to simulate the look&feel of the default searchbar :

<table>
    <tr>
        <td class="ms-sbcell">
            <input name="InputKeywords" type="text" maxlength="200" id="InputKeywords" accesskey="S" title="Enter search words" class="ms-sbplain" alt="Enter search words"  style="width:170px;" />
        </td>
        <td class="ms-sbgo ms-sbcell">
            <a title="Go Search" href="javascript:Search()">
            <img title="Go Search" onmouseover="this.src='/_layouts/images/gosearch.gif'" onmouseout="this.src='/_layouts/images/gosearch.gif'" alt="Go Search" src="/_layouts/images/gosearch.gif" style="border-width:0px;" /></a>
        </td>
        <td class="ms-sbLastcell"></td>
    </tr>
</table>

Then I opened up our default.master and traced the following bit

 <asp:ContentPlaceHolder id="PlaceHolderSearchArea" runat="server">
    <SharePoint:DelegateControl runat="server" ControlId="SmallSearchInputBox"/>
  </asp:ContentPlaceHolder>

I replaced the DelegatedControl within the ContentPlaceHolder with my HTML (see below) and previewed it SharePoint Designer and there was my modified search bar! :)

<asp:ContentPlaceHolder id="PlaceHolderSearchArea" runat="server">
 <table>
    <tr>
        <td class="ms-sbcell">
            <input name="InputKeywords" type="text" maxlength="200" id="InputKeywords" accesskey="S" title="Enter search words" class="ms-sbplain" alt="Enter search words"  style="width:170px;" />
        </td>
        <td class="ms-sbgo ms-sbcell">
            <a title="Go Search" href="javascript:Search()">
            <img title="Go Search" onmouseover="this.src='/_layouts/images/gosearch.gif'" onmouseout="this.src='/_layouts/images/gosearch.gif'" alt="Go Search" src="/_layouts/images/gosearch.gif" style="border-width:0px;" /></a>
        </td>
        <td class="ms-sbLastcell"></td>
    </tr>
 </table>
</asp:ContentPlaceHolder>

It was a big suprise to find out that when I opened up the default.aspx page from a site where I applied the custom masterpage that my custom search bar was gone and the default search bar was there. I was lost for a couple of hours yesterday figuring this one out.. I tried a couple of things :

  • Adding my custom masterpage to a feature, as insisted by a mate of mine, and then deploy it to all the sitecollections. Found a very interesting link to do this Feature to Install a Custom Master Page by Paul Papanek Stork . But unfortunately that didn't do the trick either..
  • Modifying the default.master page on filesystem level (to make sure that my masterpage was being used (this was a desperate attempt to make it work:)) and reghosting the sitecollections to make sure the masterpage was being used.
  • Put some random text in other placeholders to see whether my customized masterpage were applied or not..

And it did! It did? Yes! So no more pulling my hair out because I couldn't apply a custom masterpage.. it was my modification! It seemed that a Content PlaceHolder not only holds the content you put into but it also generates some controls itself and overrides everything you put there yourself! When I placed my custom HTML out of the placeholder I was visible instantly. So I applied the Visible="False" attribute:

 <asp:ContentPlaceHolder id="PlaceHolderSearchArea" runat="server" Visible="false">
                <SharePoint:DelegateControl runat="server" ControlId="SmallSearchInputBox" Visible="false"/>
          </asp:ContentPlaceHolder>
             <table>
    <tr>
        <td class="ms-sbcell">
            <input name="InputKeywords" type="text" maxlength="200" id="InputKeywords" accesskey="S" title="Enter search words" class="ms-sbplain" alt="Enter search words"  style="width:170px;" />
        </td>
        <td class="ms-sbgo ms-sbcell">
            <a title="Go Search" href="javascript:Search()">
            <img title="Go Search" onmouseover="this.src='/_layouts/images/gosearch.gif'" onmouseout="this.src='/_layouts/images/gosearch.gif'" alt="Go Search" src="/_layouts/images/gosearch.gif" style="border-width:0px;" /></a>
        </td>
        <td class="ms-sbLastcell"></td>
    </tr>
</table>

And there you have it :)

I found some very interesting things while googling about this matter and those are :

Another approach how to incorporate another search engine within SharePoint (instead of leading your users to another search site (which is not very userfriendly, so I'm gonna see whether I can use this approach as well))

 

Technorati tags: , , ,

3 comments:

Paul Papanek Stork said...

Another approach to getting your code in place without replacing the masterpage would be to create a control Feature. Using a Control Feature with a Sequence numnber above 10,000 you should be able to load your code as a usercontrol into the SmallSearchInputBox. This is how the regular Search control is loaded. Since your Sequence number would be higher your control would be loaded last, overriding the default Search box.

Bryan said...

This is a great work around. I am currently facing the same problem. However, I have 2 primary focuses: 1. control rendered html and 2. get the search working after using your method.

Once I use your work around the search is not working. Can you explain how you got this part to work? thank!

Anonymous said...

thanks, but this guy says don't use this technique in 2010: http://mphacker.spaces.live.com/Blog/cns!8040CC624DDC5404!1016.entry