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.
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.
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.
Table 20-7 lists the 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 < or > . |
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>
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.
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 specify whether there is grouping or sorting in the view. These tags are summarized in Table 20-9.
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>
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.
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>
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.
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.
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"> / <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.
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.
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.
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.
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"