Tags

Including Server Side Content in a Worklight Application

Worklight applications are Single Page Applications (SPAs). That doesn't mean that all the HTML for a worklight application needs to be in a single file. Loading HTML fragments into a running application is a very powerful technique. (and one that I hope to explore in its own post.) SPAs have a single DOM tree. Elements in the tree can be shown and hidden. Sub-trees can be added or pruned. But the root of the DOM does not change for the life of the application. Dojo Mobile uses views, and jQuery Mobile uses pages to give the application the ability to navigate within the DOM tree, and HTML fragments provide the ability to augment the tree at runtime, but never in the life of a worklight app does the main page transfer control to another root document.

However if you want to include server side content in your worklight application, you really need a different mechanism than those used for mobile navigation within the application.

Communication between pages

There will be some limits that will be common to all these techniques. Because the content in a Worklight App and the server side content are loaded from different domains, the web container strictly limits how they can interact. In most cases the worklight app and the server based content can't simply access each others functions and data.

For this post I've put together a demo app that just opens external web sites. It does not pass any data to the sites, and it does not get any data from the sites. It turns out that just looking at the options available for launching server based content in a Worklight app is a job in itself. The number of combinations of technique, options, and environment make this its own topic.

The more interesting case of an app that doesn't just launch server side content, but interacts with it will have to wait for a follow up post.

Just throw 'em an anchor

The simplest way to load server side content in a Worklight application is to simply put an anchor in the HTML with a server side URL for the href. How this behaves depends on the environment in which it is running. (spoiler: in most environments, this is going to turn out to be useless)

<a href="http://www.balboapark.org">Balboa Park</a>

In the desktop browser environment, an anchor with a server side URL results in the current window/tab navigating to the server side page. The Worklight app is gone at that point. If you use the back button to return to the worklight app, it actually restarts the app. Any in-memory state in the app before the anchor was selected will be gone. iOS and BlackBerry 10 apps behave the same way, with the added chalenge that the server side content will be loaded into the existing WebView (which doesn't have any navigation controls, so there is no back button to push.)

On Windows Phone 8, the server side content is loaded in the existing WebView, but there is a back button that allows you to get back to the Worklight app. However, just as with the desktop browser, the original app was unloaded when the server side content was loaded, so when you navigate "back" to the app from the server side content, the app restarts.

For these environments, putting a simple anchor with a server side URL probably isn't going to be very useful.

On Android, the server side content is loaded into the platform's default browser, and the Worklight app keeps running. The back button works to return to the running app, and the state of the Worklight app is not lost when the server side content was loaded. For Android (and only for Android) this can be a usable technique.

One way to be more specific in how you want the content to be handled when you click on an anchor is to add: rel="external" and target="_blank" to the anchor attributes. This does change the behavior for the desktop browser and BlackBerry 10 environments. The desktop browser will open the server side content in a new tab. (leaving the Worklight app running in the original tab) With these attributes in the anchor element, BlackBerry 10 will launch the server side content in a new WebView Window (which even has a handy close button to return to the undisturbed Worklight app when you are done with the server side content) But the Window doesn't have the normal navigation buttons that are present in he BlackBerry Web Browser.

Setting the name to _blank on a window.open() call causes the link to be opened in the InAppBrowser. On BlackBerry 10, this is the same WebView Browser that was used for the simple anchor with target=" _blank". On Android and iOS, the result is a similar WebView Browser, but Android and iOS have forward and back buttons available along with the Close button.

As you can see above, The Android InAppBrowser fits the page by width, but iOS lets it scroll horizontally as well as vertically. BlackBerry 10 InApBrowser fits the page width like Android does.

Unfortunately, there seems to be a number of defects in the Cordova InAppBrowser for Windows Phone 8. It behaves like the simple anchor. The server side content is opened in a WebView window with no navigation controls, and when the hardware back button is used to return to the Worklight app, the app restarts.

If, instead of using "_blank" for the name in the call to window.open(), you use "_system" then on Android and iOS, the server side content opens in the phone's browser. On BlackBerry the content opens in the InAppBrowser still, and on Windows Phone 8, the content opens in the WebView container (replacing the Worklight app)

Of course on the desktop browser, the call to windows.open() is handled directly by the browser, and Cordova doesn't get involved, so in most browsers it will open the server side content in a new window or tab, and the worklight app continue running in the existing window/tab.

The InAppBrowser is an easy way to open server side content in your worklight app, but if BlackBerry 10, and especially Windows Phone 8 are on your target list, it isn't quite ready.

The ever popular iframe

Of course you can use an iframe in a Worklight app to include server side content. How well/poorly this works for you will depend on how iframe friendly the server side content is. Unless the server side content was written with the express intention of working in an iframe, there will probably be some problems.

One advantage of using an iframe is that it puts the server side content right into your app. The iframe can be just one widget on a larger page that contains the standard headers and navigation controls for your app. This has the potential of making the server side content blend in with the rest of your app. But as mentioned above, how well/poorly this works depends on how well the server side content deals with being framed.

As seen above, the web page in the iframe doesn't automatically size itself to the width of the window. Instead, it allows vertical and horizontal scrolling, which can get tedious. This behavior is the same across all the phone types that I've looked at, and is even true in the desktop browser environment. This is just one more reason why the server side content must be explicitly designed to live in an iframe for effective integration.

There is a lot of information available about using iframes in web apps. In a Worklight app, it is important that you not define the iframe statically in the HTML, as the server side content will be loaded immediately when the application starts. This results in unneeded network traffic if you don't use the page in your app with the iframe, along with some truly ugly visual artifacts at application startup.

Instead of defining the iframe statically, add it dynamically only when it is needed:

Setting the height and width of the iframe to 100% and declaring it to be seamless, makes it fit exactly into its container. One problem with iframes is that if the content in the iframe scrolls and the page that the iframe is on scrolls, navigation can get confusing. Even with the iframe carefully sized to fit in its container, scrolling within the iframe does not seem to work at all on iOS.

WL.App.openURL()

The Worklight API has a function for showing server side content: WL.App.openURL():

This is the only way that I have found to open server side content that works uniformly across Android, BlackBerry 10, iOS, and Windows Phone 8. In all cases, it opens the server side content in the phone's default browser. The worklight app keeps running, and you can return to it using the back button on Android and Window Phone 8, by double clicking on the home button on iOS, and by using gestures to minimize the browser on BlackBerry 10. In all cases the app is right where it was before the server side content was launched, and is not restarted when you return to it.

In the desktop browser environment, it opens the server side content in a new tab. The Worklight application continues to run in the original tab.

WebView Overlay

The Worklight Getting Started materials include a module called: Integrating server-generated pages in hybrid applications. There are associated code samples that include a Web View Overlay custom Cordova plugin for iOS and Android. The Web View Overlay provides the best of both worlds of iframe and WebView browser. The Overlay fits in your application's page like an iframe, but the server side code is running in a WebView browser. The Worklight application continues to run, while the overlay is open, and when you exit the overlay, the Worklight application does not restart.

The biggest downside to the Web View Overlay, is that the implementation is only provided for Android or iOS. I don't imagine that it would be too great a task to write the BlackBerry 10 and WindowsPhone 8 plugin implementations, but I may just be mistaken on that count.

The best way to understand the Web View Overlay approach is to go through the materials at the Worklight Getting Started site. I've also included an example where I modified the plugin for my use in the PI that I will link at the end of this post.

In the images above, the Header with the back button is a part of the Worklight app. The rest of the screen is server side content presented in the Web View Overlay.

Epilogue

As I said at the start, launching server side content is the easy part. The more interesting task is for a Worklight application to launch server side content and interact with it. But that will have to be another post.

The project interchange with he Worklight 5.0.6.1 project that illustrates these techniques is here. It is super-sized because it contains all the environments discussed.

EDIT: I recently had occasion to import the project into Worklight Studio V6. It was completely broken. The problem was that the version of jQuery Mobile in the project (1.2.0) is incompatible with the version of jQuery in Worklight V6. (1.8) Updating jQuery Mobile in the project to 1.3.1 fixes everything. This highlights that while using Worklight's builtin in jQuery is awfully convenient, it might be a better practice for applications to bundle their own copy of jQuery.