How to embed an Echo2 app
This article is in response to the people who have shown interest in embedding an Echo2 app into an already existing web page. The solution I have come up with is similar to how you would go about embedding a java applet into a web page.
My original forum postings on this topic can be found at:
http://forum.nextapp.com/forum/index.php?showtopic=1710&st=0
I will provide source for all the modified and newly added classes so that you can drop/replace them into your Echo2 distributions source and rebuild the Echo2 jars to start using this for your own apps.
To start I will try to best explain what my solution does to accomplish this. Echo2 was designed to provide a web application framework (which it does very well!) that does not show/share any browser content outside of what Echo2 has provided. In other words, if you use Echo2 everything displayed within the browser window containing the Echo2 content must come from Echo2 in one way or another. When a browser hits a URL for an Echo2 app a couple different services are called to initiate the application. Two of these services are: NewInstanceService and WindowHtmlService. These services trigger the initial creation of the base x/html document to which Echo2 adds the application developers desired components. In the case of embedding an Echo2 app into a webpage we want to skip this step since our webpage already exists. To see what Echo2 produces for the base x/html simply view the source of an Echo2 app in your browser. Take notice of the sole <form> element and the ‘id’ assigned to it “c_root”. This controls where your Echo2 content is placed in a page and what you will use to embed the Echo2 content in your existing webpage. There are other things you must do when the page is first loaded like loading of the ClinetEngine.js file which I will get to shortly. In order to skip this step of creating the base x/html structure on which to build the application I made a very small modification to WindowHtmlService’s service(Connection) method which will not affect using Echo2 in the normal way.
This if statement was added to the very beginning of the service(Connection conn) method:
[code]
if(conn.getRequest().getParameter("htmlservice") != null &&
conn.getRequest().getParameter("htmlservice").equals("false")) { return;
}
[/code]
The “htmlservice” is a parameter passed on the initial request to the Echo2 servlet when using the embedded option provided in this article.
Lets now look at an example x/html page that is written for embedding an Echo2 app:
[code]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="
http://www.w3.org/1999/xhtml">
<head>
<title>Echo2 Embed Example</title> <script type="text/javascript" src="embed.js"> </script>
</head> <body onload="init()" style="position:absolute;font-family:verdana, arial, helvetica, sans-serif;font-size:10pt;height:100%;width:100%;padding:0px;margin:0px;">
<!-- THIS IS THE DIV THAT FLOATING WINDOWS ARE ADDED TO --> <div id="window" style="position:absolute; width:100%; height:100%; background-color:#e1e1e1;">
<div style="position:absolute; width:100%; height:200px; top:0%; left:0%; background-color:red;"> BEFORE THE ECHO CONTENT<br> <a href="embedded2.html">Page 2</a><br> </div>
<!-- THIS IS THE DIV HOLDING THE ECHO2 CONTENT -->
<div style="position:absolute; top:200px; left:100px; right:0px; bottom:0px; background-color:blue;">
<script type="text/javascript">
writeContent();
</script>
</div>
<div style="position:absolute; width:100px; top:200px; left:0px; bottom:0px; background-color:green;"> LEFT OF THE ECHO CONTENT </div>
</div> <!-- close of DIV ID="window" -->
</body>
</html>
[/code]
…and the embed.js file:
[code]
var server = "
http://localhost:8080";
var servlet = server + "/embed20rc7/app";
function sendInitialRequest() {
makePostRequest(getInitialParams(), false);
document.write('<script src="'+servlet+'?serviceId=Echo.ClientEngine" type="text/javascript"> <\/script>');
}
function init() {
EchoClientEngine.init(servlet, true);
}
function makePostRequest(parameters, asynchronous) {
http_request = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
} if (!http_request) {
alert('Cannot create XMLHTTP instance');
return false;
}
http_request.open("POST", servlet, asynchronous);
http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http_request.setRequestHeader("Content-length", parameters.length);
http_request.setRequestHeader("Connection", "close");
http_request.send(parameters);
}
function getInitialParams() {
// you can add any parameter here that you wish to be passed to the servlet on the initial request
var poststr = htmlService=false;
//poststr += "xyz=xyzValue";
return poststr;
}
function writeContent() {
document.write('<form action="#" id="c_root" onsubmit="return false;" style="padding:0px;margin:0px;" />');
}
sendInitialRequest();
[/code]
So, reviewing the above example file you can see how to put your webpage together and how the initial request to the Echo2 servlet and the ClientEngine.js file is loaded.
However, if you use a ContentPane as your root pane to add all your other Echo2 compoents to you will be fine until you try/need to add a WindowPane. This may or may not be a problem for you depending on how you want your WindowPanes to be contained. If you want them to be movable/contained only within the Echo2 part of your page you will be fine, but if you want them to be draggable over the whole browser window then you will need to use an extended form of the ContentPane class that I wrote. This class, EmbeddedPane, is basically the same as ContentPane except that it allows you to define a <DIV> id in it’s constructor for which <DIV> on your web page (the whole page) to add the WindowPane to. This is where the <div id=”window”> just inside the <BODY> tag comes into place in the above example html page. EmbeddedPane also has its own peer class, EmbeddedPanePeer, that extends ContentPanePeer.
Here is a brief summary of the files that were modified:
SynchronizePeerBinding: added mapping for EmbeddedPane -> EmbeddedPanePeer
WindowHtmlService: added the if statement explained earlier in the article to service()
ContentPanePeer: changed the following methods and fields from private access to protected
CONTENT_PANE_SERVICE
IMAGE_ID_BACKGROUND
renderAddChildren()
renderChild()
renderInitDirective()
The 2 newly added classes are EmbeddedPane and EmbeddedPanePeer.
All the above files are located in the patch directory of the Echo2 embedded example project available for download from my original thread on this subject at:
http://forum.nextapp.com/forum/index.php?s=&showtopic=1710&view=findpost&p=8981
The Echo2 jars provided in the lib directory of the project have already had the patch files applied to them. Just run ‘ant’ to build the deployable wars for each example.
Once the wars are deployed you should be able to visit each example at:
http://localhost:8080/embed20rc7/embedded.html for the 2.0rc7 version and
http://localhost:8080/embed770svn/embedded.html for the svn770 version
These two examples are very basic examples. The 2.0rc7 example is just a SplitPane and a Button to open a WindowPane. The svn770 example contains an AccordionPane, some labels, and a Button to open a WindowPane. All you should need to do to embed one of your Echo2 apps is change the root container from a ContentPane to an EmbeddedPane.
Disclaimer: This is still a work in progress and I hope Tod will provide this type of functionality in the main Echo2 distribution eventually. Also, I have found a problem with removing WindowPanes that can float over the whole webpage in the newer versions of Echo2. I have provided 2 examples in the embedded project that can be downloaded. One which uses Echo2 v2.0rc7 and the other that uses SVN revision 770 (which is a little newer code than what’s available in Echo2 v2.1.0.beta3). The example app that uses v2.0rc7 closes window panes normally as expected. Newer versions don’t remove the window pane on the client side, however they are removed in the application hierarchy on the server. You can test this by refreshing your browser. I have not been able to spend much time on figuring out what is causing this. So if anyone else wants to help that would be much appreciated. See posts about this in the forum:
http://forum.nextapp.com/forum/index.php?s=&showtopic=1710&view=findpost&p=8499
I would like to hear any and all comments.