How does it work?
Gavi Narra (12/24/2004)
Concept
As you type a word in the textbox, a javascript event fires and a HTTP GET request to the ASPX page. The response from the ASPX page is simply displayed in a div tag under the textbox. The page is not refreshed/reloaded for every keystroke as everything is done by the javascript in the page. The main javascript object that allows us to do this is XMLHttpRequest. You could read about it from Apple's developer site here . This is supported by IE 5.0 +, Mozilla 1.0 + and Apple's own Safari 1.2 + .
Database
The database contains just one table. The data comes from a freely available online dictionary (a public domain English word list dictionary, based on the public domain portion of "The Project Gutenberg Etext of Webster's Unabridged Dictionary" which is in turn based on the 1913 US Webster's Unabridged Dictionary. You could download it from here). The table is called WordList
| WordList |
| Word varchar(255) |
| Type varchar (10) |
| Meaning text |
I created an index on "Word" column for speed. There are a total of 182696 words
in the database.
ASP.NET page
The ASP.NET page is pretty straight forward. Gets the top 10 matching rows from
the database and spits it out. Below is the code i am using(Although
SqlDataReader might be more appropriate)
<%@Page Language="C#"%>
<%@Import Namespace="System.Data"%>
<%@Import Namespace="System.Data.SqlClient"%>
<%@Import Namespace="System.Configuration"%>
<script runat="server">
public void Page_Load(object sender,EventArgs args)
{
string keyword=Request["k"];
if(keyword!=null && keyword.Trim()!="")
{
string sql="select top 10* from WordList where word like '"+keyword.Trim().Replace("'","''")+"%'";
SqlConnection conn=new SqlConnection(ConfigurationSettings.AppSettings["connectionString"]);
conn.Open();
DataTable dt=new DataTable();
SqlCommand command=new SqlCommand(sql,conn);
SqlDataAdapter adapter=new SqlDataAdapter(command);
adapter.Fill(dt);
conn.Close();
foreach(DataRow row in dt.Rows)
{
string meaning=row["Meaning"].ToString();
Response.Write("<strong>"+row["Word"].ToString()+"</strong> <i>");
Response.Write("row["Type"].ToString()+"</i>: "+meaning+"<br>");
}
}
}
</script>
XMLHttpRequest object in the HTML page
<html>
<head>
<script>
var req;
function Initialize()
{
try
{
req=new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
req=new ActiveXObject("Microsoft.XMLHTTP");
}
catch(oc)
{
req=null;
}
}
if(!req&&typeof XMLHttpRequest!="undefined")
{
req= new
XMLHttpRequest();
}
} function
SendQuery(key)
{
Initialize(); varurl="http://www.objectgraph.com/dictionary/dict.aspx?k="+key;
if(req!=null)
{
req.onreadystatechange = Process;
req.open("GET", url, true);
req.send(null);
}
}
function Process()
{
if (req.readyState == 4)
{
// only if "OK"
if (req.status == 200)
{
if(req.responseText=="")
HideDiv("autocomplete");
else
{
ShowDiv("autocomplete");
document.getElementById("autocomplete").innerHTML =req.responseText;
}
}
else
{
document.getElementById("autocomplete").innerHTML=
"There was a problem retrieving data:<br>"+req.statusText;
}
}
}
function ShowDiv(divid)
{
if (document.layers) document.layers[divid].visibility="show";
else document.getElementById(divid).style.visibility="visible";
}
function HideDiv(divid)
{
if (document.layers) document.layers[divid].visibility="hide";
else document.getElementById(divid).style.visibility="hidden";
}
function BodyLoad()
{
HideDiv("autocomplete");
document.form1.keyword.focus();
}
</script>
</head>
<body onload="BodyLoad();">
<form name="form1">
<input name="keyword" onKeyUp="SendQuery(this.value)" style="WIDTH:500px" autocomplete="off">
<div align="left" class="box" id="autocomplete" style="WIDTH:500px;BACKGROUND-COLOR:#ccccff"></div>
</form>
</body>
</html>
The keyup event on the textbox triggeres the SendQuery method. Note that we are disabling the autocomplete feature so it does not overlap with our div tag. The initialize method creates the XMLHttpRequest object. In Mozilla and Safari you could simply do this by using
req=new XMLHttpRequest();
In IE, you could create the object based on the users installtion of MSXML libraries. The Process method acts as an event handler and displays the response text once the response is complete from the webserver.
Observations
- The response from the database is fast for the time being , but a connection is being opened for every keystroke and is not a good idea(/. will definitely bring it down).
- Google Suggest is probably running by having all the suggestion words in main memory and a custom webserver that does nothing else (Although this concept isvery easy to implement in C# )
- Roundtrips from the webserver should be minimal (2K max) as it might eat up bandwidth pretty fast.