It is sometimes necessary to pass parameters between two Forest and Tree Views setup on a portal site. This article explains how you can use the portal webserver and HTML scripts to achieve this between two FTVs.
The demonstration is a simple scenario where a book publisher has a list of books for which he wishes to update the prices. The demonstration comprises of two FTVs, one to send the price change request, and the other to apply the price change and display the book price catalogue. This demonstration also uses the new XML features of "CleverPath Forest and Trees Version 7.0" to query and modify an XML file which stores the publishers book catalogue.
The sample XML file "BookData.xml" used in this demonstration is listed in Appendix A1.
CleverPath Portal Setup
The Portal site is configured to display the following two published files.
Portal Published File | Description |
ChangePrice.ftv | FTV to send a HTML request to modify a book price. |
IframeReceive.html | Defines a HTML IFRAME with a TARGET name of "Destination". On startup this displays a blank page (about:blank) as the default URL. When the publishers issues a HTML request, this IFRAME displays a contained FTV, listing the new book prices. Source for this script is listed in Appendix A2. |
F&T View for a Book Price Change Request
The ChangePrice.ftv comprises of the following contained views.
Contained view | Visibility | Description |
OpenViewFile | Hidden | Calculates 'BookIdView' and 'SelectBook' on startup |
SelectBook | Shown | List view with XML interface, allowing publisher to select a book title from the catalog. Has an associated trigger which calculates 'BookPriceView' and 'BookIdView'. |
SendUpdateRequest | Hidden | Internet Explorer Web browser view with no interface |
BookIdView | Hidden | Queries XML to obtain book id for current selected title. |
BookPriceView | Shown | Edit view which queries XML to obtain book price for current selected title. Also allows publisher to edit the price. |
UpdateBookPrice | Shown | Button view which upon activation, obtains the selected book id and price and sets the URL for the "SendUpdateRequest" browser. An example URL setting is http://YourPortalServer/IframeDemo/IframeSend.html?id=bk110&amount=34.56. Note that YourPortalServer is the server name of your IIS webserver and IframeDemo is the sub-directory under "c:\inetpub\wwwroot" containing the IframeSend.html script |
SendUpdateRequest | Hidden | Internet Explorer Web browser view with no interface |
IframeSend.html Script
The source for this script is listed in Appendix A3.
The IframeSend.html script begins by parsing the specified argument list and creating variables with the same argument names and specified values. This HTML script has a "BODY onload" method which calls the custom redirect() function. The custom redirect() function calls the JavaScript function window.open() specifying a URL as the first parameter and the TARGET attribute name of the new window. By specifying the TARGET name of "Destination" this sends the requested URL to be opened in the neighbouring Portal window (IframeReceive.html) which has the same TARGET name.
The URL specified by IframeSend is "http: //YourPortalServer/IframeDemo/CallFtv.html?id=bk110&amount=34.56", which runs the CallFtv.html script in the neighbouring Portal window.
CallFtv.html Script
The source for this script is listed in Appendix A4.
The CallFtv.html script begins by similarly parsing the specified argument list and creating variables with the same argument names and specified values.
The body element of this script invokes the Forest and Tress Active X plug-in with the specified view file and parameters http://YourPortalServer/IframeDemo/UpdatePrice.ftv;bk110;34.56. Note that the FTV parameters are now passed in semicolon separated format. Also, if the forest and trees runtime is not installed on the client, it will be automatically downloaded and installed from the codebase specified location.
F&T View for Modifying book price and Displaying book catalog
The UpdatePrice.ftv comprises of the following contained views
Contained view | Visibility | Description |
OpenViewFile | Hidden | Extracts both arguments into Substitution variables, and calculates UpdatePriceXml. |
UpdatePriceXml | Hidden | Programatically parses and formats the XML document. |
XmlAllBooksView | Shown | Queries XML file to obtain title, price and author for all books. |
The UpdatePriceXml view makes use of an internal function library to simplify the logic within the formula. The source for the library functions is listed in Appendix A5.
The internal library provides two functions GetAttributeValue() and UpdateChildNode(). GetAttributeValue() return the attribute value for the specified attribute in the current element. UpdateChildNode() updates the specified child elements text for the current element.
The formula logic in UpdatePriceXml (listed in Appendix A6), seeks the book node for the specified book id, and updates the corresponding price. The XML document is then saved and the XmlAllBooksView is calculated
Summary Steps for Running this Demonstration:
<?xml version="1.0"?><catalog> <book id="bk110"> <author>O'Brien, Tim</author> <title>Microsoft .NET: The Programming Bible</title> <genre>Computer</genre> <price>32</price> <publish_date>2000-12-09</publish_date> <description>Microsoft's .NET initiative is explored in detail in this deep programmer's reference.</description> </book> <book id="bk111"> <author>O'Brien, Tim</author> <title>MSXML3: A Comprehensive Guide</title> <genre>Computer</genre> <price>45.66</price> <publish_date>2000-12-01</publish_date> <description>The Microsoft MSXML3 parser is covered in detail, with attention to XML DOM interfaces, XSLT processing, SAX and more.</description> </book> <book id="bk112"> <author>Galos, Mike</author> <title>Visual Studio 7: A Comprehensive Guide</title> <genre>Computer</genre> <price>29.99</price> <publish_date>2001-04-16</publish_date> <description>Microsoft Visual Studio 7 is explored in depth, looking at how Visual Basic, Visual C++, C#, and ASP+ are integrated into a comprehensive development environment.</description> </book></catalog>
|
Appendix A2 - IframeReceive.html
<HTML><iframe height = 100% width = 100% name="Destination" src="about:blank" frameborder=0 ></iframe></HTML>
|
Appendix A3 - IframeSend.html
<html><head><script type="text/javascript">// parses arguments ?token1=value1&token2=value2&token3=value3...// assigns values to tokens with same variable nameif (window.location.href.indexOf("?") != -1) { var gr_query = unescape(window.location.href.substr(window.location.href.indexOf("?") + 1, window.location.href.length)) while (gr_query.indexOf("=") != -1) { gr_attrib = gr_query.substring(0, gr_query.indexOf("=")) gr_val = gr_query.indexOf("&") != - 1 ? gr_query.substring(gr_query.indexOf("=") + 1, gr_query.indexOf("&")) : gr_query.substring(gr_query.indexOf("=") + 1, gr_query.length) //alert (gr_attrib + " : " + gr_val) eval ("var " + gr_attrib + " = '" + gr_val + "'") gr_query = gr_query.indexOf("&") != - 1 ? gr_query.substring(gr_query.indexOf("&") + 1, gr_query.length) : gr_query = "" ; gr_attrib = null gr_val = null }} else { var query = ""}</script></head><SCRIPT LANGUAGE="JavaScript"><!--function redirect () { window.open("http://YourPortalServer/IframeDemo/CallFtv.html?id="+id+"&amount="+amount, "Destination") }//--></SCRIPT><BODY onLoad="redirect()">
|
Appendix A4 - CallFtv.html
<html><head><script type="text/javascript">// parses arguments ?token1=value1&token2=value2&token3=value3...// assigns values to tokens with same variable nameif (window.location.href.indexOf("?") != -1) { var gr_query = unescape(window.location.href.substr(window.location.href.indexOf("?") + 1, window.location.href.length)) while (gr_query.indexOf("=") != -1) { gr_attrib = gr_query.substring(0, gr_query.indexOf("=")) gr_val = gr_query.indexOf("&") != - 1 ? gr_query.substring(gr_query.indexOf("=") + 1, gr_query.indexOf("&")) : gr_query.substring(gr_query.indexOf("=") + 1, gr_query.length) //alert (gr_attrib + " : " + gr_val) eval ("var " + gr_attrib + " = '" + gr_val + "'") gr_query = gr_query.indexOf("&") != - 1 ? gr_query.substring(gr_query.indexOf("&") + 1, gr_query.length) : gr_query = "" ; gr_attrib = null gr_val = null }} else { var query = ""}</script></head><body><script type="text/javascript">// Displays FTV passing it the parameters in semi-colon separated formatdocument.write("<object ID='FTW' Name='FTW' classid='clsid:5FADE212-B755-11D1-BA39-00C04FD60C4B'" + " width='100%' height='100%' codebase='http://YourPortalServer/websetup7/ftwrt700.exe'> " + " <PARAM Name='ViewFile' Value='http://YourPortalServer /IframeDemo/UpdatePrice.ftv;" +id+";"+amount+"' > </object>") </script></body></html>
|
Appendix A5 - UpdatePrices.ftv::MyXmlFuncs Internal Library Functions
Function GetAttributeValue( node as XMLDOMNode, attrib as text) as text Dim value as text Dim AttribNodes as XMLDOMNode Trace('attrib=',attrib) AttribNodes := node.attributes Trace('count=',count(AttribNodes)) if count( AttribNodes ) > 0 Dim a as XMLDOMNode for i = 1 to count( AttribNodes ) a := AttribNodes[i] Trace('NodeName=',a.NodeName) if a.NodeName = attrib Trace('NodeValue=',a.NodeValue) value := a.NodeValue break; endif next endif Trace('value=',value) return(value)EndFuncFunction UpdateChildNode(ParentNode as XMLDOMNode, ElementName as Text, ElementValue as Text) Dim XmlChildNodes as XMLDOMNode; // select child nodes XmlChildNodes := ParentNode.SelectNodes( ElementName ) if count(XmlChildNodes) > 0 Dim XmlChildNode as XMLDOMNode // assumes only 1 child XmlChildNode := XmlChildNodes[1]; Trace('New Value=',ElementValue) XmlChildNode.Text := ElementValue endifEndFunc
|
Appendix A6 - UpdatePrices.ftv::UpdatePriceXml view
Dim XmlDoc as XMLDOMDoc;Dim XmlRootNode as XMLDOMNode;// switch on validation during parsingXmlDoc.ValidateOnParse := TRUETrace('Loading...')// load the XML documentXmlDoc.Load('&XmlPath&')// get root elementXmlRootNode := XmlDoc.DocumentElementif (XmlRootNode != NULL) Dim XmlBookNodes as XMLDOMNode; // select book nodes XmlBookNodes := XmlRootNode.SelectNodes( 'book' ) if count(XmlBookNodes) > 0 Dim XmlBookNode as XMLDOMNode for i=1 to count (XmlBookNodes) // get one book at a time XmlBookNode := XmlBookNodes[i]; Dim XmlBookId as text XmlBookId := GetAttributeValue(XmlBookNode, 'id') Trace('XmlBookId=',XmlBookId) // if book id matches then update price if (XmlBookId='&BookId&') UpdateChildNode(XmlBookNode, 'price', '&BookPrice&') break endif next endifendifTrace('Saving...') XmlDoc.Save( '&XmlPath&' )
|