ajaxed: Calling server side VBScript procedures from client side (equivalent to PHP xajax)

My last post (about an ASP RSS component) included a demonstration which made use of a cool ajax technique simply called “ajaxed”. See the demonstration here again. If you play around you will recognize that there is no conventional postback and AJAX is up in here I have developed a small “library” which easily allows you to call server side ASP VBScrtipt procedures from the client side. No low-level Ajax knowledge is required…
Summarized it can be said that I have developed a bit similar thing for ASP like there is already for PHP (xajax – http://www.xajaxproject.org/). It is not the same as xajax but it also allows you to call server side procedures from client side. We are all tired of the conventional postbacks which refresh the whole page, thats why we want ajax. I was tired of hacking all the lowlevel stuff for ajax and thought of a way to call the ASP procedures directly. With this and some stuff of my existing gabLibrary I have built a small library called “ajaxed”. ajaxed just because it makes my pages ajaxed. Here is a very simple example which sums up two numbers (Try the demo here):

At first sight you can see that the calculation is done on server side (“add” function) and there is no classical XHR and not much JavaScript. The calculation is invoked through the button and therefore the button includes a JavaScript call which defines the “gateway” to the server side. Before I explain how the execution works, it is necessary to look at the page structure. The structure of an ajaxed page (as shown in the example) is the following:

Loading ajaxed.asp (include)

Create an instance of the AjaxedPage class and execute draw()

Provide 3 methods:

init(): executed on every request (before main() or callback())

main(): executed when the page is ordinary called by a user

callback(): executed when the page calls itself again and requests a server side method (action)

The execution flow results as followed:

init()

main() or callback()

The whole trick here is that the page is able to make a request to itself. It has two states. One for the ordinary request of the user – which normally displays the user interface with (X)HTML. The other state is when the page requests itself again – which results in a JSON response. Ok lets forget the underlying technical details now…

The entry point in the example is the draw() method which draws the page and cares about everything for you. As already mentioned you need to provide the procedures init(), main() and a callback(action) in your page. Whereas init() is executed on every request the main() and callback() are never executed togehter. All the presentation should be put in the main() – you see the form in the example is in the main(). All security checks, preperations, initializations, etc should be put into the init() which is always executed before the main() and callback(action). When is the callback called? It is called if the ajaxed.callback JavaScript function is executed – which in this case is in the onclick event of the button. The ajaxed.callback requires an action (which is used as input for the server side callback function) and a JavaScript callback function which will be called after the server side process has been finished. This callback function (added) gets then the return of the server side function call. In this case with page.return(). The nice thing is that the page handles all conversions from the VBScript datatypes into the JavaScript equivalents (see Generate JSON from ASP datatypes if you are interested in the details). The page posts all form variables by default to the callback which means that the form fields are accessible via request.form within the callback. The AjaxedPage class offers several convenient utility methods to access the request collection. If you dont want to post the whole form or use your own parameters for the callback, you can use the third parameter of the ajaxed.callback function (with JSON). E.g.

With this technique its now possible to call all your server side procedures and then change the DOM according to the return value(s) from the server side. There is no need to care about any XHR or e.g. loading indication. Everything is handled. Another example?

Populating dropdown from the database

Lets assume we have a table called “table” which holds two columns named “id” and “name”. We want to fill a dropdown with those values. id as the value and name as the displayed text. I have created a form which holds dropdown and a button. The button invokes the database call on server side. The callback then returns an ADODB.recordset which is automatically converted into an equivalent JavaScript data structure. The “got” JavaScript function can directly access the recordsets data. (Note: the “getRecordset” function does not exist and is just for demonstration)

The following example demonstrates that it is also possible to return more values on the callback. returnValue() allows to return more values by specifying each value with a name. return() in comparision can only return one value.

(It expects some value in the textbox. if no value is given then a “valid” flag is set to false and returned from server side. If some input is provided then an array additionally to the valid flag is returned. This example make not much sense but demonstrates the usage of more return values)

The concept makes use of Prototype JavaScript Library and the JSON utility class.
The ajaxed library includes those and therefore they can be used when working with ajaxed e.g. all features of Prototype. Furthermore it offers other convenient built-in features to ease the work with ASP pages (e.g. RFHas() method in the example above – it checks if agiven field from the request.form collection exists). Some other features of the Ajaxed page …

AjaxedPage.isPostback() – equivalent to asp.net postback

AjaxedPage.throwError() – generates an ASP user error

AjaxedPage.RFT() – gets a field from the request collection already trimmed

AjaxedPage.RFE() – gets a field from the request collection HTMLEncoded

AjaxedPage.loadJSFile() – ensures that JavaScript file is loaded only once

AjaxedPage.iif() – an VBScript inline if

AjaxedPage.getLocation() – gets the location of the page in several formats

Download the zip archive and copy the whole “ajaxed” folder into your web root. Access the demo at http://yourserver.com/ajaxed/demo/index.asp and check if everything works fine. There is a config.asp which provides some configurations.

Tell me what you think about it. I will come up with some more sophisticated examples in the future. cheeers…

ah you mean JScript I dont think that this is possible. I never accessed VBScript code from JScript within one page and so i am not sure if this is possible. I have set up a small example now but it didnt work. So i guess you cannot really use it with JScript.
Maybe if there are some ASP JScript Pro’s around, they could help.

Looks like u r inspired from ASP.net callback mechanism,
But avoided view state and page reconstruction at server side.

Good, leaving aside heavy features of asp.net and using the valuable features of asp.net.

BUT..
Yes this BUT is very much important,
Your scripts are vulnerable, can be easily exploited.

If you could proceed further and do something on security front so that you could validate the client side requests, then it would be really nice,
See to criticize u is not my motto, i find something can be improved, and i just pointed it out..!! that’s it.

@Tanmay: thanks very much for your feedback. i am really interested in the vulnerability. could you explain it more detailed. I am not sure what you mean.
If you mean that it is possible to call the callback state of the page directly. That is true but thats not a vulnerability because you should validate on server side what output you want to return and what not.
Thanks for your participation…

Eyal,
It is (as far as I know) impossible to use a VBScript class inside of Jscript for two reasons. 1. JScript can not directly create a VBScript object, though it can call a VBScript function which could return an object. Calling a function does not work either, however, because of the order that the languages are processed. Try this:

Response.write(“This is JScript”)

When you see the output, the order is reversed. This is because all JScript is run first (not 100% true but that’s the simplified explanation) and the output sent to the browser before any VBScript is executed.

I believe the reason that function definitions are available and class definitions are not has something to do with the Object Dispatch mechanism inside ASP, but I’m not enough of a fan of Microsoft to get into that mess too deeply.

Hi! This looks like a very nice addition to classic asp.
I’ve placed it on a few pages, and notice that page.RF or Request.Form variables sometimes remain empty on a callback. I haven’t figured out what exactly drives this behaviour, but on some pages the elements are empty.
At first I thought it may be the formid, and then noticed that the constant AJAXED_FORMID is not used anywhere.
Could it be a matter of setting this?

I’ve noticed that some malformed html will cause trouble. The form I was submitting was not within a proper table structure (it had some extra trs and tds from previous code) and was thus causing trouble. Now all works well and I’m impressed and will impress others!
thanks for the great addition!

Great tool! exactly what I’m looking for. I’m having one problem though. I’m calling from within a longer validation script, and I need it to return true or false to the script that is calling it. Like this

I use the checkstatezip to access the database and do a check on whether the state matches the zip code. Then statezip returns the prompt to enter a valid prompt or not, and returns true or false. Problem is, that true or false is not bubbling up to validatePurchPage2. What am I doing wrong?

I stumbled across ajaxed, and what a good asp-script. Now there is even less reason to use .Net stuff. But there is a problem with the latest protoype 1.6.0. If I replaec the prototype.js with the latest, the callbacks stop working. Do you have a new version or patch going? Keep up your good work !

How can i get the contents of another page using this library. e.g. i am on a default.asp and want to embed the results of specials.asp (with few parameters) on this page. At the moment, i am using the iframe. want to remove this and instead want to display the results in a div on default.asp

humble ajaxed uses prototypejs as the javascript library … thus you can use al its ajax facilities.. in your case it would be the Ajax.Updater .. doc can be found here: http://www.prototypejs.org/api/ajax/updater
basically you would use it like this:

hey pete … i know the documentation sucks a lot but its getting better. there are no tutorials for the datatable yet because it is not in an official release … i will release the next version soon but i think the datatable wont make it into the next one … its not finished yet .. paging and filtering is still missing.
if u have some specific question then post them on the google group … you will get answers quick as the documentation lacks

I am updating one of my pages and need to acces a large number of form variables. Previously I have always passed all the values I need to access as parameters. e.g.

This allows me to use p.RF(“passedrecvalue”) to get the value of the changed field

However I now want to use the values from about 6 other form fields. From reading I thought I could use r.RF(“Any other form element name”) to access their value. However they are always null. However if I stop passing parameters e.g.

with the callback I can access all the form elements using e.g. p.RF(“City”) etc. As soon as I pass parameters I can’t.

Is this the expected behaviour or should I be able to pass parameters and access form elements?

I have read this a few times and realise that the biggest problem with the example is the lack of HTML to show the proper page markup. Not having the statement etc makes it harder to understand what is Server side and what is Client side.

Hey just wondering how I would use JSON data with this. Here’s the deal, it will be a flash site that requires a user to enter a participation code that validates against a JSON data file. The user goes through the site answering a few questions and the answers append the JSON data file. So I need some sort of asp processing layer.