The Source for Java Technology Collaboration
User: Password:



Carla Mott's Blog

Web Applications Archives


jMaki at Community One day

Posted by carlavmott on May 12, 2008 at 03:41 PM | Permalink | Comments (0)

Last week at Community One day, the jMaki session included a couple of speakers from the community. It is great to see jMaki used in the real world.

We had four speakers at our session and I'll admit it was a lot given we only had an hour. But I was excited to include both Jennifer Myers and Daniel Ziaoure since they are both using jMaki in their projects.

The session was divided as follows. I gave a high level overview of jMaki and talked about the framework, widgets and pub/sub bus. It was pretty quick since I wanted to give others time but I was able to squeeze in a short demo.

Jennifer who also works for Sun talked about project Miso and the interface that they built using jMaki. Project Miso, provides deep, fast and broad search and indexing services and will initially be integrated into the Communication Suite. Currently the project is focussed on email, calendar and Instant Messaging products from Sun. Jennifer used the Yahoo table to display the list of items found in the search and the dcontainer to display the image that was found. Jennifer mentioned that she had no prior Ajax experience prior to starting on the project and found jMaki a great tool for quickly developing the user interface. Jenn-greg.jpg

Daniel Z, an employee of TravleMuse Inc., covered the architecture of his project and showed how jMaki is used in their site. TravelMuse helps travelers save time and make better decisions at every step of the travel planning process by providing the Web’s most user-friendly travel planning experience. Daniel explained how the jMaki framework is used for developing widgets and for widget to widget communication. The application is JSF based. The site is live now with many enhancements coming in the next month at http://travelmuse.com. danielz.jpg

And Greg closed with some of the new features like the performance enhancements and the jMaki webtop that is now available in jMaki 1.8.

Adding jMaki wrapped Yahoo widgets to a GWT app

Posted by carlavmott on May 12, 2008 at 11:11 AM | Permalink | Comments (0)

To prepare for our JavaOne session, GWT and jMaki: Expanding the GWT Universe, I decided I should add a jMaki Yahoo widget to a GWT application. Here is what I did.

I wanted to start with an existing application and I chose the Java PetStore demo application which Greg had rewritten using jMaki widgets and GWT. The code for that application is in the jmaki-store project along with a README.txt containing all the build and install instructions. First I checked out the jmaki-store workspace, built and deployed the application to make sure I had a working copy of the app. Follow the instructions in README.txt file to build and deploy but basically you need to go to the jmaki-store/code/gwt/webapp dir and type ant. There also is a target to deploy the application or you can copy the war file to the auto deploy directory. In my case I chose to deploy to GlassFish V3 and deployment was extremely fast.

I decided to add the Calendar Yahoo widget to the application because I thought it would be pretty straight forward. The following are steps needed to add the widget to the application. First, I had to add an additional class (Calendar, java) in jmaki-store/code/gwt/widgets/sc/java/jmaki/client. Calendar.java contains the following:

  
package jmaki.client;

import jmaki.client.JMakiWidget;

/**
 * Calendar Widget.
 */
public class Calendar extends JMakiWidget {
   
  public Calendar(int width, int height) {
      super(width,height);   
  }     
    
  public String getWidgetName(){
      return "yahoo.calendar";
  }
    
} 

This class extends JMakiWidget which is a wrapper for the jMaki widgets. The Calendar widget has 2 methods, a constructor and the getWidgetName method which returns the name of the widget. Following the jMaki convention the name of the widget is the toolkit name dot widget name.

Next I updated the Widgets.gwt.xml file to list all the dependencies for this widget. It turns out that the list is already in the widgets.json file as that information is needed by the jMaki plugins so I started there. I had to update the paths and reorder the list because here order matters. The Yahoo toolkit CSS files need to appear before jMaki CSS files then the Yahoo toolkit library dependencies and then the jmaki component.js file. jMaki framework will take care of this automatically but in GWT land the list needs to be specified in order. The Widgets.gwt.xml file looks like:

 <?xml version="1.0" encoding="UTF-8"?>
<module>
 <inherits name="com.google.gwt.core.Core"/>
 <source path="client"/>
 <public path="public"/> 
 <script src="resources/jmaki.js"/>
 
 <stylesheet src="resources/jmaki/ibrowser/component.css"/>
 <script src="resources/jmaki/ibrowser/component.js"/>
 
 <stylesheet src="resources/jmaki/resources/styles/themes/charcol/theme.css"/>
 <stylesheet src="resources/jmaki/accordionMenu/component.css"/>
 <script src="resources/jmaki/accordionMenu/component.js"/>

  <stylesheet src="resources/jmaki/cart/component.css"/>
 <script src="resources/jmaki/cart/component.js"/>
 
 <stylesheet src="resources/jmaki/feedreader/component.css"/>
 <script src="resources/jmaki/feedreader/component.js"/>

 <stylesheet src="resources/yahoo/resources/libs/yahoo/v2.5.1/calendar/assets/skins/sam/calendar.css"/>
 <stylesheet src="resources/yahoo/calendar/component.css"/>
 <script src="resources/yahoo/resources/libs/yahoo/v2.5.1/yahoo-dom-event/yahoo-dom-event.js"/>
 <script src="resources/yahoo/resources/libs/yahoo/v2.5.1/element/element-beta-min.js"/>
 <script src="resources/yahoo/resources/libs/yahoo/v2.5.1/container/container_core-min.js"/>
<script src="resources/yahoo/resources/libs/yahoo/v2.5.1/menu/menu-min.js"/>
 <script src="resources/yahoo/resources/libs/yahoo/v2.5.1/button/button-min.js"/>
 <script src="resources/yahoo/resources/libs/yahoo/v2.5.1/datasource/datasource-beta-min.js"/>
<script src="resources/yahoo/resources/libs/yahoo/v2.5.1/calendar/calendar-min.js"/>
<stylesheet src="resources/yahoo/resources/libs/yahoo/v2.5.1/menu/assets/skins/sam/menu.css"/>
<stylesheet src="resources/yahoo/resources/libs/yahoo/v2.5.1/button/assets/skins/sam/button.css"/>
  <script src="resources/yahoo/calendar/component.js"/>
</module>

So far I have listed the resources needed for the widget and now I need to copy those files into the web app. All the resources are in the jMaki bundle so I just need to get what is on the list and add it to my application. Here I cheated a little. I created a project using NetBeans and put a single widget (Yahoo calendar) in the page. Doing so copied in the appropriate resources and so I had the directory I needed to copy for my GWT app. The resources/yahoo/calendar/* directory under the new project was copied to the jmaki-store/code/shared/widgets/resource/yahoo directory in the jmaki-store project.

The last thing I need to do is to add the new widget to the Main window of my app. Edit jmaki-store/code/gwt/webapp/src/java/jmaki/store/client/MainEntryPoint.java to look as follows:

 
package jmaki.store.client;

import com.google.gwt.core.client.EntryPoint;

import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.Widget;

import jmaki.client.IBrowse;
import jmaki.client.AccordionMenu;
import jmaki.client.Cart;
import jmaki.client.Calendar;


public class MainEntryPoint implements EntryPoint {
    
    /** Creates a new instance of MainEntryPoint */
    public MainEntryPoint() {
    }
    
    /**
     * The entry point method, called automatically by loading a module
     * that declares an implementing class as an entry-point
     */
    public void onModuleLoad() {
        DockPanel dp = new DockPanel();
 
        AccordionMenu am = new AccordionMenu("menu.json", 200,400);
         dp.add(am, DockPanel.WEST);
         
       
        IBrowse ib = new IBrowse(400,400);
        RootPanel.get().add(ib);
        dp.add(ib, DockPanel.CENTER);
    
        Cart cart = new Cart(250, 400);
        dp.add(cart, DockPanel.EAST);
       
        Calendar cal = new Calendar(150, 150);
        dp.add(cal, DockPanel.EAST);
       
        RootPanel.get().add(dp);
    }
    
}

Now when you build and deploy the app again you will see the calendar widget in the page. Note that you do not need to change the build files.

It really is pretty easy once you figure out the order that the JavaScript dependencies should be in. Using jMaki wrapped widgets means that 3rd party components can easily be added to GWT.

jMaki at JavaOne

Posted by carlavmott on April 29, 2008 at 12:47 AM | Permalink | Comments (1)

Community One day and JavaOne are just around the corner. Community One day is a free event so we hope you will come out and learn about jMaki, GlassFish and NetBeans. Come to Moscone Center on Monday May 5 for many interesting sessions. Greg and I will be speaking along with some folks from the community.

  • Session: jMaki: The power of Ajax made easy.
    Time: 12:25- 1:20
    Room : Hall E, 133

JavaOne runs Tuesday May 6 - May 9 also at Moscone Center. There's lots of ways to learn about jMaki this year. There are sessions and Hands on labs to help you learn more. Also look for jMaki in the general session on Tuesday.

  • Session: jMaki- Ajax with Java™ Technology Made Easier
    Day: Wednesday, May 07
    Time: 09:30 - 10:30
    Room: Moscone Center - Esplanade 301
  • Hands on Lab: Building Rich Web Applications, Using jMaki
    Day: Wednesday, May 07
    Time: 14:50 - 16:50
    Room: Moscone Center - Hall E 130/131 (LAB)
  • Hands on Lab: Plug Into GlassFish™ V3 With JavaServer™ Faces and jMaki
    Day: Wednesday, May 07
    Time: 18:30 - 20:30
    Room: Moscone Center - Hall E 132 (LAB)
  • Session: GWT and jMaki: Expanding the GWT Universe
    Day: Thursday, May 08
    Time: 09:30 - 10:30
    room: Moscone Center - Esplanade 307-310


Loading data into jMaki widgets

Posted by carlavmott on April 16, 2008 at 05:22 PM | Permalink | Comments (0)

I've gotten a few questions about how to get datainto jMaki widgets. This blogs describes the different ways in jMaki to load data into widgets.

Let's look at the JSP tag for including a jMaki accordionMenu widget in your web application.

 <a:widget name="jmaki.accordionMenu"
      value="{menu : [
       {label: 'Links',
            menu: [
                { label : 'Sun.com',
                  href : 'http://www.sun.com'},
                { label : 'jMaki.com',
                  href : 'http://www.jmaki.com'}
                ]
       },
       {label: 'Actions',
            menu: [
                { label : 'Select',
                  action :{topic: '/foo/select',
                         message: { targetId : 'bar'}}
                },
                { label :'Set Content',
                  action :{topic: '/foo/setContent',
                         message: { value : 'test.jsp'}}
                }
                ]}
                ]
       }" />  

jMaki uses the attributes value and service to pass data to the widgets wrappers. The value attribute is used when the data is located in the page itself and therefore static. We use this feature in the code snippet that is dropped into a page when using an IDE so we don't have to provide a server side component just to get the widget to render correctly. The code snipet allows users to start with a working example which can be easily modified to learn more about the widget and the data model for that widget.

In the tag above the value attribute is set equal to the JSON representation of the data described in the data models for that widget. The data model pages describe the format for the different widgets in jMaki. All the code snipets provided for the IDE follow the data models for the supported platforms, Java, PHP and Ruby.

The value attribute can also be passed a client side value expression. I described how to use the value expression in my last blog, How to load blog feeds into jMaki widgets. Basically, the data is loaded into a local JavaScript variable which is assigned to the value attribute using the "@" character.

Often you will want to load data that is not statically located in the page and in jMaki this is done through the service attribute. The next example shows how to get data from a server side component in your application. The tag above now becomes:

 <a:widget name="jmaki.accordionMenu"
      service="data.jsp" />    

As a quick example I will put the data I want to load into the file data.jsp as follows:

 {menu : [
       {label: 'Links',
            menu: [
                { label : 'Sun.com',
                  href : 'http://www.sun.com'},
                { label : 'jMaki.com',
                  href : 'http://www.jmaki.com'}
                ]
       },
       {label: 'Actions',
            menu: [
                { label : 'Select',
                  action :{topic: '/foo/select',
                         message: { targetId : 'bar'}}
                },
                { label :'Set Content',
                  action :{topic: '/foo/setContent',
                         message: { value : 'test.jsp'}}
                }
                ]}
                ]
       } 

What really is happening here is when data.jsp is processed non-JSP commands are echoed out as they appear in the file. As a result the data I need is returned in JSON format which is what the widget is expecting. This is just an easy way to see how to use the service attribute without having to write a server side component. In reality, you will have to collect the data, format in JSON and print it out. The jMaki 1.1 release contains Java helper classes to create JSON object literals. You can also take a look at Jennifer's blog. The main point is that getting data from a server side component is done using the service attribute.

In PHP the same thing can be done as follows:

 <?php  addWidget( array("name" => "jmaki.accordionMenu",
    "service" => "data.php"
        ));
?>

The data is in a file called data.php (notice it looks just like data.jsp).

{menu : [
       {label: 'Links',
            menu: [
                { label : 'Sun.com',
                  href : 'http://www.sun.com'},
                { label : 'jMaki.com',
                  href : 'http://www.jmaki.com'}
                ]
       },
       {label: 'Actions',
            menu: [
                { label : 'Select',
                  action :{topic: '/foo/select',
                         message: { targetId : 'bar'}}
                },
                { label :'Set Content',
                  action :{topic: '/foo/setContent',
                         message: { value : 'test.php'}}
                }
                ]}
                ]
       }

The jMaki runtime passes the attributes from the tag to the widget constructors. In the case of the service attribute, the widgets make a jmaki.doAjax call to retrieve the data when the widget is initialized. To update the data once the widget has been initialized, you can write a handler which makes additional jmaki.doAjax calls and sends that data to the widget. See my blog on How to implement data pagination in jMaki tables for an example.

jMaki also provides an XMLHttpProxy so you can safely and easily access RESTful Web Services outside the application domain. To access a service through the proxy you use the service attribute too. In this case the tag looks like:

<a:widget name="jmaki.accordionMenu"
      service="/xhp?id=rss" />

By design you will need to use a token key to identify the service to access. The token key is specified in a file called xhp.json in the resources directory. An entry in the xhp.json file looks like:

 {"id": "rss",
      "url":"http://weblogs.java.net/blog/ludo/index.rdf",
      "xslStyleSheet": "rss.xsl"
     }  

The id is "rss" and this entry specifies the name of the style sheet to apply to the returned data by the proxy. In this example, the data is coming back as XML so we want to convert it to JSON. The current style sheet recognizes RSS 1, RSS2, ATOM 1 and ATOM 2 and converts the XML data to JSON. The style sheet is called rss.xsl and is called by the proxy server before the data is handed to the widget. See Arun's blog jMaki - Accessing External Services for more details on how to access external services using jMaki.

jMaki 1.1 developer release available

Posted by carlavmott on March 22, 2008 at 12:00 AM | Permalink | Comments (2)

There's a lot of new functionality in the developer release of jMaki 1.1. Performance enhancements, new widgets, upgrades to Yahoo 2.5 and Dojo 1.0.2, documentation and the new jMaki webtop are just some of what you will find.

The team has been busy creating new widgets such as a flow widget, bread crumbs, tag cloud and carousel are new. Thanks to the awesome work by SitePen, all jMaki native widgets have 2 new themes. Default theme is kame and also available is ocean. Finally, we have updated the jmaki-charting widget lib to support Google and Yahoo charts as well.

jMaki core has some performance upgrades where CSS is injected in the page along with JavaScript code and caching can be turned on. We see a 20-30% improvement. Also there are security improvements because we use the latest json.org secure json parser and only publish events and data to jMaki managed containers.

Yahoo 2.5 and Dojo 1.0.2 toolkits have been integrated and we support both Dojo .4.3 and 1.0.2 widgets in the same page. We also have brought back and improved the widget gallery.

We want to add more and more documentation in this release. Currently we have updated the Getting Started Guide for JSP and are working on the JSF version. The PHP version will follow soon. There are some new blogs on loading blog feeds like feedburner into a widget and supporting GWT with jMaki. Also see Arun's blog, jMaki on Rails. Finally much of the website has been translated to Japanese. Of course, we will be writing more documentation before this release goes final.

Finally, we are working on a new widget called jMaki webtop. The code is not yet available but will be soon. For now we have deployed it on jmaki.com so you can play around with jmaki webtop. You will notice that the widgets in webtop are the same widgets that are available to build jMaki applications. You will also notice that events can be sent and received in webtop just like jMaki web applications. Play around with the webtop and let us know what you think.

How to load blog feeds into jMaki widgets

Posted by carlavmott on March 07, 2008 at 12:12 AM | Permalink | Comments (0)

Recently I wanted to load data from a blog feed into a jMaki widget. Here I describe how to do just that.

The feed I want to read is coming from The Aquarium. I want to view the the title and the first 60 characters of each blog entry using the jMaki blockList widget since it automatically handles paging. The Aquarium uses Feedburner to publish blog entries so I looked for a Feedburner API to read the feed. It also needs to support https to avoid security notifications since the page will be on a java.net project. I found an API that returns the data in JSON format which allows me to provide a callback function to handle the data. This is exactly what I needed since jMaki widgets expect data in JSON format.

To get the data I added the following call to my page.

        <script>
             function processTAFeed(_in) {
             window.taItems= _in;
         }
           </script>
         <script type="text/javascript" 
src="https://api.feedburner.com/format/1.0/JSONP?uri=TheAquarium_en&callback=processTAFeed">
             </script>

The data is now available in the variable taItems in the window object. Next I want to get the data in the widget. First I add the tag to the page that specifies the widget and then I use the value binding option to pass the data. Using the @ notation tells the jMaki client runtime that following is a variable that needs to be resolved so the contents of window.taItem is placed in the value attribute. The tag looks like:

  <a:widget name="jmaki.blockList" 
       args="{filter : 'jmaki.widgets.jmaki.blockList.TAFilter'}" 
       value="@{window.taItems}"  />
                     

Notice that I specified the filter jmaki.widgets.jmaki.blockList.TAFilter. Filters are called by the jMaki client runtime and allow me to manipulate the data before it is passed to the widget.

Before looking at the filter, let's look at the template file for this widget. The blockList widget displays data in a repeating format as specified by the template in component.htm. I updated that template to include the data I want to display and wrote a filter to load the values in the template. Specifically I will replace link, title and shortContent.

<div id="${uuid}" class="jmk-blocklist jmakiBackround">
    <div id="${uuid}_content" class="jmk-blocklist-content">
        <ul id="${uuid}_list">
        </ul>
    </div>
    <div id="${uuid}_nav" class="jmk-blocklist-nav">
            <div id="${uuid}_previous" class="previous">Previous</div>
            <div id="${uuid}_mid" class="mid"></div>
            <div id="${uuid}_next" class="next">Next</div>
    </div>
    <div id="${uuid}_template" style="display:none">
        <div  class="jmk-blocklist-item">
            <a href="@{link}">@{title}</a>
            @{shortContent}<br/> 
        </div>
    </div>
</div>

Now let's look at the filter code as the final step.

jmaki.widgets.jmaki.blockList.TAFilter = function(_in) {
    var maxLength = 60;
    var _rows = [];

    for (var _i=0; _i < _in.feed.items.length;_i++) {
      var _des = _in.feed.items[_i].body;
      
        var rex = new RegExp("\\\\n", "g");
        _des =  _des.replace(rex," ");

        rex = new RegExp("\\\\\"","g");
        _des =  _des.replace(rex,"\"");
        var rex2 = new RegExp("<p>.*?</p>");
        var content = _des.match(rex2)[0];

      if (content.length > maxLength) {
          content = content.substring(0, maxLength) + "... 

"; } var row = { title : _in.feed.items[_i].title, link : _in.feed.items[_i].link, date : _in.feed.items[_i].date, body : _des, shortContent : content }; _rows.push(row); } return _rows; }

The data returned from the feed has several properties such as link, date, title, body. The link and title properties are used without modification. The body property contains the entire blog but recall that I only want to display the first 60 characters. With Greg's help we figured out how to normalize the data and pickup the first paragraph using regular expressions. The blockList takes each row array and creates an entry in a list. The filter needs a bit more work because there is the case where a link tag can appear in the first 60 characters and the closing tag is after the first 60 characters.

Support for the value binding attribute has been available in jMaki since the 1.0 release. As a result of this exercise, we'll create a feedReader widget.

Dojo Dijit widgets and jMaki

Posted by carlavmott on February 12, 2008 at 04:13 PM | Permalink | Comments (9)

We just posted the jMaki wrappers for many of the Dojo Dijit 1.0.2 widgets. Widgets wrapped include the grid, tabbed view, tree, accordion, button, fisheye, calendar and more. All the widgets support the jMaki data models as described on the wiki pages here.

Follow the instructions on Ludo's blog to add the library to NetBeans IDE or simply unzip the file in your jMaki web app and add the appropriate tags to you page. Enjoy!

jMaki wrappers for ExtJs now available

Posted by carlavmott on December 27, 2007 at 10:19 AM | Permalink | Comments (2)

In a joint effort with the ExtJs toolkit team, the jMaki wrappers for the ExtJs 1.1 toolkit are now available, jmaki-ext-1.0.1.zip. Included are wrappers for the menu, grid and tree widgets from the ExtJs toolkit. The wrappers support the jMaki data and event models as described on our wiki.

You have several options for including the widget library in your application. If you use NetBeans follow the instructions for adding the jmaki-charting widget library on Ludo's blog. Simply load the ExtJs library you downloaded instead of jmaki-charting. You can then drag and drop widgets from the palette into your application. Otherwise unzip the widget library into your application and add the appropriate tag to your page. For example, the ExtJs grid tag including default data looks like:

 <a:widget name="Ext.grid"
    value="{columns : [
     { label : 'Title', id : 'title'},
     { label :'Author', id : 'author'},
     { label : 'ISBN', id : 'isbn'},
     { label : 'Description', id : 'description'}
     ],
     rows : [
     { title : 'Book Title 1', author : 'Author 1', isbn: '4412', description : 'A Some long description'},
     { id : 'bar', title : 'Book Title 2', author : 'Author 2', isbn : '4412', description : 'A Some long description'}
     ]
     }" />


jMaki 1.0.3 available

Posted by carlavmott on December 17, 2007 at 08:23 PM | Permalink | Comments (0)

jMaki, a client server framework for creating Ajax web applications, is how shipping release 1.0.3. This release contains several bug fixes, and integrates Yahoo UI 2.4 release. In addition, one of the developers, Ahmad Zawawi, wrote a test harness using JS/glue/JSP and updated the the Yahoo and Dojo unit tests to run in the test harness. Now we can run the unit tests automatically. Currently we are testing that the widgets get loaded. Future plans include integration with 2.4.0 YUI asynchronous Test suite.

Ahmad's work has been a great help in testing this release and we will look to automated testing as part of the builds. I've uploaded the test bundles that contain the latest changes. You can run the tests manually or try out the automated harness.

jMaki 1.0.1 available

Posted by carlavmott on November 17, 2007 at 01:23 PM | Permalink | Comments (0)

jMaki 1.0.1, a client server framework for creating Ajax enabled web applications, is now available. This release contains many bug fixes. Some of the fixes include support for server side internationalization, updates for Ruby templates and updates to the command line tool support.

Try out the new release and let us know what you think.

New widget library for jMaki

Posted by carlavmott on October 07, 2007 at 10:06 PM | Permalink | Comments (4)

I just made a few more widgets available for the jMaki framework. I've included widgets that folks have asked us to provide that did not go into the main release. The new widget library is called extra and is available for download from the widgets project. It includes the revolver widget which we use on the samples page, and the list and ibrowser widgets which were part of the jMaki beta release. The library contains everything you need to run these widgets.

If you are using NetBeans then all you need to do is to click Tools-> Palette -> Add jMaki Library and the library will be added to the palette ready for you to drag and drop items in your application. Otherwise you will have to unzip the library contents in your web application.

jMaki app using Google Gears

Posted by carlavmott on September 28, 2007 at 04:50 PM | Permalink | Comments (0)

I created a simple app as a demo that uses Google Gears for local storage and also sends data to the server upon user request. I showed this at AjaxWorld where there was alot of interest so I decided I would blog about it.

Building on the Get Widget Data Sample that is part of the jMaki bundle, I added Google Gears so that it will be called when the save icon of the editor is clicked. The data in the editor is saved locally each time the editor save button is clicked. I kept the functionality of sending the data back to the server by simply adding a 'submit' button which does a jmaki.doAjax call sending the contents of the editor to a server side component.

If you are using NetBeans you can install the Google Gears Extension comp lib and add the appropriate code by dragging from the palette. To install a comp lib go to tools -> palette -> add jMaki library. If you are not using NetBeans then follow the instructions on Greg's blog on adding google gears extension to you app.

In order to save the editor contents to the local storage add the following code (in addition to the extension handler) to the onSave handler in the glue.js file.

// map topics ending with  /onSave to the handler

jmaki.subscribe("*onSave", function(args) {
    // empty the table then save it
    jmaki.publish("/google/gears/execute",
    { query : 'delete from jmaki',
     callback : function() {
       jmaki.log("Removing Previous Values");
       jmaki.publish("/google/gears/execute",
          { query : 'insert into jmaki values (?, ?)',
             args : [args.value, new Date()],
         callback : function() {
             jmaki.log("Saved " + args.value);
         }
        });
       }
    });
});

This handler gets called each time an onSave event occurs and saves data locally. A real app may use a specific topic for the editor in case other widgets in the application fire an onSave event. In this example I clear the local store each time I save.

I add a button to the the page which will push the contents of the editor to a server side components which can then save the data in a data base there. I've included the code snippet for the button and the editor widgets here:

 <div id="main">
                <div id="leftSidebar">
                    <a:widget name="yahoo.button" value="{label : 'Submit contents', action : {topic : '/submitData'}}"/>
                  
                    
                </div> <!-- leftSidebar -->

                <div id="content" style="height:400px">
                    
                    <a:widget name="dojo.editor" id="myeditor" value="@{window.editorData}" />

                </div> <!-- content -->       
            </div> <!-- main -->


In PHP the code looks like:

 <div id="main">
                <div id="leftSidebar">
                    <?php
  addWidget( array ( "name" =>"yahoo.button" value=>"{label : 'Submit contents', action : {topic : '/submitData'}}" )); 
?>
                  
                    
                </div> <!-- leftSidebar -->

                <div id="content" style="height:400px">
                    
                    <?php
  addWidget( array ( "name" =>"dojo.editor" id=> "myeditor" value=>"Edit this value." )); 
?>

                </div> <!-- content -->       
            </div> <!-- main -->


Notice that I use the id attribute on the editor widget tag. I did this because it is easy to get the widget later in the handler. I also set the topic in the button widget tag so I can easily set the handler.

I now need to add a handler for the button which sends data back to the server. The complete code for glue.js is listed below:

jmaki.namespace("jmaki.listeners");

jmaki.subscribe("/submitData", "jmaki.listeners.editorListener");

jmaki.listeners.editorListener = function(args) {
    var editorId = jmaki.getWidget('myeditor');
    var contentValue = editorId.getValue();
    if ( typeof contentValue != 'undefined' ) {
        jmaki.log("Editor content=  " + contentValue);
        // send data back to server
         jmaki.doAjax({method: "POST",
                               url: "Service.jsp",
                               content: {message: contentValue },
                               callback: function(_req) {
                                   // handle any errors
                               }
                           });
    } 
};

// map topics ending with  /onSave to the handler

jmaki.subscribe("*onSave", function(args) {
    // empty the table then save it
    jmaki.publish("/google/gears/execute",
    { query : 'delete from jmaki',
     callback : function() {
       jmaki.log("Removing Previous Values");
       jmaki.publish("/google/gears/execute",
          { query : 'insert into jmaki values (?, ?)',
             args : [args.value, new Date()],
         callback : function() {
             jmaki.log("Saved " + args.value);
         }
        });
       }
    });
});

jmaki.subscribe("/jmaki/runtime/extensionsLoaded", function() {

  jmaki.publish("/google/gears/execute", 
    { query : 'select * from jmaki order by Timestamp desc',
     callback : function(_rs) {
         if (typeof _rs != "undefined" &&
             typeof _rs.isValidRow != "undefined" &&
             _rs.isValidRow()) {
             // set data on the global window object for later access
             if (typeof _rs.field != "undefined") window.editorData = _rs.field(0);
             else window.editorData = "";
             jmaki.log("Loaded Editor Data: " + editorData);
         } else {
             window.editorData = "";
             jmaki.log("No data available");
         }
         jmaki.log('done');
     }
    });
    
});

The code above shows how I used the settings in the tag to access the editor widget and also send data to the server. When the 'Submit contents' button is clicked the function jmaki.listeners.editorListener is called. That function looks up the editor widget using the id that we set on the widget tag. It then calls a function in the wrapper that returns the contents of the editor. The jmaki.doAjax call send the data back to a server component called Service.jsp.

That's it. I have created a war file of the demo app and posted here so you can see working app.

How to implement data pagination in jMaki tables

Posted by carlavmott on September 19, 2007 at 05:31 PM | Permalink | Comments (6)

The question about paging through data in a table comes up enough that I decided to answer in a blog. Using some code Greg posted in an email a few months back let's create a simple example of paging through data in a table. In this example, we will use the Dojo fisheye widget to drive the pages that are displayed in a Dojo table. Each time the user clicks on an icon the table displays different parts of the data depending on the icon clicked. Most of the work for determining what to display is done in JavaScript code. The data is in a JSP file but can be in some serverside component that returns the data in JSON format. We will use the jmaki.doAjax call to get the data when the page loads.

I created the index page with the standard jMaki layout and added the Dojo fisheye widget in the left side bar and the Dojo table widget in the main area. In this case we will not provide any data for the rows but rely on the paging mechanism to supply all data. index.jsp looks like:

            <div id="main">
                <div id="leftSidebar">
                    
                <a:widget name="dojo.fisheye" args="{orientation:'vertical'}" value="[ 
     {iconSrc:'https://ajax.dev.java.net/images/blog_murray.jpg',
      label : 'Page 1',
      action : { message : {value : 'books1'}}
     },
     {iconSrc:'https://ajax.dev.java.net/images/chinnici.jpg',
      label : 'Page 2',
      action : { message : {value : 'books2'}}
     },
      {iconSrc:'https://ajax.dev.java.net/images/JayashriVisvanathan.jpg',
      label : 'Page 3',
      action : { message : {value : 'books3'}}
     }         ]"/>

                    
                </div> <!-- leftSidebar -->

                <div id="content" style="height:400px">
                    
                 
                    <a:widget name="dojo.table"
                    subscribe="/datatable"
                    publish="/datatable"
                    value="{columns : [
     { label : 'Title', id : 'title'},
     { label :'Author', id : 'author'},
     { label : 'ISBN', id : 'isbn'},
     { label : 'Description', id : 'description'}
     ],
     rows : [
     ]
     }" />

     
            </div> <!-- content -->
        
            </div> <!-- main -->

Some things to note. The fisheye widget publishes to the topic '/dojo/fisheye' unless it is over written. In this case we use the default. Remember that the user will click on an icon in the fisheye and that will result in loading different pages of data. The way that I communicate the page to load is by using an action. In this case I use a strings 'book1', 'book2' and 'book3' to identify the page. The strings are passed using the property 'value'. Finally, notice I reset both subscribe and publish attributes for the table widget. More on this later.

Next I created a JSP called books.jsp which contains all the data we're going to use. The data is already in JSON format. books.jsp looks like:

[
 [
  { id : 'i1', title : 'Book Title 1', author : 'Author 1', description : 'A look at the samples ', url : 'https://ajax.dev.java.net/samples'},
  { id : 'i2', title : 'Book Title 2', author : 'Author 2', description : 'A Some long description', url : 'https://ajax.dev.java.net/samples'},
  { id : 'i3', title : 'Book Title 3', author : 'Author 3', description : 'A Some long description', url : 'https://ajax.dev.java.net/samples'},
  { id : 'i4', title : 'Book Title 4', author : 'Author 4', description : 'A Some long description', url : 'https://ajax.dev.java.net/samples'},
  { id : 'i5', title : 'Book Title 5', author : 'Author 5', description : 'A Some long description', url : 'https://ajax.dev.java.net/samples'}
 ],
 [
  { id : 'i6', title : 'Book title 6', author : 'Author 2', description : 'A Some long description', url : 'https://ajax.dev.java.net'},
  { id : 'i7', title : 'Book title 7', author : 'Author 2',  description : 'A Some long description', url : 'https://ajax.dev.java.net'},
  { id : 'i8', title : 'Book title 8', author : 'Author 2', description : 'A Some long description', url : 'https://ajax.dev.java.net'},
  { id : 'i9', title : 'Book title 9', author : 'Author 2',  description : 'A Some long description', url : 'https://ajax.dev.java.net'},
  { id : 'i10', title : 'Book Title 10', author : 'Author 2',  description : 'A Some long description', url : 'https://ajax.dev.java.net'}
 ],
 [
  { id : 'i11', title : 'Book Title 11', author : 'Author 3', description : 'A Some long description', url : 'https://ajax.dev.java.net/about'},
  { id : 'i12', title : 'Book Title 12', author : 'Author 3', description : 'A Some long description', url : 'https://ajax.dev.java.net/about'},
  { id : 'i13', title : 'Book Title 13', author : 'Author 3', description : 'A Some long description', url : 'https://ajax.dev.java.net/about'},
  { id : 'i14', title : 'Book Title 14', author : 'Author 3', description : 'A Some long description', url : 'https://ajax.dev.java.net/about'},
  { id : 'i15', title : 'Book Title 15', author : 'Author 3', description : 'A Some long description', url : 'https://ajax.dev.java.net/about'}
 ]
]

The data is formated as an array of arrays of objects. Each array of objects is a page of data. Most of the ids in the data should look familiar as they map to the columns. The last element is a url. It is not represented on the page but can be used. As you will see we will write the code so when the user clicks on the row we will navigate to that url. In order to get that url we need to write a handler for the onSelect event for a table. The handler will be listening to the '/datatable/ topic and that is why we added a publish argument to the table tag.

Finally I updated the glue.js file to add the JavaScript code for getting the data and providing the appropriate data for the table. The JavaScript code follows:

/*
 * These are some predefined glue listeners that you can
 *  modify to fit your application.
 *
 * This file should not placed in the /resources directory of your application
 * as that directory is for jmaki specific resources.
 */

// uncomment to turn on the logger
jmaki.debug = true;
// uncomment to show publish/subscribe messages
jmaki.debugGlue = true;


var books; // load using an ajax request

jmaki.doAjax({
  url : "books.jsp",
  callback : function(req) {
   books = eval(req.responseText);
   jmaki.log("Loaded Books " + books);
  }
});



// map to the defualt topic /dojo/fisheye to fisheye handler
jmaki.subscribe("/dojo/fisheye*", function(args) {
    switch (args.message.value) {
        case  'books1' : {
            // clear the rows
            jmaki.publish("/datatable/clear", {});
            jmaki.publish("/datatable/addRows", { value : books[0]});
            return;
        }
        case  'books2' : {
            // clear the rows
            jmaki.publish("/datatable/clear", {});
            jmaki.publish("/datatable/addRows", { value : books[1]});
            return;
        }
        case  'books3' : {
            // clear the rows
            jmaki.publish("/datatable/clear", {});
            jmaki.publish("/datatable/addRows", { value : books[2]});
            return;
        }

    }
 });

 // the handler for the datatable
jmaki.subscribe("/datatable/onSelect", function(args) {
/*    var row = getRow(args.targetId);
    if (row){
        jmaki.log("url=" + row.url);
        window.location.href = row.url;
    }
    */
    if(args.value && args.value.url){
        jmaki.log("url=" + args.value.url);
        window.location.href = args.value.url;
    }
});

// find the row
function getRow(targetId) {
  for (var i=0; i < books.length; i++) {
      for (var ii=0; ii < books[i].length; ii++) {
          if (books[i][ii].id == targetId) return books[i][ii];
      }
  }

}
The first thing that happens is I make a jamki.doAjax() call to get the data and store it locally. Then I define two handlers to manipulate the data. I subscribe to '/dojo/fisheye' and based on which string I get (book1, book2, book3) I publish the appropriate section of data to the '/datatable' topic which the Dojo table is subscribed. This way I control what is loaded into the table. Since I formated the data in way that matches the table data model paging becomes really easy.

I also have a handler for the onSelect event from the table. When the user clicks on a row the table widget will automatically publish the id of the row that was selected. There have two ways of getting the url. Since this is a table widget the data of the selected row is included in the payload so I can just look at the value of the url property. The second way to find the url is to get the targetId property which tells me the id of the thing that was selected (true for all onSelect events) and use that to traverse through the data and find the appropriate row. Then I can just access the url property. I included the code for both since both are useful.

Tha's it. You now have a way of paging through the data in the table widget in jMaki.

Simple end to end jMaki application

Posted by carlavmott on September 11, 2007 at 12:55 PM | Permalink | Comments (0)

This blog describes how to use jMaki actions and events to drive behavior or data in widgets. I will build a simple end to end application that shows the main concepts of widgets driving widgets (behavior) and also getting data from a server when needed.

I actually created two versions of the application, JSP and PHP, for this blog, Each have three Yahoo buttons named 'select CA', 'set Values' and 'reset Values' and one Dojo combobox. The buttons will drive the content of the combobox. In this application, one of the buttons will cause the application to access the server for data which will become the values in the combobox.

The main code of the JSP page looks like:

 <div class="main">
     <div class="leftSidebar">
                    
        <a:widget name="yahoo.button" value="{label : 'select CA', 
                     action : {topic : '/combobox/select', message : {targetId : 'bar'}}}"/>
        <a:widget name="yahoo.button" value="{label : 'setValues', 
                     action : {topic : '/mytopic/setvalues'}}" />
        <a:widget name="yahoo.button" value="{label : 'resetValues', 
                     action : {topic : '/mytopic/resetvalues'}}" />           
     </div> <!-- leftSidebar ->

     <div class="content" style="height:400px">
                    
        <a:widget name="dojo.combobox" subscribe="/combobox"
            value="[
                 {label : 'Alabama', value : 'AL'},
                 {id : 'bar',label : 'California', value : 'CA'},
                 {label : 'New York', value : 'NY', selected : true},
                 {label : 'Texas', value : 'TX'}	           
            ]" />

      </div> <!-- content -->
        
  </div> <!-- main -->

The PHP looks like:

<div class="main">
     <div class="leftSidebar">
                    
        < addWidget( array("name" => "yahoo.button", "value"=>"{label : 'select CA', 
                     action : {topic : '/combobox/select', message : {targetId : 'bar'}}}"/>
        < addWidget( array("name" => "yahoo.button",
                                     "value" => "{label : 'setValues', 
                     action : {topic : '/mytopic/setvalues'}}" />
        <addWidget( array("name" => "yahoo.button",
                                     "value" => "{label : 'resetValues', 
                     action : {topic : '/mytopic/resetvalues'}}" />           
     </div> <!-- leftSidebar ->

     <div class="content" style="height:400px">
                    
        < addWidget( array("name" => "dojo.combobox",
                                       "subscribe" => "/combobox",
                                       "value" => "[
                 {label : 'Alabama', value : 'AL'},
                 {id : 'bar',label : 'California', value : 'CA'},
                 {label : 'New York', value : 'NY', selected : true},
                 {label : 'Texas', value : 'TX'}	           
            ]" />

      </div> <!-- content -->
        
  </div> <!-- main -->

As an aside, I'd like to point out that the data model for the widgets is the same for the two platforms.

Notice that I used jMaki actions to drive the combobox. We can select a value to be displayed in the combobox by simply publishing an event to a topic along with the id of what we want selected. In jMaki, we use publish and subscribe extensively in widget to widget communication. See my article A practical guide to jMaki events for more information on the publish/subscribe mechanism in jMaki. Let's look at how to use actions more closely.

In the first button, we want to select one of the items, California, in the combobox. To get the desired result, we use the action property to publish to a topic. The combobox implements the jMaki combobox data model which means it implements the data model and two handlers, select and setValues. This means that there is code in the widget wrapper that is called when an event is published to /dojo/combobox/select and /dojo/combobox/setValues. You have the option to override the topic name if you like. In this example I have overwritten the default topic to be /combobox. Now to select the item 'California' all I need to do is send an event to the appropriate topic with the id of the item I want selected. As you can see in the combobox tag above I used the id 'bar' in the second item. I pass that same id as the targetId property in the action object. An event is published to the '/combobox/select' topic along with a payload containing a value object with the value to be selected. The underlying widget initialization code takes care of executing the appropriate code needed to select the item. That's right, you didn't have to write any JavaScript code at all. We believe that simple operations should be just that simple.

In the case of selecting which item will be displayed in the combobox we had all the data that we needed. Some times however, you may want to get data from a data base and so you will need to write a handler to do that. The second button causes the application to make a call back to the server to get data and replaces the values in the combobox with that new data. In that action object I simple have a topic property where I have specified a new topic name and that's all. This means that an event is published to that new topic. I then need to add a handler which will provide the appropriate code which is associated with that topic. To do that I add JavaScript code in the glue.js file which the framework automatically loads with each page. To associate my new handler to the topic that the action object is publishing to I use the jmaki.subscribe function. See the code below:

jmaki.subscribe("/mytopic/setvalues", function (args) {

   jmaki.doAjax({method: "POST",
               url: "data.jsp" ,
                callback: function(_req) {
                    var tmp = _req.responseText;
                    var obj = eval ("(" + tmp + ")"); 
                    jmaki.publish("/combobox/setValues",  obj );
                    // handle any errors
                }
   });

});

All I have to do is use the same string in both the topic property and the jmaki.subscribe function and the handler will get called.

Once in my handler, I use the jmaki.doAjax call to connect to the server code. This function is a generalized XMLHttpRequest call which can be used from evaluated code. jmaki.doAjax also allows you to set a timeout which will abort the call to the server if exceeded, it encodes any content before contacting the server and it provides some basic error handling.

In this application the server code simply returns the data in JSON format. For the purpose of this blog I created a JSP and PHP file that contained the data to be returned. Note that the filename in the jmaki.doAjax call must match the name of the file you created. I do have to convert the data returned to a JSON object because what is returned is a string so here I used the eval function and then publish that object as the payload to another topic. By publishing the data to the '/combobox/setValue' topic I have sent the data that I want loaded in the combobox to the widget because it is already subscribed to that topic.

The contents of data.jsp or data.php follows:

[ {  label: "Taipei, Taiwan ", value: "Taipei, Taiwan" , selected: true } , 
{  label: "Shanghai, China", value: "Shanghai, China" },
{ label: "Rome, Italy", value: "Rome, Italy"},
{ label: "Paris, France", value: "Paris, France"}]

For completeness I have include the handler code for the reset button. I used an action to call another handler but I didn't access the serve r to get the data as it included in the handler code itself.

jmaki.subscribe("/mytopic/resetvalues", function(args) {
 var list = [
       {label : 'Alabama', value : 'AL'},
       {id : 'bar',label : 'California', value : 'CA'},
       {label : 'New York', value : 'NY', selected : true},
       {label : 'Texas', value : 'TX'}	           
    ];
  jmaki.publish("/combobox/setValues",  list );
});

As you can see using jMaki actions simplifies the communication between widgets. Something that I didn't show in this blog is calling multiple actions at one time. You also have the option to specify an array of action objects so that multiple events are fired with just one click. One final note, it is also possible to chain actions. I can specify an action which in turn causes another action to be executed. An example would be a button could drive the selection of a combobox which in turn can drive another combobox. It is quite easy to build an interactive web application using jMaki.

Building web 2.0 apps with jMaki made even easier

Posted by carlavmott on August 09, 2007 at 12:19 PM | Permalink | Comments (4)

Since I posted a blog last December on building web 2.0 apps with jMaki, several new features have been added to make building the app much easier. This blog shows the new way to build the same app using the new features.

jMaki is a light weight framework for developing JavaScript centric Ajax-enabled web applications using Java, Phobos and PHP. In this blog I will show how to use one of the layout templates, various widgets, the dynamic container and the glue feature that are part of jMaki to quickly build a web 2.0 application.

Again I will use NetBeans to build the application but it is not required. The app will use a Dojo fisheye widget to drive the content of the page just like before. Let's get started.

You will need jMaki .9.7 (RC2) release or later of jMaki. This is supported by the NetBeans 1.6.9.9.9.5 and Eclipse plugins for jMaki.

Create a web application in Netbeans and select the default page layout.

layout.gif

In the 'left side bar' drag and drop the Dojo fisheye widget. Set the orientation of the fisheye widget to be vertical by adding the following to the tag.

args="{ orientation:'vertical'}"

The entire tag should look as follows:

    <div class="leftSidebar">
                   
                    
      <a:widget name="dojo.fisheye"  args="{ orientation:'vertical'}"
                
      value="[{iconSrc:'https://ajax.dev.java.net/images/blog_murray.jpg',
       label : 'You are here!',
       action : { topic : '/foo/select', message : {targetId : 'bar'}}
                              },
       {iconSrc:'https://ajax.dev.java.net/images/chinnici.jpg',
       label : 'test3'},
       {href : 'http://jmaki.com', iconSrc:'https://ajax.dev.java.net/images/JayashriVisvanathan.jpg',
       label : 'test4'}
       ]"/>
                    
                    
    </div> 

Notice that now we have action properties in the widgets. See Greg's blog about actions for more information. action properties are used to publish information such that other widgets can consume it. It simplifies widget to widget communication because it makes use of the publish/subscribe mechanism that is already part of jMaki. The action property can set a topic for the element and a message or payload that is passed along. In previous implementations of jMaki the url property was published to a topic. Now we set the property we want to pass along. See the model pages for the events and payloads expected by the various widgets. You'll see how to use this shortly.

Create the page which is to be loaded when we click on an icon. This step has not changed.

mapit.gif

Add the geocoder and the google map widgets to the page and save.

So far nothing has changed from what we did before but here is where things get interesting. Recall that we want to use the fisheye widget to load other web pages. Specifically we want to click on an image and load a page based on the image that was clicked. In other words, we want to connect the action of clicking on an image in the fisheye widget to loading the map in the main content area. To do this we will use the action property and now we don't need to write any glue code. Using action in this way works because we know the url that we want loaded and that url is the same each time that image is clicked. We are not doing additional processing such as determining the url to publish so we really don't need to write any JavaScript. That's right, the easy things just got easier. So change the fisheye widget to use action to publish to a topic the url that is to be loaded. The code looks like:


 <a:widget name="dojo.fisheye" args="{ orientation:'vertical'}" value="[ 
                              {iconSrc:'https://ajax.dev.java.net/images/blog_murray.jpg',
 label : 'You are here!',
 action : { topic : '/foo/select', message : {targetId : 'bar'}} },
  {iconSrc:'https://ajax.dev.java.net/images/chinnici.jpg',
  label : 'test3', 


  action: {topic : '/jmaki/dcontainer', message:   'mapit.jsp'}},


  {href : 'http://jmaki.com', iconSrc:'https://ajax.dev.java.net/images/JayashriVisvanathan.jpg',
      label : 'test4'}
      ]"/>

This means that when the user clicks on the second image; the page with the map is loaded. This is done through the action property which publishes mapit.jsp as the message or payload to the topic /jmaki/dcontainer. Now we need a dcontainer widget that is listening or subscribed to this topic. The dcontainer widget knows what to do will a payload containing just a url in it. Previously we did all this in the glue code. We had a handler which extracted the url property from the fisheye widget and published it to another topic. Again the dcontainer was listening to that topic knew what to do with the url and everything worked. The action tag allows us to specify the topic to publish to and the contents of the payload so no additional code is necessary.

The last step to building the app is to add the dcontainer widget to the main content area.

  <a:widget name="jmaki.dcontainer" subscribe="/jmaki/dcontainer" 
   args="{iframe : 'true'}"/>
                    

As before the topic that the dcontainer is listening to must be the same as the one the fisheye widget is publishing to. We now use the subscribe attribute on the widget tag to assign topics. Previously we set topics in the args attribute. That was changed so that there are publish and subscribe attributes on the tag. Widgets can subscribe to more than one topic though only publish to one. Finaly, since we are loading a page which has Google maps we need to set iframe property to true for the page to render correctly.

That's it! No need for Glue code because the url we pass is not calculated but static. The underlying publish and subscribe mechanism handles delivering the data to the widgets and the widgets all handle a set of the payloads correctly so simple operations are trivial to code.

In the next, blog I will show how use actions and glue code to load data dynamically.

jMaki data models formally specified

Posted by carlavmott on July 30, 2007 at 10:32 PM | Permalink | Comments (0)

The jMaki data models have been formally specified and as of last week, build .9.6 implements all specifications. The data model pages include the formal specification of the data expected by the widgets. They also include information about the event types and payloads published by the widgets as well as the event types and payloads expected by the widget subscribers. You will find lots of examples to help you get started.

When you look at the pages you will see that the data models are described using BNF. I like this format because it specifies what is legal as well as what is not legal. The data models are defined for the various types of widgets such as menus, trees. tables, tabbed views etc. The data models are consistent across the widgets regardless of the underlying toolkits. The jMaki widget wrappers convert the data from the jMaki data models to the model the underlying toolkits expects. This way you can switch between the toolkits without having to change the data format. Also the widget wrappers include publishers and subscribers so that dynamic widget to widget communication is greatly simplified. I'll talk more about the publishers and subscribers later in this blog.

In all cases you will see a set of properties that are common across the models. I'll go over some of these properties but see the main model page for a complete description.

  • id - id of the item such as a tab, table row or tree node. You use this property to identify that item.
  • label - the label or title of a tab, column, tree node or menu item. In the past we were not consistent across the data models but now have settled on label as the identifier.
  • href - indicates that the following string is a url and that when clicked we navigate to that url.
  • include- indicates that the following string is a url that we include in a container in the page.
    • action - indicates that the following object is used to communicate some action in most cases to other widgets.
    • topic this string resets the topic name for this element only
    • message can be a string (usually a url) or an object which contains data passed to another widget
  • targetId - the id of the element the action is to affect. This was set using the id property above. targetId is used regardless of whether the element is a node, row, tab etc.

    We tried to be consistent across the models so that users would learn one model and most if not all the information would carry over to the other models.

    Something that is new to the models is the action property. The action property is a declarative way of associating widget behavior. This is extremely powerful for simple operations because no JavaScript code is required to affect another widget. As a result of adding actions we found that we needed to describe the event model as well. Widget to widget communication is simplified because now the widgets also subscribe to various topics out of the box. They also include handlers for those topics. This means that you can publish to a topic which a widget is subscribed to, passing along the correct data and you can affect the behavior of that widget. This works much the same way as I described in my previous blog jMaki - widgets talking to widgets only you pass all the needed information as an action. See Greg's blog for a example on how to use actions .

    As I mentioned above the widgets now subscribe to topics and handle certain events. The underlying mechanism for communication is still publish/subscribe (see the article 'A practical guide to jMaki events' for details on events in jMaki). The main idea is that widgets now subscribe to one or more topics such as '/yahoo/tabbedview/select'. There is a handler in the widget code which parses the message or payload and performs some action based on the topic name and the payload received. Consider the case of the tabbed view. The widget subscribes to the topic 'select' and contains a handler which expects the id of the tab which should be selected. By simply publishing a message to that topic containing the tab id to be selected you can affect which tab is visible on the page. What all can you do? What are the subscribers and what data is required? All these questions are answered in the model pages. You will find the list of events that are handled as well as the payload expected for each type of event.

    jMaki - widgets talking to widgets

    Posted by carlavmott on July 29, 2007 at 09:51 AM | Permalink | Comments (4)

    Widgets talking to widgets has just become a lot easier in jMaki. The .9.6 build or first Release Candidate fully supports the data models we have recently specified. You will find the formal specifications on the wiki model pages. We wanted to specify the data passed to the widgets so users know what the widgets expect when loading data. We found that the models also need to describe the event payload that is published and the event payload expected for the subscriber topics now included in the widgets. This is useful when wanting to dynamically update the data in the widgets. The pages include several examples to get you started. Because jMaki has a standard data model for each of the widgets and each widget subscribes as well as publishes to topics, it is very easy to dynamically update the widgets.

    In this blog I'll show how to build a simple application using the various widgets from the different toolkits and I'll wire the widgets so that they talk to each other. With the 9.6 release of jMaki widgets now subscribe to topics as well as publish events. We will use the publish and subscribe mechanism to tell the widgets how to update the data the widget is contains. See the the article A practical guide to events in jMaki for more information on the publish and subscribe mechanism in jMaki. The application I will build will have 2 buttons, one to add a rows to tables and a button to remove rows from a table. It will also contain 3 table one for each of the toolkits with tables. You will need jMaki 9.6.1 or later. Let's get started.

    Create a project with the standard layout. In the side bar create 2 buttons. I used Yahoo buttons from the palette. Set the labels so that one button will add a row of data to the tables and the other will remove data from the tables.

        <a:widget name="yahoo.button" publish="/button/addTable" args="{label : 'Add table data' }"/>
                        
        <a:widget name="yahoo.button" publish="/button/removeTable" args="{label : 'Remove table data' }"/>
                        
     

    In the main content section, add 3 table widgets one from Dojo, one Yahoo and one from Ext JS. In each table, set the subscribe arg to '/table/topic'. Each table will subscribe to the same topic so that in our event handler we only need to publish one event and affect all tables.

                
       <a:widget name="Ext.grid" subscribe="/table/topic"
              value="{columns : [
                { 'label' : 'Title', 'id' : 'title'},
                { 'label':'Author', 'id' : 'author'},
                { 'label': 'ISBN', 'id' : 'isbn'},
                { 'label': 'Description', 'id' : 'description'}
                ],
                rows : [
                 { 'title' : 'Book Title 1', 'author' : 'Author 1', 'isbn': '4412', 'description' : 'A Some long description'},
                 { id : 'foo', 'title' : 'Book Title 2', 'author' : 'Author 2', 'isbn': '4412', 'description' : 'A Some long description'}
                 ]
                }" >
                        
      <:widget name="dojo.table" subscribe="/table/topic"
                 value="{columns : [
                { 'label' : 'Title', 'id' : 'title'},
                { 'label':'Author', 'id' : 'author'},
                { 'label': 'ISBN', 'id' : 'isbn'},
                { 'label': 'Description', 'id' : 'description'}
                ],
                rows : [
                 { 'title' : 'Book Title 1', 'author' : 'Author 1', 'isbn': '4412', 'description' : 'A Some long description'},
                 { id : 'foo', 'title' : 'Book Title 2', 'author' : 'Author 2', 'isbn': '4412', 'description' : 'A Some long description'}
                 ]
                }" >
                        
      <:widget name="yahoo.dataTable" subscribe="/table/topic"
                value="{columns : [
                { 'label' : 'Title', 'id' : 'title'},
                { 'label':'Author', 'id' : 'author'},
                { 'label': 'ISBN', 'id' : 'isbn'},
                { 'label': 'Description', 'id' : 'description'}
                ],
                rows : [
                 { 'title' : 'Book Title 1', 'author' : 'Author 1', 'isbn': '4412', 'description' : 'A Some long description'},
                 { id : 'foo', 'title' : 'Book Title 2', 'author' : 'Author 2', 'isbn': '4412', 'description' : 'A Some long description'}
                 ]
                }" >
                        
    

    So far we have added widgets to the application and now want to glue widgets together using the new features in jMaki.

    In the glue.js file we need to add a handler that will add data to the tables when the 'Add table data' button is clicked. We will use the publish/subscribe mechanism to perform these operations. Also we need to add handler to remove data from the tables. Note that I will uncomment out the 'debugGlue = true' line in the glue.js file. This shows me all the events that are published and if there is a subscriber for the event. It really helps when working with events to "see" what is published to a topic and if there is a listener.

    
    jmaki.namespace("jmaki.listeners");
    
    //yahoo button adds the onClick to the end of the topic name.
    jmaki.subscribe ("/button/addData/onClick", "jmaki.listeners.addTableData");
    
    jmaki.listeners.addTableData = function(args) {
    //set the row data
    var row =  [
             { title : 'Book Title 3',
               author : 'Author 3',
               isbn: '4415',
               description : 'A Some long description'
             },
             { title : 'Book Title 4',
               author : 'Author 4',
               isbn: '4416',
               description : 'A Some long description'
             }
          ];
    // send the row data 
    jmaki.publish("/table/topic/addRows", { value : row });
    }
    

    Now that we can add rows to the tables let's implement the feature to remove data. Again we can write a handler that is invoked when the button 'Remove table data' is pressed. That handler will remove the row with a specific id. Note that the row ids must be unique.

    
    jmaki.subscribe ("/button/removeData/onClick", function(args) 
    {jmaki.publish("/table/topic/removeRow", {targetId : 'foo'})})
    
    
    

    This works because all the table widgets subscribe to the same topic and support the subtype 'addRows' which allows the add operation. The tree widgets support similar subtypes (like addNode and removeNode). Most widgets in jMaki now subscribe to a topic and have handlers associated with events that can be used to modify the data in the widget. See the individual data model pages for the list of event subtypes supported by the various widgets. I have uploaded the war file update tables for this application for those who wish to start with that. The actual web application name is WebApplication11.

    New Update fetaure in jMaki NetBeans plugin

    Posted by carlavmott on June 21, 2007 at 12:24 PM | Permalink | Comments (0)

    The jMaki NetBeans plugin now has an update feature which automatically updates the version of jMaki that is included in your app. This means that the appropriate files are copied from the new release of jMaki into your application so you don't have to do it yourself. As part of the update, the entire resources directory structure that is part of your application is copied into a resources.zip just in case you made a change to one of the jMaki files. Only the files under the resource directory are updated. None of the application files are touched.

    The steps for updating your application are pretty easy.

    1. Right click on the project you want to update and select Properties.

      upgrade_properties.gif

    2. Select Frameworks from the left nav bar.
    3. Click on Update jMaki resources

      update_jmaki.gif

    4. When the update is complete, click OK

        That's it! Although you are told to back up the resources directory the update feature will do that for you. You will get a dialog with the location of the zip file that was created from your project in case you need to retrieve the old files in the resource dir.

        One thing to note is that the current update feature does copy in only the libraries that already exist in your application, however, it will copy in the entire toolkit library. For example, if your application includes a Yahoo menu widget, once updated it will contain all the files that are part of the Yahoo toolkit and the wrappers for those widgets. This means that the applications size may be a little bit bigger than before the update. If size is an issue you can go into the resources directory and manually prune the unused files.

        Updating to a new version of jMaki is now alot easier with the update feature. Thanks to Ludo for providing it!

        jMaki .9.3 release available

        Posted by carlavmott on June 11, 2007 at 01:04 PM | Permalink | Comments (0)

        We just released jMaki .9.3 which contains a few bug fixes including one for the Flickr wrapper to access Flickr, changes to the Dojo editor wrapper and the initial release of the extension mechanism which allows behavior/functionality that are shared among widgets. See Greg's write up on extensions for more information.

        Making jMaki service arg consistent

        Posted by carlavmott on June 11, 2007 at 12:57 PM | Permalink | Comments (1)

        We are going through the jMaki widget wrappers making sure that they all are consistent in how they support the 'service' arg. The 'service' arg is used to provide data for the widget where the data is from an external source. This means that a URL is provided to the 'service' arg. In many samples, we specify a JSP which contains the data. This is purely for convenience as the URL can also point to a servlet or other Java EE component.

        Previously the Dojo Editor wrapper used the service arg to provide a URL to a servlet which would be called on an onSave event and was expected to handle saving the contents of the editor data. While this is useful it is inconsistent with the way other widgets use the 'service' arg. In the interest of consistency and simplifying the programming model, I changed the editor wrapper so that the 'service' arg now provides data to the widget. This means that the web developer can load the editor with an existing document which can then be edited using the 'service' arg. For example,

         <a:widget name="dojo.editor"  service="/data.jsp"/>
        

        In this case, the contents of the editor when rendered comes from data.jsp.

        But we still want to get the data from the editor for and save it. No worries. This can be done through the Glue code. See the getwidgetdata sample for an example of getting the contents of the editor. The sample also shows how to send the data back to a servlet for further processing.

        Big changes in jMaki

        Posted by carlavmott on April 26, 2007 at 11:57 PM | Permalink | Comments (2)

        jMaki .9 release was pushed out last week. We are feature complete! There were some significant changes to the framework with this new release.

        First, the widgets are in a separate project (widgets.dev.java.net). With each toolkit, we pruned the wrappers and included only widgets which are high quality. In the case of Yahoo, several new widgets have been wrapped. Each toolkit is built as a component library and the NetBeans plugin has been updated to only add the libraries that are used in the application where previous versions included all toolkits in each web applcation. Also the Ext widget toolkit has been added to jMaki. Finally, all widgets were updated to publish events to a topic.

        Only the core framework remains in ajax.dev.java.net. This was done so we can stabalize the core and provide widgets at a different rate than the core. Much of the Java server code has been rewritten to be cleaner and more performant. The tags changed to be more descriptive. you will need to use the following:

      1. <%@ taglib prefix="a" uri="http://jmaki/v1.0/jsp" %>
      2. <%@ taglib prefix="a" uri="http://jmaki/v1.0/jsf" %>
      3. change < a:ajax ... > to < a:widget ... >
      4. Also there updates to Glue code to include the ability to specify Glue code on a per page basis. Creating mashups with RSS feeds is also easier with the use of Filters. Now you can provide code to read the stream and create the JSON formatted data. Finally, another key feature in this release is the ability to add themes to the application including support in the Netbeans plugin. All downloads are still available from the ajax.dev.java.net project. See the samples as they have been updated to take advantage of the new features.

        Finally, this week Ludo added an upgrade button to the project. This allows you to upgrade you web app to the latest release of jMaki. It makes a backup of you app and udpates you application to the new version. The plugin has been updated and available for you to try out.

        jMaki at JavaOne

        Posted by carlavmott on April 25, 2007 at 10:35 PM | Permalink | Comments (0)

        Looks like you'll get to see jMaki in several places at JavaOne this year. Greg Murray and I have a session TS-6375 jMaki: Web 2.0 App Building Made Easy. We'll give an overview of jMaki and the architecture, talk about some of the features like Glue and the data models, go over the value proposition and give some cool demos.

        If you want to get your hands dirty then the following labs will interest you. Schedule info

      5. Building Ajax-Enabled JavaServer Faces Components and Web Applications With jMaki, Dynamic Faces, and the NetBeans IDE
      6. Benchmarking and Profiling Web 2.0 Applications for Performance
      7. Also look for us at our booths at ComunityOne day, May 7 and in the Pavilion during JavaOne. See a demo, ask us questions or just stop by and say hi.

        jMaki widget data model explained

        Posted by carlavmott on April 24, 2007 at 01:33 PM | Permalink | Comments (1)

        In jMaki, each type of widget (tree, table, menu ...) has the same data model regardless of the toolkit which provides the widget. This is a value proposition in jMaki which we believe very useful. What this means is that you can use a table from Yahoo to display your data and if later you decide that the table from Dojo better suites your needs then you can switch to the Dojo widget but not have to change the format of the data. With jMaki you learn a data model and use it with any toolkit implementation. Below I describe the models for tables or grids, trees, accordions, and menus. All widgets in jMaki expect data in JSON format and as you will see I use that format to describe data models.

        Now, does this mean that all toolkits support the same functionality? There are cases where some toolkits support a more complicated structure than others. For example, Yahoo menus can have submenus where jMaki menus can not. In theses cases, you can still feed the same data to jMaki menu as Yahoo but currently jMaki will ignore some of the values. In cases where the widget from a particular toolkit supports additional functionality that is passed to the underlying widget. If the support is not available that data is ignored. We do this in the widget wrappers so the underlying toolkit only gets data it understands.

        Data model for tables/grid widgets:

        Provide column and row data as separate arrays in an object literal format.

        {
           'columns' :[
                {'title' : 'Company', 'width' : 200, locked:false}, 
                {'title' : 'Price', 'width' : 75, 'renderer': 'usMoney'}, 
                {'title' : 'Change', 'width' : 75, 'renderer': 'change'}, 
                {'title' : '% Change', 'width' : 75, 'renderer': 'pctChange'}, 
                {'title' : 'Last Updated', 'width' : 85, 'renderer': 'italic'}
                ],
               rows : [
                ['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
                ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
                ['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am']
            ]
        }
        

        Data model for trees:

        Note that the 'expanded' property is defaulted to false for subtrees.

        {
                   'root' : {
                     'title' : 'Yahoo Tree Root Node',
                     'expanded' : true, 
                     'children' : [
                     { 'title' : 'Node 1.1'},
                     { 'title' : 'Node 1.2',
                       'children' : [
                        { 'title' : 'Node 3.1',
                        'onclick' : {'url' :'foo'}}
                        ]
                     },
                     { 'title' : 'Node 4.1'},
                     { 'title' : 'Node 4.2'}
                     ]
                  }
         }
        

        Data model for menus:

        Not all menus support submenus and those that don't skip the entries for the submenus in the data. The 'label' property is followed by either a 'menu' or 'url' property.

        
         menu: [
            { 'label': 'Images',
                'menu' : [
                  {label:'Birds', url: 'jsonibrowse.jsp'},
                  {label:'Cat', url: 'ibrowse.jsp'}
              ]
             },
             {label: 'Bookmarks',
                'menu' : [
                   {label:'Digg', url:'digg.jsp'},
                   {label:'Delicious', url:'delicious.jsp'}
                 ]
              }                
           ]
        }
        

        Data model for tabbed view:

        content is used to provide static inline data. url points to a page which will be loaded in the specified tab.

        {
          'tabs' :[
                       {'label' :'My Tab', 'content' : 'Some Content'},
                       {'label' :'My Tab 2', 'url' : 'tab1.jsp'}
                     ]
        }
        
        

        Data model for accordian:

        content is used to static inline data. url is used to point to a page which will be loaded in that area.

        {'rows' : 
            [
             {'label':'Books','content':'Book content'},
             {'label':'Magazines','content':'Magazines here'},
             {'label':'Newspaper','url' : 'foo.jsp'}
           ]
        }
        


        jMaki, SWDP and GlassFish

        Posted by carlavmott on March 20, 2007 at 05:19 PM | Permalink | Comments (0)

        Last week was a busy week with several releases in Project jMaki, GlassFish and Sun Web(2.0) Developer Pack or SWDP. SWDP is a newly announced pack targeting developers interested in producing Web 2.0 Rich Internet Applications. We're excited that jMaki is one of the technologies in SWDP. Other technologies include Phobos, Project DynaFaces, RESTful web services APIs and more. Find out more information on SWDP and check out the tutorials and live examples.

        You can always find the latest release of the jMaki framework on the download page. Last week v.8.3.2 was made available and includes better Facelet support, new jmaki.extend API for extending widgets, easier way of adding Glue listeners, true widget library loader in NetBeans and a few bug fixes. If you have not already done so check out the samples page also there are a few new samples available in the samples download area. Many of these features were made possible because of contributions from the community. I created a contributor spotlight page to showcase just some of the folks that have contributed so far.

        jMaki and also SWDP run on GlassFish application server. The latest release of GlassFish, V2 beta includes features such as clustering, improved administration and support for Web 2.0 applications. Each release of jMaki and SWDP are tested on the latest stable version of GlassFish.



        Powered by
        Movable Type 3.01D
  •  Feed java.net RSS Feeds