This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.
|
Download the code (6KB) |
Ken Spencer |
Advanced PageObjects |
This month I'll look at how you can use the PageObject to expose methods that can be accessed by other pages. The sample application that I'll use ties database actions in one page to a function that performs a different database action in another page. The resulting application interface is shown in Figure 1. |
Figure 1: The Customer Information Page |
This page uses the Visual InterDev 6.0 data environment and several design-time controls to provide the key database interface. The user can scroll through the page using the navigation controls at the bottom. When the user clicks the Get Order Total button, the application retrieves the total dollar amount for all of the customer's orders from the server. The PageObject provides the functionality for retrieving that information. Let's take a look at how this page was constructed.
Creating the Base Functionality
|
|
I used a Data Command object to create the recordset. If you prefer, you can drop a Recordset design-time control on the page directly. Next, add Textbox design-time controls that will be used to display the values for each field. For each textbox, open its properties and set the Recordset property to the name of the recordset you created in the last step. Set the Field property to the name of the field that control will display, then apply the changes. You can save time by placing all the controls on the form first. Then open the properties for the first one, change them, and click Apply instead of OK. Then you'll be able to click the next control in the editor and the property page will change to display the properties for that control. Repeat this process for each control. Next, place a RecordsetNavBar design-time control on the page. Drop this control after the last Textbox design-time control. Open the properties for the control and change the Recordset property to the recordset you created earlier. This completes the basic functionality for the page. Now save the page and view it in the browser to make sure it works correctly. Now you need to add the PageObject design-time control to the page. The PageObject will do two things. First, it will let you store the current customer ID and expose it as a property for use in other pages. Second, when you create methods on this page, the PageObject control will let you access them from a separate ASP file. To add the PageObject control, drag it from the toolbox and drop it on the page after the other controls that are already there. Open the PageObject, click the Properties tab, and add the property CustomerID. The property page should look like the one shown in Figure 2. When it does, click OK to close the property pages. |
Figure 2: PageObject Properties |
Now, click the Source tab of the editor to display the page in source view. Open the script outline by clicking the appropriate tab under the toolbox or by selecting View | Other Windows from the menu. Open Server Objects & Events and find your Recordset object. Open it and double-click the onrowenter event. This will enter the event block in the page. Next, change the event to look like this: |
|
This code sets the CustomerID property in the PageObject to the current CustomerID from the current row in the recordset. This event fires each time the recordset changes to a new record.
Adding the Order Total Method
|
|
This statement links the Orders and Order Details tables. It also creates an expression named LineItemTotal. The expression is created using this syntax: |
|
You can create the expression by entering the first part of the statement (up to the AS) as the Column property in the grid pane, then entering LineItemTotal into the Alias column. This returns LineItemTotal as a field in the recordset, making it unnecessary to do the math in your function. In fact, you could calculate the orders completely in SQL, but I've chosen to do it in the recordset to demonstrate how to walk through it in your ASP code. An "= ?" entry in the Criteria column sets this up as your parameter for this query. This will let you pass in the CustomerID value to the query after the user selects a customer. You can see the criteria and the entire SQL statement in Figure 3. Next, let's create your method. First, create a script block in your code. You can enter the <% and %> tags directly into code, or right-click in the page where you want the script block and select Script Block from the shortcut menu. Next, select Server to insert the code block. Now, you can generate the header for the GetOrderTotalByCustomer function. This function can take one parameter, the CustomerID: |
|
Wouldn't it be nice if you could make this function generic so it could be called from many different places? You can do this by allowing for different types of parameters (see Figure 4). I'll walk you through it step by step. First, dimension a variable named lTotal in GetOrderTotalByCustomer. Next, insert an If…Then statement into the code. This block of code checks the parameter that's passed to the method. If the parameter is blank, the code tries to pull the value for sCustomerId from the CustomerID property you created in CustomerdInformation.asp. If this value is also blank, the code looks in the querystring and form variables for a value. This extra checking provides a lot of robustness to the method. Once the code finds a valid CustomerID, it performs its logic on it. The Open method executes the SQL statement you embedded in the Recordset object, creating the actual recordset like this: |
|
Once this is open, you can start looping through the recordset with a Do while…Loop block: |
|
The next line pulls the LineItemTotal from the recordset and adds it to the lTotal variable you dimensioned earlier: |
|
Next, the code moves through the recordset with the MoveNext method. After tallying all the LineItemTotal values, the Loop statement completes the operation: |
|
The last line in the GetOrderTotalByCustomer method sets the method name equal to the lTotal counter: |
|
Now you need to let other pages use this method. To do this, you must export the method with the PageObject in one of two ways. You can make the method available as an Execute method that can be used only from client-side scripts. You can also export a method as a Navigate method. This second choice lets both client and server-side scripts execute the method. When you export a Navigate method, executing it causes a jump to the page that contains the method. It can perform its processing, then move to another page, or simply display the page containing the method. An Execute method will simply execute without navigating to another page. Let's export the method I just created as an Execute method. |
Figure 5: Selecting a PageObject Method |
First, drag a PageObject design-time control from the toolbox and drop it on the page after the code I added earlier. Open the Properties dialog (see Figure 5) and select the method you created from the Execute method list. That's it! The method's now exported. Now you need to create a reference to the CustomerdInformation.asp file. This reference will let your method access the CustomerID property. To reference another page, click the References tab, then click the … button next to the first entry in the Name column. Select CustomerdInformation.asp, and close the Create URL and the PageObject properties dialogs. When you've completed these steps, save the page.
Using the Method
|
|
The first statement executes the method in your ASP script. The method call passes in the customer ID that you are using in this page (thisPage.getCustomerID). It also passes in the name of another method (displayCustomerOrderTotal), which I'll show you how to create in a moment. The second line of code disables the cmdGetOrder button to prevent the user from clicking it again before the method completes. The displayCustomerOrderTotal method will execute when the server method completes. This is known as asynchronous execution because the client application does not wait for the server method to complete before it continues to the next line of code. Instead, the client application continues with its tasks and lets the user interact with it. When the server method completes, it will execute displayCustomerOrderTotal, which is known as the callback method because it is called when the server method completes. The code for this method is: |
|
When the displayCustomerOrderTotal method executes, it takes the return value from the server method, which is stored in the retObj object that was passed in as a parameter. This value is displayed on the page by setting the Value property of the HTML textbox. The second line enables cmdGetOrder, so the user can execute it again. You do not have to use a callback method. Instead, you can execute it synchronously using this syntax: |
|
However, the callback method is helpful when you execute methods on the server that contain database code. If the code takes an unexpectedly long time to execute, the user is not locked into waiting for it. The user can continue to work on other features in the page until the server code returns.
You should provide feedback to the user by disabling the button. This lets the user know that something is happening
in the application.
Conclusion
|
From the January 1999 issue of Microsoft Internet Developer.