Jennifer's Weblog

« Previous month (Jul 2006) | Main | Next month (Sep 2006) »

http://blogs.sun.com/jenniferb/date/20060814 Monday August 14, 2006

Using a jMaki Widget in a Phobos Application

Last week I blogged about how to use the new publish/subscribe mechanism in jMaki to handle an event of the jMaki fisheye widget. To demonstrate this, I created an application that uses the fisheye widget to display bios of some of Sun's engineers.

This week, I'll describe how I used the jMaki fisheye widget to implement the same use case in a Phobos application. You can find this example in the apps/bioFisheyeWidget directory of the Phobos workspace.

The Phobos project is focussed on building a web application framework that allows you to develop your web applications with a scripting language. Just as you can add jMaki widgets to web applications built with JSP technology, you can add jMaki widgets to web applications built with Phobos.

Here again is a screenshot from the web application I described last week:

To implement this web application in Phobos, I performed these steps:

  1. I checked out the jMaki and Phobos projects and built them, as described in Building a Phobos Distribution.
  2. I created my application's directory structure according to the Phobos project's conventions. See Your First Phobos Application for more details. You can also refer to my example, called bioFisheyeWidget, located in the apps directory of your Phobos installation.
  3. I added the images for the fisheye into the bioFisheyeWidget/static directory.
  4. I created a script called index.js in the bioFisheyeWidget/application/script directory. What this script does is it forwards to the controller, which handles the rendering of the view. Here is the index.js file:

    library.httpserver.sendRedirect(library.httpserver.makeUrl("/fisheye"));
    

  5. I created the controller script, called fisheye.js inside the bioFisheyeWidget/application/controller directory. It creates the Fisheye controller object, which renders the view. Here are the contents of fisheye.js:

    library.common.define(controller, "fisheye", function() {
        this.Fisheye = function() {
            this.index = function() {
                library.view.render("fisheye.ejs");
            };
        };
    });
    

  6. Finally, I created the view script, called fisheye.ejs and added it to the bioFisheyeWidget/application/view directory. It is just like1 the JSP page from the application I blogged about last week, except for one thing: Instead of using the custom ajax tag, you need to call the jmaki.insert function provided by Phobos to add the widget to the page:

    <% library.jmaki.insert({component: "dojo.fisheye", args:{items:[
                 {iconSrc:'JayashriVisvanathan.jpg',caption:'Jayashri', index:1},
                      {iconSrc:'chinnici.jpg',caption:'Roberto',index:2},
                      {iconSrc:'blog_murray.jpg',caption:'Greg',index:3}]}}); %>
    </p>
    </div>
    

That's it! For an introduction to the Phobos architecture, see the document, An Overview of Phobos. See the tutorial for more information on building Phobos applications.

1: There is one other difference between fisheye.ejs and the JSP page I described last week: In fisheye.ejs, I use double quotes around the response text and don't escape the single quotes. After you check out the example code, you can compare the JSP page with the view script.

http://blogs.sun.com/jenniferb/date/20060807 Monday August 07, 2006

Handling jMaki Widget Events Using Publish/Subscribe

One of the many widgets that jMaki offers is the Dojo fisheye widget:



A page author adds this widget to an application by including the following ajax tag in a page:

 <a:ajax
name="dojo.fisheye"
args="{items:[
{iconSrc:'images/icon_browser.png',caption:'You are here!'},
{iconSrc:'images/icon_calendar.png',caption:'test3'},
{iconSrc:'images/icon_update.png',caption:'Update'}
]}">
</a:ajax>

In the preceding tag, each item in the items array represents the properties for the icon in the widget.

This widget resizes the image icons as the user moves the mouse over them. But, what if you want something to happen when the user clicks on an image? One way to do this is to register an event handler onto the widget by hand, as explained in Sang Shin's excellent jMaki lab.

Now there's a much easier way, which is to use the new publish and subscribe mechanism that Greg Murray has just added to jMaki. I thought it would be a good idea to modify the example fisheye widget that is part of jMaki so that it publishes itself as a topic to which individual applications can subscribe.

What we did to the fisheye widget's component.js file is we replaced the alert message inside the onClick function with a publish statement:

dojo.require("dojo.widget.FisheyeList");
// create the top level widget var fishEye = dojo.widget.createWidget(widget.uuid);
// programtically add FisheyeListItem children to the widget var counter = 0;
while (true) {
var i = widget.args.items[counter++];
if (i == null) break;
var icon = dojo.widget.createWidget("FisheyeListItem", i);

    icon.onClick = function (){
 jmaki.publish("/fisheye", this);
 }

   fishEye.addChild(icon);
}

As shown in the preceding code, for each image in the fisheye, we create a new icon widget. The i variable in the call to create the icon widget is the set of properties we pass from our widget.  (Recall the items array in the ajax tag.)

Inside the onclick function, we call the publish method, passing the topic, which is "/fisheye" and the icon widget corresponding to the icon that was clicked.  The icon, which includes all the properties passed from the tag is what is published.

Now what we need is an application to subscribe to the topic. To do this, we modified the fisheye.jsp page in the dojo-test application included in jMaki.  What the application does now is it displays images of some of Sun's movers and shakers. When a user clicks on an image, the bio matching the image displays on the same page.  Here is the JSP page that does this:

    <a:ajax type="dojo" name="dojo.fisheye"
args="{items:[
{iconSrc:'images/JayashriVisvanathan.jpg',caption:'Jayashri', index:1},
{iconSrc:'images/chinnici.jpg',caption:'Roberto',index:2},
{iconSrc:'images/blog_murray.jpg',caption:'Greg',index:3}
]}"/>


<script>
function fisheyeListener(item) {
var targetDiv = document.getElementById("newpage");
var responseText = "";
var index = Number(item.index);
switch(index){
case 1: // Set responseText equal to Jayashri's bio
break;
case 2: // Set responseText equal to Roberto's bio
break;
case 3: // Set responseText equal to Greg's bio
break;
default: responseText += 'Click on one of the photos above';
break;
}
targetDiv.innerHTML = responseText;
}
jmaki.subscribe("/fisheye", fisheyeListener);
</script>
<p>
<h3><div id="newpage"></div></h3>

Notice that there is a function that subscribes to the "/fisheye" topic. This function passes the reference to the topic into the JavaScript function, fisheyeListener, which is called if a message is published to the topic.

Let's go through what happens when this application runs. First, the fisheye widget renders itself. When the user clicks an icon in the fisheye widget, all the properties for that clicked icon are published to the topic. The JSP page then checks the icon's index property to see which icon was clicked and then replaces the div tag with the appropriate bio:





To see the new fisheye, you need to check out a new jMaki workspace or update your current workspace and then build it. Alternatively, you can browse the code.

To see an example of two jMaki widgets interacting using the publish and subscribe mechanism, download the latest jMaki application and take a look at the Yahoo Map with Geocoder example. With this example, you can enter a location into the GeoCoder widget and a tooltip that points to the location is added on top of the map widget.

One of the great things about this mechanism is that once you publish a topic for a widget, you can subscribe to the topic from any application and respond to a widget event however you like. You don't need to hardcode specific behavior into the widget.


Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.