WSS Form Views and the XML View Descriptor


If you want to display a list of items for a folder inside your Web application, you don't have to write the code for this functionality. WSS Forms lets you place a view control inside your HTML pages that you can customize via parameters to display the items in your folder. This view control is similar to the view control you see in OWA. The view control also supports rich clients such as Internet Explorer 5.0 and later (which can use DHTML and XML) as well as HTML 3.2 clients such as Internet Explorer 4.0 or Opera. The key thing is that you do not have to know what type of browser is attempting to access the view. The view control automatically detects the browser and displays either a rich view for rich clients or an HTML 3.2 view for HTML 3.2 clients . Also, the view control has built-in grouping and sorting capabilities, and you can filter based on queries and customize the user interface.

Adding a View to a Web Page

The first thing you'll want to do when you add a view to your Web page manually is to declare an XML namespace in your HTML. You can do this by adding the line <HTML XMLNS:wf> . Next you specify a WF:VIEW tag as follows :

 <style>   @media all {     WF\:VIEW { BEHAVIOR:url("exchweb/controls/wfview.htc") }   } </style> 

As you can see, the view control is actually an HTC. HTCs are script-based components . For example, wfview.htc, which is usually located where you installed Exchange Server ( drive :/program files/exchsrvr/exchweb/controls/), contains code that declares properties, methods, and events for the HTC and some script that implements those properties, methods , and events.

The next step is to actually insert the view. You do this by dropping a WF:VIEW tag into your code. The following code shows all of these elements combined to display a simple view:

 <html XMLNS:WF> <STYLE>   @media all {     WF\:VIEW { behavior:url(/exchweb/controls/wfview.htc) }   } </STYLE> <WF:VIEW id="FolderView1"          style="width: 100%; height: 80%"          URL="%DataURL%"          viewDescriptor="FolderView1_XML"          linkspecSingleClick="%DataURL%"          targetSingleClick="_self"> 

You might notice in the WF:VIEW tag that the viewDescriptor property points at FolderView1_XML . The viewDescriptor property tells the view control where to pull the XML view descriptor that specifies the columns , sorting, and grouping that is contained in the view. This view descriptor can be an XML island in the Web page or can contain an absolute or relative URL to a file that contains the XML view descriptor.

Before we drill into the specific XML tags contained in the view descriptor, you need to be aware of two issues. First, if you look at the WF:VIEW tag, you might notice some parameters such as style , URL , and targetSingleClick . It makes no difference whether you specify these parameters in the WF:VIEW tag or as part of the XML view descriptor. Second, the XML view descriptor is shared between Exchange and Outlook. Outlook can expose and set its views using the XML view descriptor.

XML View Descriptor Format

The XML view descriptor format has four kinds of tags: primary, column, group by and sort by, and formatting tags. The primary tags are the ones that really affect the general settings of the view control. One example of a primary tag is the filter tag. You can specify the overall SQL WHERE clause to filter the items in the view by using the primary filter tag.

Column tags, on the other hand, affect only the column in which the tag is specified. Column tags can change the style, user interface, or functionality of the column. Also, you use column tags to specify properties from the items you want to display in the view. You should learn all about column tags because they are the primary means of getting the view control to display your data.

Group by and sort by tags are optional tags that specify whether there is grouping or sorting for the overall view. They are not required to render a view.

Formatting tags affect the overall rendering of your view. You can specify formatting for alternate rows to provide a unique user interface, header styles, or other styles to customize the view control.

Primary Tags

Table 20-7 lists the primary tags.

Table 20-7: Primary Tags

Tag

Description

boldUnreadItems

A value of 1 (the default) specifies that unread items are in bold. A value of does not bold unread items.

filter

Specifies the SQL WHERE clause to use to filter the items contained in the view. Note that the WHERE clause must be properly escaped for XML. This means that operators such as < and > must become &lt; or &gt; .

highlightrowstyle

Specifies the CSS text for style attributes on a selected row in a view. The default value is background “color:HIGHLIGHT; color :HIGHLIGHTTEXT . You can change this style to make the selected rows appear in yellow or green or whatever user interface styles you want.

imagepath

Specifies the URL path from which the view control will pull the image. The default value is /exchweb/img , which is where OWA pulls its images from.

linkSpec

Specifies the URL that the view control will use as the link for items in the view. The default value is %DataURL%?cmd= open , which will be replaced with the exact URL to each item with the open parameter as the command.

linkSpecSingleClick

Specifies the macro that is the URL to use when an item is clicked. The default value is %DataURL%?cmd=preview . This value will be replaced with the URL to the data item with the preview command along the querystring. When the values in the linkSpecSingleClick and linkSpec tags are the same, click and double-click have the same effect.

page

Specifies which page in the view to show. If the page does not exist, the view control will show the first page or the page that the user was already viewing.

rowsPerPage

Specifies as an integer the number of rows to show in the view for each page. If you specify a value of for this tag, the entire result set will be shown.

scope

Specifies a specific SQL FROM clause in case you need to do a custom SCOPE or traversal in your query. The default value for this tag is a shallow traversal of the current folder. If you specify the searchSubfolders tag, this tag is ignored.

searchSubfolders

A value of 1 indicates that you want to do a deep traversal. A value of specifies a shallow traversal. Remember that you cannot do a deep traversal in the MAPI Public Folder tree.

shadowrowstyle

Specifies the CSS style text for the selected rows in a view when the view does not have the focus. The default value is background “color:THREEDFACE .

sortascicon

Specifies the icon to use for the column heading when sorting in ascending order in that column. The default value is /exchweb/img/view-sortup.gif .

sortdescicon

The opposite of the sortascicon tag. It specifies the icon to use when sorting the view in a descending order. The default value is /exchweb/img/view-sortdown.gif .

target

Specifies where HTML links should open from the view, such as _self or _blank . You will normally want to set this to _blank to make items open in a new browser. If you specify targetSingleClick , you do not have to specify this tag.

targetSingleClick

Specifies where HTML links should open from the view when a user clicks on an item or link. You will normally want to set this tag to _blank to have the view control open the item in a new browser window.

view

A required root element of the view descriptor. Every view descriptor has a view tag. The rest of your tags are placed between the <view> </view> tags.

viewDescriptorURL

Specifies the location of an external view descriptor. All the standard WSS Forms macros are supported in this URL, including %DataURL% , %DataContainer , %FormURL% , and %FormContainer% .

viewDescriptor

Specifies the location of an internal view descriptor. This is normally an XML data island. If you specify both the viewDescriptor and viewDescriptorURL properties, the viewDescriptor property will be used.

Xslpassthrough

Used in conjunction with the customxsl tags in the column tags. This tag specifies valid XSL that you can use to transform data from Exchange before displaying that data in the view. You will see an example of XSL passthrough later in this chapter.

Let's look at an XML view descriptor that uses primary tags. The following view descriptor has a filter and opens the item in a new browser window when you click the item:

 <WF:VIEW id="FolderView1" viewDescriptor="FolderView1_XML">     <XML id="FolderView1_XML">         <view>             <style>width: 100%; height: 80%</style>             <URL>%DataURL%</URL>             <linkspecSingleClick>%DataURL%</linkspecSingleClick>             <targetSingleClick>_blank</targetSingleClick>             <filter>                 "DAV:ishidden" = false AND "DAV:isfolder" = false                 AND "DAV:contentclass" = 'My_list'             </filter>             <viewstyle></viewstyle>             <headerstyle>background-color:#C0C0C0</headerstyle>             <rowstyle></rowstyle>             <searchSubfolders>0</searchSubfolders>         </view>     </XML> </WF:VIEW> 

Column Tags

The only problem with the view descriptor you just saw is that it is blank. This is because the view has no column tags. Column tags specify the actual data columns to place in the view. Table 20-8 lists the column tags.

Table 20-8: Column Tags

Tag

Description

Bitmap

A value of 1 means that an IMG element will be created with the SRC attribute pointing to the contents of the property specified in the prop tag. Do not specify the checkbox tag with this tag because the results are undefined . The default value is .

Boolfalseicon

Specifies the absolute or relative URL to an image when your property is a Boolean that is false .

Booltrueicon

Specifies the absolute or relative URL to an image when your property is a Boolean that is true .

Checkbox

A value of 1 means that the column will be a set of check boxes that the user can select or deselect.

Column

The root element for all your columns. All the rest of the column tags must be children between your <column> </column> tags.

customxsl

Specifies the name of the XSL passthrough block to be used to format the data for this column.

Format

Specifies the format string to use for numeric and date data. The format strings you can use were described earlier in the chapter.

Groupbycolumn

Specifies that the current column should be grouped in the view. This tag is useful only for HTML 3.2 views.

Headerstyle

Specifies the HTML style you want to apply to the header for the column.

Heading

Specifies the string you want displayed for the column heading.

Multivalued

A value of 1 tells the view control that your multivalue property is comma delimited. The default value is (not comma delimited).

name

Associates check boxes with the column. Useful only when you have check boxes in your view.

Prop

Specifies the property to be displayed in the column. For example, to show the subject of the message, you set this property to urn:schemas:httpmail:subject .

Sortable

A value of 1 tells the view that your column can be sorted by the user.

Style

Specifies the HTML style to be applied to every column.

Type

Specifies the type of property, such as string.

Visible

Specifies whether to show the column. A value of 1 makes the column visible, and 0 makes the column invisible. This is useful if you want dynamic views and when you use URL overrides (as discussed later in the chapter).

The following is the earlier view descriptor but with column tags added:

 <WF:VIEW id="FolderView1" viewDescriptor="FolderView1_XML">     <XML id="FolderView1_XML">         <view>             <style>width: 100%; height: 80%</style>             <URL>%DataURL%</URL>             <linkspecSingleClick>%DataURL%</linkspecSingleClick>             <targetSingleClick>_blank</targetSingleClick>             <column>                 <heading>Read only</heading>                 <prop>DAV:isreadonly</prop>                 <headerstyle>width: 33%</headerstyle>                 <style>width: 33%</style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <column>                 <heading>Hidden</heading>                 <prop>DAV:ishidden</prop>                 <headerstyle></headerstyle>                 <style></style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <column>                 <heading>Friendly name</heading>                 <prop>DAV:displayname</prop>                 <headerstyle></headerstyle>                 <style></style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <column>                 <heading>Content state</heading>                 <prop>                     http://schemas.microsoft.com/exchange/contentstate                 </prop>                 <headerstyle></headerstyle>                 <style></style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <column>                 <heading>Expiration date</heading>                 <prop>urn:schemas:httpmail:expiry-date</prop>                 <headerstyle></headerstyle>                 <style></style>                 <format>M/d/yyyy h:mm:ss tt</format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <column>                 <heading>Keywords</heading>                 <prop>                     urn:schemas-microsoft-com:office:office#Keywords                 </prop>                 <headerstyle></headerstyle>                 <style></style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <column>                 <heading>Has attachments</heading>                 <prop>urn:schemas:httpmail:hasattachment</prop>                 <headerstyle></headerstyle>                 <style></style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <filter>                 "DAV:ishidden" = false AND "DAV:isfolder" = false                 AND "DAV:contentclass" = 'My_list'             </filter>             <viewstyle></viewstyle>             <headerstyle>background-color:#C0C0C0</headerstyle>             <rowstyle></rowstyle>             <searchSubfolders>0</searchSubfolders>         </view>     </XML> </WF:VIEW> 

Group By and Sort By Tags

Group by and sort by tags specify whether there is grouping or sorting in the view. These tags are summarized in Table 20-9.

Table 20-9: Group By and Sort By Tags

Tag

Description

Countlabel

Specifies the label to use to display the number of items in the grouping. For example, if three items are in the grouping and you set this tag to Number of Items , the view control will display Number of Items: 3 in its user interface.

Groupby

Specifies the grouping for your view. You use the Order tag to specify the property to group by and in what order to group multiple properties.

Heading

Specifies the string to prepend to the group by column heading in your view. This is usually the friendly name of the property you are grouping by.

Order

Used in conjunction with Groupby and Orderby to specify the properties to group or sort by and the order in which to perform each of those operations on the specified properties.

Orderby

The container tag for specifying a sort order in your view.

Prop

Specifies the name of the property, such as urn:schemas:httpmail:subject .

Style

Specifies the HTML style to apply to the header rows of a grouped view. You can specify any style that is valid for a <TR> tag.

Sort

Specifies how to sort a column. The possible values are ASC and DESC .

Unreadlabel

If this tag is present, the unread count for the grouped items is displayed in the header for the grouping. You specify the string that should appear before the number of unread items ”usually Unread .

The following example shows how to use group by and sort by tags:

 <view> . . . <groupby>     <order>         <heading>Friendly name</heading>         <prop>DAV:displayname</prop>         <headerstyle></headerstyle>         <style></style>         <format></format>         <sortable>1</sortable>         <visible>1</visible>         <checkbox>0</checkbox>         <bitmap>0</bitmap>         <countlabel>Count</countlabel>         <unreadlabel>Unread</unreadlabel>         <sort>ASC</sort>         </order>     </groupby> . . . </view> 

Formatting Tags

You might want to apply some general formatting to your view, such as making alternating rows different colors (as you can in Microsoft Excel). To do general formatting, you use the formatting tags, which are listed in Table 20-10.

Table 20-10: Formatting Tags

Tag

Description

Altrowstyle

Specifies the HTML style for all the odd rows in your view. You can specify a different color for the odd rows.

Headerstyle

Specifies the HTML style to apply to all your headings in the view.

Rowstyle

Specifies the HTML style to apply to all your rows in your view.

Viewstyle

Specifies the HTML style to apply to the overall HTML <TABLE> that makes up your view.

The following example uses these tags to create a highly customized view:

 <view> . . .     <viewstyle>width:100%; </viewstyle>     <headerstyle>background-color:#c0c0c0;CURSOR: hand</headerstyle>     <rowstyle></rowstyle>     <altrowstyle>background-color:lightblue</altrowstyle> . . . </view> 

Methods, Properties, and Events of the View Control

Beyond the tags we just covered, the view control has some extra methods and properties. If you look through the HTC code for the control, you will find these methods, properties, and events. For example, to use script in your Web page to refresh the control, delete the selected items in the control, listen for selection change events, or even add page navigation to the control, you need to use these methods, properties, or events. I cannot adequately describe each and every one, but I will highlight the key tasks you'll want to perform with them.

Deleting Selected Items and Refreshing the View Control

If you look through the actual code in wfview.htc, you will see some properties and methods, including the deleteItems and Refresh methods. When called from your client-side script, the methods delete the items selected in the view and refresh the view, respectively. They are valid only for the rich view control that is in Internet Explorer 5.0 and later, not for the HTML 3.2 rendering of the view control. The following code from the Training application shows how to get the reference to the view control on the page and how to use both methods:

 <WF:VIEW id="view1"          style=""          URL=""          onReady="viewload()"          viewDescriptor="FolderView1_XML"          linkspec="%DataURL%"          target="_blank"          rowsPerPage="15">          <XML id="FolderView1_XML">         <view>             <column>                 <heading>Icon</heading>                 <prop>                   http://schemas.microsoft.com/exchange/outlookmessageclass                 </prop>                 <headerstyle></headerstyle>                 <style>cursor:hand</style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>1</bitmap>             </column>             <column>                 <heading>Last Author</heading>                 <prop>                     urn:schemas-microsoft-com:office:office#LastAuthor                 </prop>                 <headerstyle></headerstyle>                 <style>cursor:hand</style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <column>                 <heading>Title</heading>                 <prop>urn:schemas:httpmail:subject</prop>                 <headerstyle></headerstyle>                 <style>cursor:hand</style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <column>                 <heading>Last Saved Time</heading>                 <prop>DAV:getlastmodified</prop>                 <headerstyle></headerstyle>                 <style>cursor:hand</style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <column>                 <heading>Size</heading>                 <prop>                     http://schemas.microsoft.com/mapi/proptag/x0e080003                 </prop>                 <headerstyle></headerstyle>                 <style>cursor:hand</style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <filter>                 "DAV:ishidden" = false AND "DAV:isfolder" = false             </filter>             <viewstyle></viewstyle>             <headerstyle>                 background-color:#c0c0c0;CURSOR: hand             </headerstyle>             <altrowstyle>background-color:lightblue</altrowstyle>             <rowstyle>background-color:FFFFFF</rowstyle>             <searchSubfolders>0</searchSubfolders>             <orderby>                 <order>                     <prop>urn:schemas:httpmail:subject</prop>                     <sort>ASC</sort>                 </order>             </orderby>         </view>     </XML> </WF:VIEW> <BR> <input type=button value="Delete Selected Items"        onclick="javascript:document.all.view1.deleteItems()"> <input type=button value="Refresh"        onclick="javascript:document.all.view1.refresh()"        id=button2 name=button2> 

As you can see, the client-side HTML just listens for an onclick event for two buttons on the form. Then some client-side JavaScript is called that gets the view element, which is called view1 from its ID, and calls the methods on the component.

Adding Navigation to Your Page

By default, when you add paging to your view via the rowsperpage property, the view control does not provide a way to navigate to new pages. You must provide this capability if multiple pages of data need to be displayed. Luckily, some methods and properties make adding navigation easy. The sample from the Training application has all the script you need to add navigation to your application. You use the pageCount property, which specifies the total number of pages of data. You also use the nextPage and previousPage methods, which move the control to the next and previous page, respectively. The following code from the sample application shows how to implement navigation paging in your view:

 <form class="form" name=viewform method="POST" action="">     <IMG id=idPageControl_PrevPage onclick="GoToPreviousPage()"          title="Previous Page" src="../resources/view-prevpage.gif"          style="CURSOR: hand; HEIGHT: 20px; POSITION: relative;                 WIDTH: 20px">     <FONT face=verdana id=idPageControl_PageText size=2           style="POSITION: relative;COLOR:#000000; TOP: -5px">     Page:<INPUT id=idPageControl_PageNumInput onkeydown="changePage()"                 style="FONT-FAMILY: verdana; FONT-SIZE: 12px;                        POSITION: relative; WIDTH: 50px">     /&nbsp;&nbsp;     <INPUT id=idPageControl_PageMaxInput readOnly            style="BACKGROUND-COLOR: #FFFFFF;                   BORDER-BOTTOM-COLOR: appworkspace;                   BORDER-BOTTOM-STYLE: solid;                   BORDER-LEFT-COLOR: appworkspace;                   BORDER-LEFT-STYLE: solid;                   BORDER-RIGHT-COLOR: appworkspace;                   BORDER-RIGHT-STYLE: solid;                   BORDER-TOP-COLOR: appworkspace;                   BORDER-TOP-STYLE: solid; COLOR: #000000;                   FONT-FAMILY: verdana; FONT-SIZE: 12px;                   POSITION: relative; WIDTH: 50px">     </FONT>     <IMG id=idPageControl_NextPage onclick="GoToNextPage()"          title="Next Page" src="../resources/view-nextpage.gif"          style="CURSOR: hand; HEIGHT: 20px; POSITION: relative;                 WIDTH: 20px"> </form> <script language="javascript">     //View behavior Navigation script     function GoToNextPage()     {         currentPage =             document.forms["viewform"]["idPageControl_PageNumInput"];         pageCount =             document.forms["viewform"]["idPageControl_PageMaxInput"];         if (view1.pageCount != "0")         {             if ( currentPage.value != view1.pageCount)             {                 view1.nextPage()                 currentPage.value++;                 pageCount.value = view1.pageCount;             }         }     }          function GoToPreviousPage()     {         currentPage =             document.forms["viewform"]["idPageControl_PageNumInput"];         pageCount =             document.forms["viewform"]["idPageControl_PageMaxInput"];         if ( currentPage.value != "1")         {             view1.previousPage()             currentPage.value--;             pageCount.value = view1.pageCount;         }     }          function viewload()     {         currentPage =             document.forms["viewform"]["idPageControl_PageNumInput"];         pageCount =             document.forms["viewform"]["idPageControl_PageMaxInput"];              currentPage.value = "1";              if(view1.pageCount == "0")         {             pageCount.value = "1";         }         else         {             pageCount.value = view1.pageCount;         }     }          function changePage()     {         currentPage =             document.forms["viewform"]["idPageControl_PageNumInput"];         pageCount =             document.forms["viewform"]["idPageControl_PageMaxInput"];         if (event.keyCode == 13)         {             view1.page = currentPage.value;             pageCount.value = view1.pageCount;         }         event.cancelBubble = true;     } </script> 

The code contains an HTML form that has buttons for next and previous pages as well as listings for the current page and the total amount of pages. The script is called when you click one of these buttons, type a number to change to a different page, or reload the view. The script has validation code that makes sure you are not trying to go to pages in the view that do not exist.

Listening for Selection Change Events

Events are a powerful way to make your code aware of the changes happening in the control. However, you must look through the source code to find the events, which include onReady , onRefresh , onBeforeDelete , and onError . You can see the events denoted in the source code with the identifier PUBLIC:EVENT . Once you figure out which event you want to listen for, you must register some client-side code to be called when that event occurs.

The onSelectionChange event from wfview.htc can be useful if you want to know which item the user is currently selecting in the view. You can then populate data in a form from that item or do a database lookup based on that item's data.

To register client-side code to be called when this event occurs, you add a line to your view declaration. The following view declaration registers a client-side script called FolderView1_OnSelectionChange to be called when the onSelectionChange event occurs for the view control:

 <WF:VIEW id="FolderView1"          style="width: 100%; height: 80%"          URL="%DataURL%"          viewDescriptor="FolderView1_XML"          RowsPerPage="10"          page=1          linkspec="%DataURL%"          target="_blank"          onSelectionChange = "FolderView1_OnSelectionChange"> 

To register for onReady or onError , you just add another line to the declaration just like the onSelectionChange line. You must then write the script that implements FolderView1_OnSelectionChange . However, I recommend that you always look at the source code that fires the event in wfview.htc. The event-firing code usually passes you an event object that contains valuable properties about the object firing the event. The following code from wfview.htc shows that the fire code for onSelectionChange passes an event object that specifies whether multiple items were selected in the multipleItems property, the HTML element that was selected as srcElement , and the selected item's URL in selectedURL :

 function mf_fireOnSelectionChange(objRow, b_wasSelected) {     var f_MultipleItems = "NONE";     if(null != objRow && "true" == objRow.isGroupHeader)     {         return;     }     var objSelectedItems = this.all("selected");     if (null != objSelectedItems)     {         if(null != objSelectedItems.length)         {             switch(objSelectedItems.length)             {                 case 0:     f_MultipleItems = "NONE"; break;                 case 1:     f_MultipleItems = "SINGLE"; break;                 default: f_MultipleItems = "MULTIPLE"; break;             }         }         else         {             f_MultipleItems = "SINGLE";         }     }     var objEvent = createEventObject();     objEvent.type        = "SelectionChange";     objEvent.srcElement    = this;     objEvent.selectedURL= (null == objRow) ? null : objRow._href;     objEvent.selected    = b_wasSelected;     objEvent.multipleItems = f_MultipleItems;     _ideventonSelectionChange.fire(objEvent); } 

We can now effectively write our event handler. We'll simply have the code MsgBox out the selected URL and whether multiple items were selected in the view.

 <script language=VBScript>     Sub FolderView1_OnSelectionChange()         MsgBox window.event.selectedURL         MsgBox window.event.multipleItems     End Sub </script> <script language=Javascript>     Function FolderView1_OnSelectionChange()     {         alert(window.event.selectedURL);         alert(window.event.multipleItems);     } </script> 

That's all you need to do to figure out which events the control offers, register for those events, and then write your handler for the events.

Using an External View Descriptor

Rather than having to hardcode a view descriptor into your Web page, you can point the control at a location from which to retrieve the XML view descriptor. The view descriptor file must be on the computer that's running the Web Storage System.

Using XSL Passthrough

You might want to apply your own custom formats, calculations, or other sorts of custom processing to data. When you use the view control, you can use the xslpassthrough and customxsl properties to customize how the control displays or calculates data by providing your own custom XSL scripts that process individual columns before displaying them in the view. For example, you might want a numeric rating column that is displayed as a graphic with stars (which is common for rating systems on the Internet) rather than showing a numeric rating. You can use the xslpassthrough property to create calculated columns in your views; however, this property is supported only in Internet Explorer 5.0 and later.

To use xslpassthrough , you perform a couple of steps in your view descriptor. First you add the XSL namespace to your view definition. You will see this step in the upcoming sample code. Then you define an xslpassthrough block containing a unique name. This block will contain the XSL markup that you want to implement. You can think of the xslpassthrough block as similar to an XSL stylesheet. Finally, you find the column where you want to run your custom XSL when it is displayed. You can do this by adding a customxsl tag that contains the name of the xslpassthrough block you want to call.

The following code shows all of these steps. It displays a calculated icon (such as the graphic with stars mentioned earlier) for a column rather than the number that would normally appear in the column.

 <WF:VIEW id="FolderView1"          style="width: 100%; height: 80%"          URL="%DataURL%"          viewDescriptor="FolderView1_XML"          linkspecSingleClick="%DataURL%"          targetSingleClick="_self">     <XML id="FolderView1_XML">         <view xmlns:xsl="http://www.w3.org/TR/WD-xsl">             <column>                 <heading>myinteger</heading>                 <prop>myinteger</prop>                 <headerstyle></headerstyle>                 <style></style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>                 <customxsl>calcrating</customxsl>             </column>             <column>                 <heading>Friendly name</heading>                 <prop>DAV:displayname</prop>                 <headerstyle></headerstyle>                 <style></style>                 <format></format>                 <sortable>1</sortable>                 <visible>1</visible>                 <checkbox>0</checkbox>                 <bitmap>0</bitmap>             </column>             <filter>                 "DAV:ishidden" = false AND "DAV:isfolder" = false                  AND "DAV:contentclass" = 'My_list'             </filter>             <viewstyle></viewstyle>             <headerstyle>background-color:#C0C0C0</headerstyle>             <rowstyle></rowstyle>             <searchSubfolders>0</searchSubfolders>             <xslpassthrough name="calcrating">                      <xsl:choose>                     <xsl:when test="prop1[. = 1]">                         <DIV>                             <IMG SRC="../images/1star.gif">                                 <xsl:attribute name="alt">                                 <xsl:value-of select="prop1"/>                                 </xsl:attribute>                             </IMG>                         </DIV>                     </xsl:when>                     <xsl:when test="prop1[. = 2]">                         <DIV>                             <IMG SRC="../images/2stars.gif">                                 <xsl:attribute name="alt">                                 <xsl:value-of select="prop1"/>                                 </xsl:attribute>                             </IMG>                         </DIV>                     </xsl:when>                     <xsl:when test="prop1[. = 3]">                         <DIV>                             <IMG SRC="../images/3stars.gif">                                 <xsl:attribute name="alt">                                 <xsl:value-of select="prop1"/>                                 </xsl:attribute>                             </IMG>                         </DIV>                     </xsl:when>                     <xsl:otherwise>                         <DIV>                             <IMG SRC="../images/4stars.gif">                                 <xsl:attribute name="alt">                                 <xsl:value-of select="prop1"/>                                 </xsl:attribute>                             </IMG>                         </DIV>                     </xsl:otherwise>                 </xsl:choose>             </xslpassthrough>         </view>     </XML> </WF:VIEW> 

You might be wondering where the value prop1 came from in the XSL value-of statement. You have to look at the SELECT statement that the view control creates to understand this. Here is the SELECT statement for the previous view:

 SELECT "myinteger" As prop1, "DAV:displayname" As prop2, "urn:schemas:http mail:read" As read, "http://schemas.microsoft.com/exchange/outlookmessage class" As messageclass, "DAV:href" As davhref FROM SCOPE('SHALLOW TRAVERSAL OF ""') WHERE "DAV:ishidden" = false AND "DAV:isfolder" = false AND "DAV:content class" = 'My_list' 

As you can see from the SELECT statement, your columns are aliased into propX , where X is the location of your property in the column order. Therefore, prop1 refers to the myinteger property. Once you know this, creating the XSL code for the xslpassthrough property is straightforward. You can have multiple xslpassthrough blocks to implement different functionality for different columns in your application. Also, note that you can access different column values in your XSL by just specifying a different property name in your XSL code. This means you can add columns together to create a calculated column in your view.

Working with URL Overrides

In some cases, you might want to change the SELECT statement that you created in your view by using the filter tag. For example, you might want to add hyperlinks to your Web page to allow users to sort by a particular column or filter by a dynamic property (such as who the user is). To allow you to dynamically modify any property of the view control, the control supports the ability to pass along URL overrides of the properties of the control. You can also use script to override any of the properties of the control.

To use URL overrides, you just append certain keywords to the URL of the Web page that contains the view control. Here is the syntax for using URL overrides:

 http://URL/?view.<viewid>.<property>=<value>&<property>=<value> 

For example, if you want to append a new filter to the existing filter used in the SQL SELECT statement for your view, you can use the filterappend property in your URL and specify the additional SQL WHERE clause parameter you want to add. In the following URL, we will create a filtered view to display only those items where the display name is a certain value and sort the view in ascending order of importance. In this example, the ID of the view is named folderview1 in our wf:view definition.

 http://server/public/myapp/?view.folderview1.filterappend="DAV:dis playname"='myvalue.eml'&view.folderview1.sort="importance;ASC" 

Besides exact matches, you can use other predicates such as the LIKE predicate. The following URL appends a filter to find all items that begin with the character t :

 http://server/public/myapp/?view.folderview1.filterappend="DAV:displayname"    LIKE 't%' 

Below is the escape character encoded version of the URL.

 http://server/public/myapp/?view.folderview1.filterappend="DAV:dis playname"%20LIKE%20't%25' 

You can change any of the view control properties. Remember that if you are going to append filters, you must cast any values that are not String or Boolean . The following example shows a URL with the correct casting to query on an integer value:

 http://server/public/myapp/?view.folderview1.filterappend="myinteger"=CAST("2" as "i8")&view.folderview1.sort="importance;ASC" 



Programming Microsoft Outlook and Microsoft Exchange 2003
Programming MicrosoftВ® OutlookВ® and Microsoft Exchange 2003, Third Edition (Pro-Developer)
ISBN: 0735614644
EAN: 2147483647
Year: 2003
Pages: 227
Authors: Thomas Rizzo

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net