To read the article online, visit http://www.4GuysFromRolla.com/webtech/071999-1.shtml

Using the Page Object in your Components

By Bruno Carlos (Substancia Lda - www.substancia.com)


Introduction

Note: This article was supposed to be on Wrox's ASP Today, but after two months waiting they replied saying it was a hack instead of a trick. Well, hack or not it does the job and it's the only way of doing it as far as I know.

I develop all my ASP in JScript and like every programmer that reuses his code I started creating a set of ASP libraries to manage Recordsets, Date/Time, Math, etc. The library got so powerful and big that some pages had about 900 lines of ASP code. Imagine the load on the server each time I had to use just a simple function of the libs. That's when I decided to convert all my scripting code to a Visual Basic ASP component in DLL format.

The good thing about a VB Component is that it's really easy to make your previous code work on it even if it's in JScript. The bad thing is you have to forget some stuff you took for granted like the eval function. That made me almost quit the project but, at the same time, it also made me try harder to find a solution for the problem.

The ideia and concept

One thing I found is that you can pass the Page Object to the Component from ASP (I decided to call it the Page Object since I never found any reference about it so far). How do you do it? Using the this keyword of the JScript language or the Me keyword when in VBScript.

Though it works with VBScript the rest of the article will focus on using JScript because of its power to evaluate string expressions, something that VBScript only introduces in version 5 and not everyone has this version installed (you can get VBScript 5 from the Microsoft Scripting Site).

Don't forget you have to be working in Server Side JScript for this to work:

    obj=Server.CreateObject("4guysfromrolla.Article");
    obj.Init(this);

Now on the VB Class:

    Public page As Object

    Function Init(ByRef page As Object)
        Set Me.page = page
    End Function

For those of you that use VBScript you can do it using the Me keyword in the ASP Page:

    obj.Init(Me)

Using the Page Object

Now you have the page variable in the Active X DLL pointing to the Page Object of the ASP page itself. From now on you can call whatever you want with the page Object from the DLL like if you were in the ASP page. You can use it in your component to call functions and access objects that you have in your ASP page, including functions that are intrinsic to the JScript language like parseInt, eval, etc:

Example: Using the Response object:

    page.Response.Write("Hi mom, I'm using the page Object to make a Response.Write!!!")

To simplify things you could assign the page.Response object to a variable in your Component code (don't forget to make a reference to Active Server Pages Object Library in your project) :

    Public Response As ASPTypeLibrary.Response

Now In the Init function:

    Set Response = page.Response

You can also add variables for the other built-in ASP Objects like Request, Server, Session, etc.

Before, you could only access this objects using the Scripting Context or the GetObjectContext() function. Now, using the Page Object, you not only have access to those objects but also to custom ones like variables you create:

Example: Getting a value from a ASP variable:

In the ASP page:

    var testing = 150;

In the DLL:

    Response.Write( page.testing )

If that wasn't enough you are even allowed to call functions not available in Visual Basic (like eval):

Example: Using the eval function:

    Response.Write( page.eval("testing+50"))

Take in consideration that the eval function runs in the asp page context. That means that any object you refer to must be know by the asp page.
That's why in the last example the testing variable in the string to be evaluated doesn't need to have the page object before it, the asp page only knows the variable as testing.

If you need to evaluate expressions in your VB ActiveX components that's a great way of doing it without having to install other 3rd party components. Of course it will only work if you use the component in asp pages.

A real scenario

Now, for a real life case. Suppose you want to run a variable expression using the values of a Recordset. In VB you would have to hard code the expression not giving much power to the component. In the following example (which is included in the article material) you'll see how easy it is to interact with Recordset values and display them the way you want.

Let's begin by creating a Recordset without a Data Store, also know as a Data-Boundless Recordset. I won't get into much detail about this since it was already discussed and I'll present the shortest code to do it:

In the ActiveX Component:

    Public rs As New ADODB.Recordset

    rs.CursorLocation = adUseClient
    rs.Fields.Append "Name", adVarChar, 100
    rs.Fields.Append "Site", adVarChar, 100
    rs.Open
    For x = 1 To 3
        rs.AddNew
        rs("Name") = "Site" & x
        rs("Site") = "http://www.site" & x & ".com"
    Next
    rs.Update

What I just created was a Recordset with two Columns (Fields). The first column has the Site Name and the second the Site URL. For demonstration It is filled with 3 Rows (Records) of automatic generated data.

If you wanted to display the Recordset in a HTML Table you would get something like this:

<table border="1">
<TBODY>
  <tr>
    <td><b>Name</b></td>
    <td><b>Site</b></td>
  </tr>
  <tr>
    <td>Site1 </td>
    <td>http://www.site1.com </td>
  </tr>
  <tr>
    <td>Site2 </td>
    <td>http://www.site2.com </td>
  </tr>
  <tr>
    <td>Site3 </td>
    <td>http://www.site3.com </td>
  </tr>
</TBODY>
</table>

So far you're displaying static content. But you wanted to create a third column that would have custom content, for example a link to each site (I'll skip the code to display the table and the values of the Recordset):

In the ActiveX Component:

    Function table(str As String)

        rs.MoveFirst

        While Not rs.EOF
            Response.Write (page.eval(str) )
            rs.MoveNext
        Wend

    End Function

In the ASP Page:

    obj=Server.CreateObject("4guysfromrolla.Article");
    obj.Init(this);
    obj.table("'<a href=' + obj.rs('Site') + '>' + obj.rs('Name') +'</a>'");

The result of this would be:

<table border="1"> <TBODY> <tr> <td><b>Name</b></td> <td><b>Site</b></td> <td><b>Link</b></td> </tr> <tr> <td>Site1 </td> <td>http://www.site1.com </td> <td><a href="http://www.site1.com">Site1</a></td> </tr> <tr> <td>Site2 </td> <td>http://www.site2.com </td> <td><a href="http://www.site2.com">Site2</a></td> </tr> <tr> <td>Site3 </td> <td>http://www.site3.com </td> <td><a href="http://www.site3.com">Site3</a></td> </tr> </TBODY> </table>

All I had to do was pass a string that gets evaluated in the VB Component with page.eval(str). Actually, it gets evaluated in the ASP Page. That's why I had to make reference to the obj variable in the string. Also notice that the string is in JScript syntax since it is evaluated by JScript and not VB.

In the article material you will find additional samples using individual radio buttons for each row. Additionaly you can start building a powerful Recordset object from here. You can have a Recordset bound to a database and then add additional Columns with code to be evaluated each time you display a its contents in a table. This is an ideal approach for Shopping Carts systems where you want to display Columns with buttons that can remove or change the Basket.

A Problem and its solution

The only problem you may face is that VB doesn't know the name of the variable obj itself. And you probably would be interested in evaluating expressions that made reference to the object itself. For example:

In the VB Component:

    Response.Write( page.eval("obj.rs('Site')") )

The above code works fine if you named your variable obj in the ASP Page. But now let's suppose you changed the name of the variable in the ASP page. It just wouldn't work because JScript wouldn't find the object. The workaround here is to pass the name of the variable you created along with the Init Function:

In the ASP Page:

    obj=Server.CreateObject("4guysfromrolla.Article");
    obj.Init("obj", this);

And in the Component:

    Public page As Object
    Public name As String

    Function Init(name As String, ByRef page As Object)
        Set Me.page = page
        Me.name = name
    End Function

Now, even if you change the name of the object you always know its name so you can use the eval function like this in your component:

    Response.Write( page.eval(Me.name & ".rs('Site')") )

Conclusion

Though the Page Object is a powerful tool to make your Component coding more flexible you have to bare in mind that it will be tightly integrated to the Scripting language you use. For instance, If you use functions only available to JScript your Component will fail to run when calling it from VBScript, or at least part of it. If you are a programmer that is still not sure what scripting language to use you will face a few problems in the future when using this way of doing things.

On the other side the Page Object brings new ways of expanding and not getting stuck in a particular problem. Use it wisely and your components will make things not thought possible before. In this article we only accessed the ASP built-in Objects like Request, functions like the eval function, and some variables created in the asp page itself. But you're not limited to that and the power of the Page Object is that you're only limited by your imagination. With time you will discover how this simple ideia will help you in your projects.

In the article material you'll find the source for the Visual Basic ActiveX DLL that you can compile (or then just use regsvr32 to register the included dll). You will also find a sample ASP page that uses the component. Good luck.

You can contact me regarding this article at bruno.carlos@substancia.com


Attachments:

  • The contents of this article in ZIP format


  • Article Information
    Article Title: Using the Page Object in your Components
    Article Author: Bruno Carlos
    Published Date: Monday, July 19, 1999
    Article URL: http://www.4GuysFromRolla.com/webtech/071999-1.shtml


    Copyright 2017 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers