Calling JavaScript from VBScript

I’ve been working on a Classic ASP / VBScript website recently, so I have been brushing up against the limitations of VBScript again. Not hard limitations, like “you can’t do that”, just inconveniences like… no sort for you!

Rather than dust off my old copy of a sort algorithm, I figured the easiest way, and the path to best performance, would be to just…

Give up and use JavaScript

Unlike VBScript, JavaScript is a programmer-friendly language with all sorts of goodies like prototype-based object orientation, functional programming, and — specifically useful for the task at hand — a built-in sort function for arrays.

Best of all, your VBScript code can call your JavaScript code, and vice versa. There is a little extra handling necessary for some data, such as arrays, but otherwise it’s all pretty straightforward.

With one caveat: don’t write blocks of inline VBScript interspersed with blocks of inline JavaScript and expect them to run in order; they won’t. This is because the ASP parser runs JavaScript first, and VBScript second. However, that doesn’t matter if you’re just calling JavaScript functions or object methods from VBScript.

Why not write it all in JavaScript?

Indeed! It is a much nicer language for writing ASP programs. In fact, why not ditch ASP altogether and use PHP, or .NET, or $favouriteLanguage or $favouriteFramework?

That’s not the point. If you’ve got a large codebase written in VBScript ASP and it needs new functionality, it’s usually easiest to keep writing VBScript ASP.Then when the client needs someone else to work on the code, they can hire a VBScript programmer to add more new stuff.

Usually easier; but sometimes you can sneak in a little bit of JavaScript to just move things along a bit quicker (and any half-decent website programmer ought to be proficient in JavaScript by now!)

Just remember to preface your JavaScript code with this:
<script language="jscript" runat="server">
And end with this:
</script>

Sorting a Dictionary Object

My specific requirement was to sort the contents of a Scripting.Dictionary object. This dictionary is used to collate a pile of data resulting from multiple searches across multiple databases, and present it as if it were a single search. Great, and relatively easy, except that the dictionary object doesn’t have a method for ordering the data it holds.

So, here’s a little JavaScript function that accepts an unsorted dictionary and returns a sorted dictionary.

/**
* sort a dictionary object by its keys
* @param {Scripting.Dictionary} dict
* @return {Scripting.Dictionary}
*/
function sortDictionary(dict) {
    var i, len, key,
        newDict = new ActiveXObject("Scripting.Dictionary"),
        keys = new VBArray(dict.Keys()).toArray();

    keys.sort();

    for (i = 0, len = keys.length; i < len; i++) {
        key = keys[i];
        newDict.Add(key, dict.Item(key));
    }

    return newDict;
}

It’s short and fast. Here’s a quick summary of what it’s doing:

  • grab an array of the dictionary’s keys
  • sort the array
  • copy the data from the unsorted dictionary to a new dictionary, in order
  • return the new dict

The two key bits that allow this all to happen are:

  • VBArray — takes a SafeArray and wraps it up so that JavaScript can access it
  • .toArray() — a method on the VBArray object that returns a regular JavaScript array

Simple. Job Is Done.

Facebooktwittergoogle_plusredditlinkedinmailFacebooktwittergoogle_plusredditlinkedinmail