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 is anything from asp to cfm to php to old-school perl cgi's.
First and foremost, AJAX is VERY easy. Get it over 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 entered zipcode.
This is a simply database pull, but because the zipcode is like the 5th thing asked, and theres 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.
- HTML form or something along these lines
- JS scripting to pass the http request
- server-side script or some other processor to return data when its called.
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 = "http://path.com/to/root/location/"; // be sure to change this to your URL
- function getZipcode(str)
- {
- var url=rootpath + "ziplookup.asp?zipcode=" + str
- xmlHttp=GetXmlHttpObject(stateChanged)
- xmlHttp.open("GET", url , true)
- xmlHttp.send(null)
- }
- function stateChanged()
- {
- if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
- {
- document.getElementById("citystate").innerHTML=xmlHttp.responseText
- }
- }
- function GetXmlHttpObject(handler)
- {
- var objXmlHttp=null
- if (navigator.userAgent.indexOf("Opera")>=0)
- {
- alert("Opera not supported...")
- return;
- }
- if (navigator.userAgent.indexOf("MSIE")>=0)
- {
- var strName="Msxml2.XMLHTTP"
- if (navigator.appVersion.indexOf("MSIE 5.5")>=0)
- {
- strName="Microsoft.XMLHTTP"
- }
- try
- {
- objXmlHttp=new ActiveXObject(strName)
- objXmlHttp.onreadystatechange=handler
- return objXmlHttp
- }
- catch(e)
- {
- alert("Error. Scripting for ActiveX might be disabled")
- return
- }
- }
- if (navigator.userAgent.indexOf("Mozilla")>=0)
- {
- objXmlHttp=new XMLHttpRequest()
- objXmlHttp.onload=handler
- objXmlHttp.onerror=handler
- return objXmlHttp
- }
- }
And the form (x)html:
- <form id="frmdefault">
- <tr>
- <td class="txtright">Zipcode:</td>
- <td class="txtleft"><input name="zipcode" type="text" id="zipcode" size="6" maxlength="5" onkeyup="getZipcode(this.value)" value="<%=request.cookies("OD")("zipcode")%/>" /></td>
- </tr>
- <tr>
- <td class="txtright" valign="bottom">City / State:</td>
- <td class="txtleft">
- <div id="citystate"><span class="hilite">(Enter Zip Code First)</span></div>
- <div id="citystate2">
- <input class="hilite" type="text" id="city" name="city" maxlength="50" size="15" value="<%= request.cookies("OD")("city") %/>" />
- <input class="hilite" type="text" id="state" name="state" maxlength="2" size="3" value="<%= request.cookies("OD")("state") %/>" />
- </div>
- </td>
- </tr>
- </form>
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")
- Conn.open 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
- rst.open sSQL
- if not rst.eof Then
- citylist = citylist & "<option value="""">Select City"
- citylist = citylist & "<option value="""">---------------</option>"
- While Not rst.eof
- citylist = citylist & "<option value="""& rst(0) &""">"& rst(0) &"</option>" & VbCrLf
- rst.movenext
- Wend
- citylist = "<select onchange=""fillcity(this.value);"" name=""selcity"">"& VbCrLf & citylist &"</select>"& VbCrLf
- response.write citylist
- Else
- response.write "<span class='hilite'>No Record of this Zip</span>"
- end If
- sSQL = "SELECT distinct state FROM [ZipCodes] where zip = '"& request("zipcode") &"'"
- Set rst = Server.CreateObject("ADODB.Recordset")
- rst.ActiveConnection = conn
- rst.open sSQL
- if not rst.eof Then
- statelist = statelist & "<option value="""">Select State</option>"
- statelist = statelist & "<option value="""">---------------</option>"
- While Not rst.eof
- statelist = statelist & "<option value="""& rst(0) &""">"& rst(0) &"</option>" & VbCrLf
- rst.movenext
- Wend
- statelist = "<select onchange=""fillstate(this.value);"" name=""selstate"">"& VbCrLf & statelist &"</select>"& VbCrLf
- response.write statelist
- Else
- response.write "" 'no need to echo is out twice...
- end If
- set rst = nothing
- set conn = Nothing
- Else
- response.write "<span class='hilite'>Enter all 5 digits</span>"
- 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:
- <form id="frmdefault">
- </form>
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");
- theform.city.value = str;
- }
Also, 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.
The onkeyup will fail if JS is disabled, so its good 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
Source:
asp_ajax_skeymedia.zip
10 comments
2 years and 5 months ago
Good Stuff...
Sholom Sandalow
2 years ago
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.
1 year and 8 months ago
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 . . .]
1 year and 8 months ago
yukiandrews:
The best thing to do would be to store a session variable for the zipcode on the following page.
formactionpage.asp:
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
1 year and 7 months ago
Thanks man, I am one of the ASP classic programmer (READ: dinosaur). Your post is vert useful to me. Keep up the good job!
1 year and 6 months ago
Brian, would it be possible to receive the complete source for your example here? I learn best that way. Thanks!
1 year and 6 months ago
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.
1 year and 4 months ago
nice thing ... i thought you might be interested in an Ajax Library for classic ASP (ajaxed). Check http://www.webdevbros.net/ajaxed/
there are still guys around hacking classic ASP
1 year and 4 months ago
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!!
1 year and 3 months ago
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:
Write a comment
If you want to add your comment on this post, simply fill out the next form:
* Required fields
You can use these XHTML tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>.
No trackbacks
To notify a mention on this post in your blog, enable automated notification (Options > Discussion in WordPress) or specify this trackback url: http://skeymedia.com/classic-asp-and-ajax-tutorial/trackback/