Quantcast
Channel: Coding in the cloud » Umbraco
Viewing all articles
Browse latest Browse all 10

Ajax-enabled search in Umbraco (using Examine and Razor)

$
0
0

I am about to implement an ajax-enabled search for an Umbraco site. Writing the prototype was quick (and fun) so I thought I’d share it. Here goes:

To make it work I have this search macro (run from my search page template):
Search.cshtml:

<form method="post">
<input type="text" id="searchstring" name="searchstring" value="@Request["searchstring"]"/>
<input type="submit"/>
</form>

<div id="searchresults">
@if (IsPost) {
  @RenderPage("SearchResults.cshtml")
}
</div>
              
<script type="text/javascript">
$(document).ready(function() {
    var content = $('#searchstring').val();
    $('#searchstring').keyup(function() {
        if ($('#searchstring').val() != content) {
            content = $('#searchstring').val();
            $.ajax({
               type: "POST",
               url: "/searchresults",
               data: "searchstring=" + content,
               success: function(msg){
                 $('#searchresults').html(msg);
               }
             });                                                                                      
        }
    });                           
});
</script>

Note that the script is using jQuery, which you will need to reference somewhere on your page.

And this macro to get search results (SearchResults.cshtml):

@using Examine
@using Examine.SearchCriteria
@using UmbracoExamine

@{
  var searchString = Request["searchstring"];
  if (!String.IsNullOrEmpty(searchString))
  {
    var searchProvider = ExamineManager.Instance.DefaultSearchProvider.Name;
    var searchResults = ExamineManager.Instance.SearchProviderCollection[searchProvider].Search(searchString, true);

    foreach (var c in searchResults)
    {
      <div>
        <h3><a href="@umbraco.library.NiceUrl(c.Id)">@c.Fields["nodeName"]</a></h3>
        @if(c.Fields.Keys.Contains("bodyText"))
        {
          var bodyText = c.Fields["bodyText"];
          if (bodyText.Length>100)
          {
            bodyText = bodyText.Substring(0,100);
          }
          <p>@Html.Raw(bodyText)</p>
        }
      </div>
    }
  }
}

And to get the search results for my Ajax post I simply have a template (searchresults):

<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" %>

<asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server">
 <umbraco:Macro Alias="SearchResults" runat="server"></umbraco:Macro>
</asp:Content>

Important about the Examine configuration

I’m using the ootb provided indexer (same as the backend) for this prototype. That’s easy to start with but not advisable for a real site, since it includes both unpublished and protected content.

Please read this article by Shannon Deminick about Examine and Razor.

Improvements

This works, but there are several areas of improvements which I am about to dive into. Suggestions are more than welcome!

* Better handling for the text change (javascript)
* Nicer display of content (examine / strings)
* Limit number of search results / paging

CoffeScript version of the js code

<script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>
<script type="text/coffeescript">  
  content = $('#searchstring').val()
  $('#searchstring').keyup ->
   currentContent = $('#searchstring').val()
   if currentContent!=content
     content = currentContent
     $.ajax({  
               type: "POST",
               url: "/searchresults",
               data: "searchstring=" + content,
               success: (msg) ->
                 $('#searchresults').html(msg)
           })
</script>


Viewing all articles
Browse latest Browse all 10

Trending Articles