In today's article I will show you how to create your own Facebook-like (or LinkedIn-like) search box. If you haven't seen what it looks like, here is an example:
We will create an attribute and use it to decorate the action methods of our controllers. When we decorate an action, we will be adding metadata, such as the display name it should appear with in the search results and an optional icon. When the user types something in the search control, we will use jQuery to POST to a special controller, which will be enumerating all action methods in all controllers. While enumerating, it will be looking for a match between the search query and the metadata of each 'indexed' action method.
Note: You can download the working demo project from here.
Visit the project page here: http://yankov.us/#Projects
Ok, let's start with the attribute. In your Code folder (if you don't have one - go ahead and create it) add a new class and name it 'ActivitySearchAttribute'. It will have two string properties - Text and ImageUrl. Implement it like that:
This is the attribute we will be using to decorate our action methods in the controllers. That way we will mark them as 'searchable'.
Let's create a couple of dummy controllers, with a couple of actions in each of them and decorate them with the newly created attribute. Like this:
The Search Controller
Now let's implement the search controller. Basically, what it will be doing is: receive a query string (e.g. "the", as in the first image of this post), get all controllers, enumerate the action method of each controller, match the 'Text' property of the 'ActivitySearch' attribute (which we use to decorate the action) and then return an array of the matches with the appropriate URL to each result. Just like Facebook. I won't paste the code here, as it is big, but you will find it in the attached sample project. The file is in Controllers and is named "SearchController.cs".
The search will be a dynamic thing. While the user types, we will be sending a request to a controller and we will be receiving a response. We need to create a class which we will serialize to JSON and use it as a response. In your Code folder, create another class and name it 'ActivitySearchResultItem'. It will have three properties: Text, Url and Image. Implement it like that:
The Search controller will be returning an array of those, to the jQuery UI, as a JSON response.
Now, when we have the back-end, we just need to implement the front-end in jQuery and html. Note that our solution will be using a 3rd party library - jquery.autocomplete.pack.js
The auto-complete jQuery plugin will take care of attaching to the text-box and submitting/receiving data to/from the back-end controller. We just need to process and format the results. When the user clicks a result, he will be redirected to the URL property associated with the result item (see 'Json Response' above). Like that:
As you can see, the jQuery code expects that if there is an Image associated with the search result it should be in the /Content/images folder.
Here is how to setup your page which will contain the search-box control.
Now, when you have everything in place, start the project and just type in the search box some phrase which you know will hit a result. You should see something like:
The search results are clickable and when clicked, it will take you to the appropriate action. You can optimize the whole solution with various caching settings and techniques.
You can download the whole demo project here.