Classic ASP and AJAX

There aren’t many tutorials on the web for Classic ASP and AJAX interfaces. Classic ASP is just about fazed out at most companies, but there are still plenty of legacy applications that use it. There is a lot of confusion about AJAX and what it is. Mainly, it is a client-side application that sends data to a back end parser, and thus the back-end processor can be written in anything from asp to cfm to php to ruby/rails to java and even old-school perl cgi’s.

First and foremost, AJAX is a very simple concept. Get it out of your head that it’s complicated because its not.

Now, let’s get to it.
I was faced with the problem of performing a city and state look up based off an entered zipcode.
This is a simple database pull, but because the zipcode is like the 5th thing asked, and there’s more after it, it doesn’t make sense to go through a page reload process.

AJAX to the rescue.

AJAX uses 3 “sides” to make it happen.

  • an (x)HTML form or something along these lines
  • JavaSscript scripting to pass the http request and to receive the return response
  • and a server-side script or some other processor to ‘do the dirty work’ and return data back to the JavaScript that called it

First, grab this JavaScript function set. This can be found on just about every AJAX app or tutorial out there. I have added some tweaks to fit our application here.

var xmlHttp;
var rootpath;

rootpath = ""; // be sure to change this to your URL

function getZipcode(str)
var url = rootpath + "ziplookup.asp?zipcode=" + str;
//we'll do a GET lookup here to keep things simple. POST also works, but adds a bit extra to it that is not relevant for this example

xmlHttp = GetXmlHttpObject(stateChanged);"GET", url , true);

function stateChanged()
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")

function GetXmlHttpObject(handler)
var objXmlHttp=null;

if (navigator.userAgent.indexOf("Opera")>=0)
alert("Opera not supported...");
if (navigator.userAgent.indexOf("MSIE")>=0)
var strName="Msxml2.XMLHTTP";
if (navigator.appVersion.indexOf("MSIE 5.5")>=0)
objXmlHttp=new ActiveXObject(strName);
return objXmlHttp;
alert("Error. Scripting for ActiveX might be disabled");
if (navigator.userAgent.indexOf("Mozilla")>=0)
objXmlHttp=new XMLHttpRequest();
return objXmlHttp;

And the form (x)html:

Zipcode: " /> City / State:
(Enter Zip Code First)
" />
" />

Obviously, that would be a part of the larger table you are working with that has the name, address, and so on above it.

Notice the onkeyup command on the zipcode input box? When you release a key, it initiates the AJAX process. In our case, it calls ziplookup.asp and passes in “this.value” or, the entered zipcode.

so, what does ziplookup.asp do with it?

< % If Len(request("zipcode")) = 5 Then strCN = "Provider=SQLOLEDB.1;UID=XXXXXXX;Password=XXXXXXX;Persist Security Info=False;Initial Catalog=XXXXXXXX;Data Source=sqlbox1" Set Conn = Server.CreateObject("ADODB.Connection") strCN dim rst,bool,myval,citylist, statelist citylist = "" statelist = "" set rst=server.CreateObject("adodb.recordset") sSQL = "SELECT distinct city FROM [ZipCodes] where zip = '"& request("zipcode") &"'" Set rst = Server.CreateObject("ADODB.Recordset") rst.ActiveConnection = conn sSQL if not rst.eof Then citylist = citylist & ""
citylist = citylist & ""

While Not rst.eof
citylist = citylist & "" & VbCrLf

citylist = ""& VbCrLf
response.write citylist

response.write "No Record of this Zip"
end If

sSQL = "SELECT distinct state FROM [ZipCodes] where zip = '"& request("zipcode") &"'"

Set rst = Server.CreateObject("ADODB.Recordset")
rst.ActiveConnection = conn sSQL

if not rst.eof Then
statelist = statelist & ""
statelist = statelist & ""

While Not rst.eof
statelist = statelist & "" & VbCrLf

statelist = ""& VbCrLf
response.write statelist

response.write "" 'no need to echo it out twice...
end If

set rst = nothing
set conn = Nothing

response.write "Enter all 5 digits"
End if


The first thing we do is to check if the entered value is 5 digits. There is no use putting extra server load on the DB for something that will never be useful. So, we wait until there’s been 5 digits entered in the input box, then we run through our query.

Since there are more than 1 city with similar zip codes, and the possibility that a zipcode might NOT be in my table that i found on the net somewhere, I have given the option to enter in free-form as well. Selecting the drop down will auto populate the input for city and state.

That’s where our onchange functions come in handy.

Make sure you have your form id’ed correctly:

else, the DOM scripting won’t work.

function fillstate(str) {
var theform = document.getElementById("frmdefault");
theform.state.value = str;

function fillcity(str) {
var theform = document.getElementById("frmdefault"); = str;

Some old browsers don’t support these techniques, so keep this in mind. I built this in an all IE6 environment, so i don’t have to worry about browser differences. Editors Note: This article is several years old now and some concepts for browser testing likely has changed

The onkeyup event handler won’t do anything if JS is disabled by a user, so it’s a good idea to have a “graceful degradation” option a well, be it a button or other method to get the data back to the form– even if it requires a page load.

Well, there you have it. A nice and easy classic ASP AJAX example.

Get coding =0



  1. Very impressive and works a treat. Personally I would remove line ** If Len(request(“zipcode”)) = 5 Then … Else … End If** and use LIKE in the SELECT statement, i.e.
    SELECT distinct city FROM [ZipCodes] where zip like ‘”& request(“zipcode”) &”%'”
    This obviously creates more overheads but it’s nice to have and see all values being updated on every keystroke. UK zipcodes are different though so it may not be useful in US.

  2. beautiful and thank you
    any idea how i can retain the values selected from these dropdowns on submit?
    [when the user uses the browser’s back button they have to start over . . .]

  3. yukiandrews:

    The best thing to do would be to store a session variable for the zipcode on the following page.


    session("zipcode") = request.form("zipcode")

    and in your form, pre-populate the value for the zip code:

    " />

    And finally, in the footer somewhere, call the javascript to iniitate the query. Note, it’s important that this JS happens AFTER the form field is populated from the session variable (thus, a window.onload call in the head section will most likely be problematic)

    This is un-tested and off the seat of my pants, so there may be some errors and/or typos 🙂

    Hope this gives you some guidance. Good luck 🙂

  4. Thanks man, I am one of the ASP classic programmer (READ: dinosaur). Your post is vert useful to me. Keep up the good job!

  5. Brian, would it be possible to receive the complete source for your example here? I learn best that way. Thanks!

  6. ubigdummie,

    Unfortunately this was part of an intranet project at my last company where I am no longer employed. Thus, I don’t have access to the source code.

    However, I did some copy paste action and made a full page of the posted code. This is untested as I don’t have ASP or MSSQL on my blog webserver.

    I have added a link to the source in the orig post. Again, un-tested.

  7. Very great work my friend. You’re certainly right about one thing…barely any good documentation out there about Classic ASP and Ajax. Thumbs up to you!!

  8. After reviewing this post again, I’ve noticed a critical flaw. The query is subject to SQL Injection. Please be sure you are running a RegEx or some data parsing on all your variables that are entered into a SQL query like this.

    In this case for US-based 5-digit zipcodes, we should do something like this:

    <% Function digitsonly(teststr) dim isValid dim regEx isValid = True set regEx = New RegExp regEx.IgnoreCase = false regEx.Pattern = "^[0-9]{5}$" isValid = regEx.Test(teststr) digitsonly = isValid End Function zipcode = request("zipcode") if len(zipcode) = 5 then if digitsonly(zipcode) = false then response.write "bad data" response.end else 'do the query and the rest of the above ASP back end functions. end if %>

  9. Man thanks,
    I have looked all over the web from some guidance and I guess I finally entered the right keywords cause here it is. I only have one question. How much do you have to change the database call if you are using mySql instead of SQL server?

  10. SQL Server and MySql are 98% similar in T-SQL structure.

    The major differences are TOP vs LIMIT (ie, select top 2 from table in MSSQL vs select * from table Limit 2 in MySql), multi-phrase column name ticking (ie, backticks vs [] brackets, and group by’s are not as strickt in mysql. Other than a few other advanced techniques (triggers, etc) the syntax is very similar.

    In this particular example, the only thing that would need to be changed would be to change [zipcode] to `zipcode` (note, those are back ticks, not quote marks). You can also leave the ticks off completely as it is a single string (ie, the field name is not `zip code` with a space).

  11. We switched from ASP to AJAX last year and we’ve got lot of advantages: AJAX is quicker and more reliable than ASP.

  12. Mark, I think you’re mis-using one of the technologies then. AJAX is NOT a replacement for ASP or ANY server-side language. It’s simply the call method instead of traditional GET/POST.

  13. Thanks for this. Our entire website is vbScript/Javascript and I have no idea when it would change. This makes all sorts of things possible for us that weren’t an option using vbScript/Javascript/SQL alone.

  14. Hi. I wanted to drop you a quick note to impart my thanks. I’ve been observing your blog for a month or so and have picked up a heap of effective information as well as relished the way you’ve structured your site. I am attempting to run my own blog however I think its too general and I would like to focus more on smaller topics.

  15. This is such a great treasure to find! I’m getting into AJAX late in the game and was having a real difficult time with understanding how to get ASP data and use it with javascript, like it was a clash of two worlds. The instructions made it very clear – thanks.

    One issue I found is that the closing tags for the ‘input’ ASP value tags have a stray closing slash between the ‘%’ and ‘>’, as in:

    This prevented the page from loading until corrected.

  16. This is for XHTML compliance. It shouldn’t have any bearing on ASP parsing correctly.

    is 100% valid XHTML.

    is not.

  17. This is a great article! There are still legacy ASP apps out there which this works with amazingly well!! Thanks very much.

  18. I appreciate any classic asp information. There are more of us out there than anyone gives credit. I am getting a `permission denied` error when I begin typing into the text field. I have the connection string worked out with my ID/PW (and it works on other pages for this table), but I cannot figure out where this may be coming from… Any ideas? Thanks!!!


  19. Got the permission denied worked out by putting in the complete address rather than using the var url on line 17 of default.asp. But now it doesn’t do anything. It shows the form, but when text is input, nothing happens. Any ideas? Thanks!

  20. i run in dreamweaver cs5 this code but server error??
    this error:
    The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there was an error in a CGI script.

    can you help me???

Leave a comment

Your email address will not be published. Required fields are marked *