Home Blog JavaScript Creating an AJAX AutoComplete using Prototype and JQuery with no conflict
Creating an AJAX AutoComplete using Prototype and JQuery with no conflict
JavaScript
Written by Dicky   
Friday, 11 November 2011 13:47
AddThis Social Bookmark Button

I was looking for a robust, simple and elegant solution to create an AJAX autocomplete that will query database. I landed on this 10 cool Auto-Complete scripts article. After weighing my options, I choose Ajax Autocomplete for Prototype due to its simple and clean look.

I heard so much about Prototype JavaScript Framework but never really use it so I think it would be cool to try it on. So at first, I need to create a service page that will take the query and return the dataset in JSON format. For simplicity and fast response, I use classic ASP as my service page. In order to create the JSON datatype, I use aspjson library. Here's what I have on my ASP page.

<% @LANGUAGE="VBSCRIPT" CODEPAGE="65001" %>
<!--#include file="JSON_2.0.4.asp"-->
<%
Function QueryToJSON(dbcomm, params)
        Dim rs, js
        Set rs = dbcomm.Execute()
        Set js = jsObject()
        js("query") = params(0)
        set js("suggestions") = jsArray()
        set js("data") = jsArray()
        Do While Not (rs.EOF Or rs.BOF)
                js("suggestions")(Null) = rs("cname")
                js("data")(Null) = rs("catalogid")
        rs.MoveNext
        Loop        
        Set QueryToJSON = js
        rs.Close
End Function
%>
<% 
   strConn = "Provider=SQLOLEDB;Data Source=<your server>;Initial  Catalog=<catalog>;User  Id=<userid>;Password=<password>"
  Set conn = Server.CreateObject("ADODB.Connection")
  conn.Open strConn
  searchParam = Request.QueryString("query")  
  query = "SELECT top 10 * FROM products with (nolock) WHERE cname like '" & searchParam & "%'"
  arParams = array(searchParam)
  Set cmd = Server.CreateObject("ADODB.Command")
  cmd.CommandText = query
  Set cmd.ActiveConnection = conn
  QueryToJSON(cmd, arParams).Flush
  conn.Close : Set Conn = Nothing
%> 

I call my page seachJson.asp. You can always test whether it's working or not by going to http://localhost/searchJson.asp?query=li. Make sure you fill out your database information on the code above and put your file under C:\Inetpub\wwwroot so it will be processed by IIS.

On the other hand, here's my test page:

 <html>
<head><title>test ajax</title>
<script type="text/javascript" src="/js/prototype-1.7.0-mod.js"></script>
<script type="text/javascript" src="/js/autocomplete-mod.js"></script>
<link rel="stylesheet" type="text/css" href="/styles.css" />
</head>
<body>
<input type="text" name="keyword" id="keyword" />
<script type="text/javascript">
  new Autocomplete('keyword', { 
  serviceUrl:'searchJson.asp',
  minChars:2,
  maxHeight:400,
  width:300,
  deferRequestBy:100,
  // callback function:
  onSelect: function(value, data){
     window.location = "product.asp?id=" + data;
  }
});
</script>
</body>
</html>

You may notice that I don't use the original prototype-1.6.0.2.js and autocomplete.js that you can download from here. This is because if I use the original implementation, it will clash with my existing pages that uses a lot of JQuery functionality. It's not possible for me to redo so many pages that use JQuery by using the .noConflict() method since it will takes too much time to modify all the pages.

So what I did is modifying the Prototype.js framework to use $$$() instead of $() based on the suggestion in this article. And I use the latest 1.7.0 version (at this time of writing) compared to 1.6.0.2 where it actually get rid of all the $$() function. I also modified the autocomplete.js so that it will use the prototype $$$() constructor instead of $() where it will clash with JQuery and causing my .ready() function not functioning with JQuery and gives the following error: $ is not defined $(document).ready(function(){

After all that, I found one more issue. My local toggle() JavaScript function is not working! After do more research, I found out it clashes with the toggle() function on Prototype framework. I have to delete the toggle() function in the Prototype framework since my local toggle() function do much more than toggling the class, I can do this safely because I know that the autocomplete.js does not use toggle() function on Prototype. You can also change your function name to something more unique if you don't want to delete the toggle() function in the prototype. Learned lesson: try not to use a generic function name when creating a local JavaScript function.

So finally I got everything working. If you are interested with the modified Prototype.js and autocomplete.js which uses $$$() instead of $(). You can download it here and play around with it yourself. Have fun!