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.
|
![]() |
Ken Spencer |
Building on the Intranet |
First, let's consider some potential issues with building intranet applications. The first step I took was to move the files I used last month into a subfolder of the Web site. Some of the files use the scripting object model (SOM) and generated the following error when I tried to view one of them in the browser: |
|
This error occurred because the file was moved to a subfolder in the site and the relative link to pm.asp was no longer valid. The link _ScriptLibrary/pm.asp should have been changed to ../_ScriptLibrary/pm.asp.
To check the code for the file, I opened it in the Visual InterDev code editor. Surprise! The editor sort of fixed the file. It did change the URL to the correct path, which eliminated the error, but also rewrote the header for the SOM code and placed it just after the first line in the file (the normal location for the SOM code). The trouble is, I had previously added Option Explicit as the second line in the file to force the definition of a variable before it is used. Option Explicit eliminates many subtle errors that creep into an application and, in my opinion, is a requirement for developing applications using VBScript or Visual Basic. When Option Explicit is used in a page and you try to use a variable that is not defined, it will generate the following error in the browser: |
|
This effectively traps all of your undefined variables when you test the page, and eliminates quite a bit of testing and troubleshooting.
Anyway, after the SOM code was rewritten by the editor, the page no longer worked because Option Explicit was located after the SOM block, triggering an error when the Option Explicit statement was executed. The only solution was to move the Option Explicit code manually back to the second line in the file. Beware of any changes you make to pages that may cause the SOM code to be rewritten. This causes problems when you try to use Option Explicit in ASP pages. The page directive must be the first line in the file and Option Explicit must be the second. Visual InterDev is smart enough to replace the page directive line if you remove it, so that does not eliminate this problem. Consider yourself warned. Errors due to the SOM code being rewritten occur when changes are made to the application and relative links in the SOM code are broken. Luckily the editor fixes these links, but in the process other problems can pop up. You may also run into similar trouble when you are using the Response object. Many of the Response object methods and properties must be used before any HTML is sent to the browser. For instance, using Response.Expires or Response.Redirect after any HTML tag will generate this error: |
|
When you see this, do not panic. Fixing it may be as easy as simply adjusting your code to move the lines ahead of the SOM code, or it may take a bit of programming. But if the page was working and then breaks, look at the location of the SOM code before you make any changes. If you perform any action that rewrites the SOM code, then you will have to modify the file so that your code comes before the SOM code.
Now let's take a look at building special features into your applications. I am often asked about certain techniques and how to use them to solve problems with Web applications. Often the answers to these questions come from unexpected places. Some of the answers are particular to Visual InterDev and its design-time controls (DTCs), while others are actually based on simple HTML features that can solve particular problems. I should also mention for developers who are new to Visual InterDev that the various ASP objects are still quite handy for your applications. One often-overlooked feature is the Response.Expires method mentioned previously. Response.Expires sets the expiration time for a page in minutes. If a user visits a page a second time before the page expires, the page will be displayed from the browser's cache. On pages that are built from a database and have time-sensitive information, you can cause a page to expire immediately by using the following code: |
|
This will make sure that the user is always seeing the latest data, not old data from the cache. Using Tables and Grids It appears to me that the most often-used features of a Web application are table and grid displays. This includes using either generic HTML/DHTML tables like the one I used last month or using tools like the Grid DTC that automatically generate HTML/DHTML tables. I'll will show you how to put some neat features into your application using the Grid DTC. These features can also be added using standard HTML tables, but that would require much more work to add record-scrolling features. First, let's look at adding a feature to your application that is similar to tooltips in Windows®. During a recent Visual InterDev course, one of my clients asked how to add this type of feature to his Web application. Tooltips are used frequently in Windows, and would be great to add to many applications to make them more intuitive and require less support. For instance, when you display data in a table, it would be handy to let users point at a field or row and be able to see more information about the item. One example of this would be building a table so a user could point at the name of a contact and then the application would display the contact's title and phone number. Hmm. This type of technology could be extremely useful in many different areas. To demonstrate this feature, I created a new page to use with my application from last month. This page, Product.asp, will display a table showing product information from the database. The interface is simple. The grid displays the basic data on products, as shown in Figure 1. The page uses the Header.inc file from last month to insert the NorthWind Traders logo. |
![]() |
Figure 1: Table with Product Information |
To create the page, I added a Recordset DTC and pointed it at the NorthWind database. The SQL for the recordset is: |
|
Next, I added a Grid DTC and selected the columns shown in Figure 1. I also unchecked the "Fixed column width" box on the Format property page for the grid. This allows the table to automatically size itself at runtime based upon the width of the data. Once you have created these settings, close the properties, save the page, and test it by viewing the page in the browser. Your results should be similar to Figure 1, except your page will not yet have the "Sorted by" line in the header.
To add the tooltip support, you need to adjust the code for the column that will contain a tooltip. To generate the tooltip, I'm going to use a bit of HTML code that creates an anchor tag without a link. The syntax of this anchor tag is: |
|
This tag will display the "anchor name" value when the page is viewed. If the user places the mouse over the text, the value in the Title attribute will display, creating the tooltip effect.
To add this support to the grid, open the properties for the grid and click the Data tab. Next, select the CompanyName column in the Grid columns section of the property page. Click on the CompanyName column and enter the following code in the Field/expression box: |
|
This seemingly complex bit of HTML will display the company name for the user and place the contact name and title behind the company name as a tooltip.
If you do not enter the HTML syntax correctly, you may see the following error when you view the page in the browser: |
|
This error is referenced in Knowledge Base article Q191974 and occurs because a single quote is in the expression or header for a field. The preceding error was generated because I missed a quote in the expression. If you need to output a single quote in an expression, then use two backslashes to prefix the quote. For instance, you may need to create an expression like Name's with a quote in it. To accomplish this you must use this syntax: |
|
You can also change the font or color of a specified column to let users know it is different. For instance, to change the data with the tooltip to bold and italic, you can use the following code in the Field/expression property: |
|
Now let's take a look at another useful feature. A question often asked during my Visual InterDev course is how to let users sort the items in a table like they would in Microsoft® Outlook®. This really provided some food for thought since the client was using the Grid DTC to generate the table. If the page was using only HTML, you could hyperlink the headers in the grid and sort the grid that way. You could also use an ActiveX® control that provided this functionality, but that has its own issues. In this case, the client really wanted to use the Grid DTC, but also wanted to add this functionality.
Well, a little bit of testing turned up the solution. To sort the grid, you simply use expressions in the header box of the grid. The first step in adding sorting was to create links in the header of the grid back to the page. This allows the user to click the header to sort a column. To add the links, open the properties for the grid and display the Data property page. Next, in the Header property for each column, add the following code: |
|
For each column, change the Sort variable to the name of the column to sort on for that particular column. The name of the anchor (ProductID in this case) will be displayed as the column header. Figure 2 shows the Data property page with the header code highlighted. |
![]() |
Figure 2: Data Property Page |
When the user clicks on a header, the browser will navigate back to Product.asp. The query string sort variable is set to the column name to sort on, providing a way to detect the user's requested sort order.
At this point, you need to add a few more features to the page to implement the sorting functionality. First, drag a PageObject from the Toolbox and add it to the page. This object will come in handy as you begin to add code to the page. Next, drag two label controls and drop them immediately after the Current Products header. The labels will be used to provide feedback on the current sort mode. Open the properties for the first label and set its Field/expression property to "Sorted by". Change the name to lblSortHeader. Open the properties for the second label and change its name to lblSortOrder and set its Field/expression property to blank. The label controls are used instead of HTML text because they are addressable in ASP code. Next, open the Recordset DTC properties and display the Implementation page. Uncheck the "Automatically open the recordset" property. From this point on, the script code in the page will control the recordset. Save the changes and close the properties. To manage the sort status, you need to create a variable that is available to your code outside of the current page. You have two choices: Session variables or a PageObject property. I chose the latter because I prefer not to create a slew of Session variables in an application, as it tends to confuse other developers and lead to problems down the road when the variable names and purposes have long been forgotten. To create a PageObject property, open the property pages for the PageObject and display the Properties page. Enter one new property, set its name to ProductPageMode, and set its Lifetime property to Page. This will create a property that lives with the page and not the session. Close the property pages when you have completed the entry. Now you can begin to add the script to drive the page. First, add an event handler for the OnEnter event for the PageObject. The easiest way to add this event is by using the Script Outline. Expand the Server Objects and Events folder, then double-click the OnEnter event to add the event handler code block to the page. The first bit of code for this page defines two variables. Place the Dim statement just after the script definition for the server event handlers: |
|
These variables are defined outside the subroutine code to make them global and allow their use outside of the script block, if needed.
Now you can begin to create the code for the page. The first thing that happens in the OnEnter event is the startup code for the page. This is the code that runs only the first time the user visits the page and is implemented with an If block that checks the firstEntered property of the page. The default sort order for the recordset is ProductID, so the first time the user visits the page this code sets the caption of the label DTC to Product ID. Notice that setCaption is a method and not a property. Next, the recordset is opened, and finally the page variable (ProductPageMode) is set to blank. |
|
The balance of the code in the page manages sort requests by the user. The following line sets the SortMode variable to the Sort QueryString variable: |
|
If the SortMode is not blank, the following if statement executes the code to sort the recordset: |
|
The if statement also checks the ProductPageMode variable against the SortMode variable and only sorts the recordset if they do not match. If you do not check for this match, the sort will work on each column, but the grid's navigation buttons will not work correctly.
Next, the caption of the label is set to the value of the current SortMode variable: |
|
The following line retrieves the current SQL from the recordset DTC: |
|
Now you can add the order by clause and the column to sort to the SQL: |
|
Next, the recordset is closed and the new SQL is set to its CommandText property using the setSQLText method, as shown in the following code: |
|
Finally, the recordset is reopened and the ProductPageMode property is set to the current SortMode variable, and the if statement and subroutine block are terminated: |
|
Now you should be able to save the page and test it. Make sure you try sorting each column and use all the navigation features. If you do not thoroughly test this page, you may think it works fine, but a major piece such as navigation may not work at all. Conclusion
There are a tremendous number of issues to deal with when building Web solutions. Many times users or developers need to implement features that are common to other applications, such as those created with Visual Basic, but are hampered by HTML or other browser issues that do not support these features. Sometimes you can easily build in the features yourself, but there are other times it's a bit harder to make this work. |
From the July 1999 issue of Microsoft Internet Developer.
|