Friday, December 17, 2010

Create your own auto-complete control using JavaScript and asp.net web-service

Adding auto-complete to a textbox makes user life easy. User doesn’t have to type complete word which he is willing to type. Also its an added advantage to user experience. User expects a website to be fast and more user friendly and of course auto-complete is an user friendly option. There are many auto complete controls available to download for ex, autocompleteextender control in ajax control toolkit.

The disadvantage of using already built, third party control is lack of flexibility. You cannot edit and modify the code written by someone else until it is open source and code is available to download.

So how about creating our own auto-complete control for websites? It is cool, isn’t it?  Lets go ahead and create our own. What we need to do is to write some html, javascript and asp.net webservice(in case of programmers not using .net you can use ajax calls to methods which supplies array of string values to control). I’ll be using .asmx files, as it is more familiar. Speaking about webservices in .net is beyond the scope of this topic.

Enough theory, let me start with some code which you are willing to see here it goes.,

public class DbingleController
    {
DbingleContextDataContext currentcontext;
public DbingleController()
        {
            currentcontext = new DbingleContextDataContext();
       
        }

public List<string> GetWords(string searchingword)
        {
var words = currentcontext.SearchWords.Where(w => w.Word.ToLower().StartsWith(searchingword.ToLower()));
            List<string> wordslist = new List<string>();
wordslist = words.OrderByDescending(c => c.Count).Select(w=>w.Word).Skip(0).Take(10).ToList();
            return wordslist;
        }
    }
[WebMethod]
        public string[] GetWordsList(string querystring)
        {
            if (!string.IsNullOrEmpty(querystring))
            {
                DbingleController controller = new DbingleController();
                return controller.GetWords(querystring).ToArray();
            }
            return new string[0];
          
        }

GetWordsList is a method in webservice which we’ll be calling from javascript. It returns array of words from database starting with query string passed as method parameter. DbingleController is a class which speaks with database.It’s a linq class. Webservice calls method in Dbinglecontroller class which gets data from database. You can have your own database queried to return array of strings. At the end only array of strings matters.
Now how to call this webservice? To call webservice include the code in master page.

<asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true" EnablePartialRendering="true"  runat="server">
    <Services>
        <asp:ServiceReference Path="~/services/DbingleService.asmx" />
    Services>
    asp:ScriptManager>

Path is the path to your webservice.

In aspx page create a textbox and add an <ul> next to it, here is where you fill up array of strings to achieve auto complete.

                <asp:TextBox ID="QueryTextBox" AutoCompleteType="None" autocomplete="off" runat="server"
                    Width="429px" Height="25px" onkeyup="javascript:fillbox(event)">asp:TextBox>
<ul id="autocompleteextender" style="border: 1px solid; display: none; float: left;
                    list-style: none outside none; margin: 0 0 0 292px; padding: 0px; width: 431px; z-index: 1000;
                    background-color: White;text-align:left;">
                ul>

Finally, it’s time to write javascript and complete auto-complete.

<style type="text/css">
        .selecteditem
        {
            background-color: aliceblue;
            text-align:left;
        }
    style>
<script type="text/javascript">
          var textboxoriginalvalue;
          var arr = [];
          var downkeycount = -1;

          function fillbox(e) {

              var unicode = e.keyCode ? e.keyCode : e.charCode;
              if (unicode != 13) {

                  if (unicode != 40 && unicode != 38) {
                      var value = jQuery('#<%= QueryTextBox.ClientID %>').val();                     
                      textboxoriginalvalue = value;
                      getprediction();
                  }
                  if (unicode == 40)//down arrow
                  {
                      downkeycount += 1;
                      highlightword();
}
                  if (unicode == 38)//up arrow
                  {
                      if (downkeycount > -1) {
                          downkeycount += -1
                      }
                      if (downkeycount == -1) {
                          downkeycount = (arr.length - 1);
                         }
                      highlightword();                   

                  }
              }
          }

          function getprediction() {                            Dbingle.services.DbingleService.GetWordsList(textboxoriginalvalue, success, CallFailed);
          }
function success(res) {
              arr = res;
              fillwords();
          }
function CallFailed(res) {
              alert(res.get_message());
          }

          function fillwords() {
              var ulhtml = "";
              for (var i = 0; i < arr.length; i++) {
                  ulhtml += '
  • ' + arr[i] + '

  • ';
                  }
                  if (arr.length > 0) {
                      var ul = document.getElementById('autocompleteextender');
                      ul.style.display = 'block';
                  }
                  jQuery('#autocompleteextender').html(ulhtml);

              }
    function highlightword() {
                  $textboxitem = jQuery('#<%= QueryTextBox.ClientID %>');
                  jQuery('#autocompleteextender li').removeClass('selecteditem');
                  $listitem = jQuery('#autocompleteextender li:eq(' + downkeycount + ')');
                  $listitem.addClass('selecteditem');
                  if (downkeycount >= arr.length) {
                      $textboxitem.val(textboxoriginalvalue);
                      downkeycount = -1;
                  }
                  else {                 
                      $textboxitem.val(arr[downkeycount]);
                  }
              }
           script>

    On keyup event call fillbox(e) method of javascript, this method calls webservice to get array of strings starting with typed word and fills <ul>

    The line “Dbingle.services.DbingleService.GetPrediction(textboxoriginalvalue, success, CallFailed);” In getprediction() method calls the webservice [Dbingle.services] is a namespace [DbingleService] is a webserivce which you have added path reference in master page earlier. [GetWordsList] is method textboxoriginalvalue parameter passed to the method , the next two parameters are JavaScript methods which is called on success and failure of request respectively.
    A list objects are created with the array returned which are added to <u> and style property is changed.

    On press of up/down arrow key, fillbox(e) method is called which highlights and fills the value of text box with selected value. Once the end array is reached, the text box value is replaced with original user entered value.
    So now our autocomplete control is ready. Let’s see how it looks








    I created this control for my website www.dbingle.com

    No comments:

    Post a Comment