Jennifer's Weblog

« More Fun with jMaki:... | Main | Dynamic Faces, Part... »

http://blogs.sun.com/jenniferb/date/20070119 Friday January 19, 2007

Still More Fun with jMaki: Loading data into a Dojo table using JSON APIs

OK, I think I've exhausted the "More Fun with jMaki" moniker. But that doesn't mean I won't write more about jMaki. Upcoming blogs include how to wrap a Dojo widget into a jMaki widget. This time, I'll show how to load your own data into a Dojo table. This blog focusses only on how to convert Java object data into JSON format. It doesn't detail getting the data from a database.

The first thing to determine is what format the data for the Dojo table needs to be. To do this, you look at the widget.json file for the table widget. This file is located in the resources/dojo/table directory of the jMaki samples download. As the default value, it shows the following:

"defaultValue":{
"columns": { "title" : "Title", 
             "author":"Author", 
             "isbn": "ISBN #", 
             "description":"Description"},
"rows":[
 ['JavaScript 101', 'Lu Sckrepter','4412', 'Some long description'],
 ['Ajax with Java', 'Jean Bean','4413', 'Some long description']
 ]
}
In JSON-speak, this means that you have a JSON object (denoted by the outer curly braces) that contains another JSON object representing the columns of the table (denoted by the inner set of curly braces) and an array representing the rows of data (denoted by the square brackets). Inside the rows array is a set of other arrays. Each one of those arrays represents a single row of data.

What you need to do is use the JSON APIs to convert Java object data into this JSON format.

First, I created a Book bean to represent a book. If you are using the Java Persistence API, you could make this an entity class. Here is part of the Book class:

public class Book {

    private int bookId;
    private String title;
    private String firstName;
    private String surname;

    /** Creates a new instance of Book */
    public Book(int bookId, 
                String title, 
                String firstName, 
                String surname) {
        this.bookId = bookId;
        this.title = title;
        this.firstName = firstName;
        this.surname = surname;
    }

    public int getBookId() {
        return bookId;
    }

    public void setBookId(int bookId) {
        this.bookId = bookId;
    }
    ... // other getter and setter methods for the other properties.
Next, I created a class to convert the data to JSON. In this class, I added a method to create some rows of data. This is where you'd normally do your database access:

    public List createBooks() throws Exception {
        ArrayList books = new ArrayList();
        Book book = 
            new Book(201, 
               "My Early Years: Growing up on *7", 
               "Duke", "");
        books.add(book);
        book = 
            new Book(202, 
                "Web Servers for Fun and Proft", 
                "Jeeves", "");
        books.add(book);
        book = 
           new Book(203, 
                "Web Components for Web Developers", 
                "Webster", "Masterson");
        books.add(book);
        return books;
    }
Now comes the method that converts this data into JSON format using the JSON APIs:

    public JSONArray getBookData() throws Exception {
             JSONArray books = new JSONArray();
             JSONArray book = new JSONArray();
             ArrayList bookList = 
                     (ArrayList)createBooks();
             Iterator i = bookList.iterator();
             while(i.hasNext()){
                     Book bookData = (Book)i.next();
                     book.put(bookData.getBookId());
                     book.put(bookData.getTitle());
                     book.put(bookData.getFirstName());
                     book.put(bookData.getSurname());
                     books.put(book);
                     book = new JSONArray();
             }
             return books;
    }
This method uses the JSONArray API to create the rows array that contains an array representing each row of data. I'll explain in a minute why I'm not creating the column data here.

Finally, you refer to the getBookData method from the page using an EL expression:

<jsp:useBean id="appBean" 
                class="overviewApp.ApplicationBean" 
                scope="session"/>
<a:ajax name="dojo.table" 
   value="{columns: {'isbn':'ISBN #',
                      'title':'Title',
                      'firstName':'First Name',
                      'surname':'Last Name'},              
           rows:${appBean.bookData}}"/
>
Notice that I had to manually enter the columns data, but I can reference the rows data in the bean. This is because the JSONObject API uses HashMap under the covers. As you might know, HashMap does not ensure insertion order. Our use case requires it so that the column headings match up with the row data in each column. Therefore, I manually entered the column data into the page. If it were not for this issue, we could create the table as a JSON object in the bean so that the page author could reference the entire table with one EL expression.

Comments:

Could you show what the EL synatx would look like for a jsf page?

I've tried this (as suggested by Greg Murray):

<a:ajax name="dojo.table" args="{columns: { 'title' : 'Title', 'author':'Author', 'isbn': 'ISBN #', 'description':'Description'}}" value="#{bookBean.bookData}" />

But I get this render error:

Error loading jmaki.widgets.dojo.table.Widget : id=dojo_table10 Script: http://localhost:8084/Dairy/resources/dojo/table/component.js (line:64). Message: self.rows has no properties

Thanks for your help,
Joe

Posted by Joe Ersinghaus on January 21, 2007 at 12:24 AM PST #

Could you use one of the following options for you Ajax Tag ; it works fine for me : Data handled by a Bean <a:ajax id="table2" name="dojo.table" value="{columns: { 'title' : 'Title', 'author':'Author', 'isbn': 'ISBN #', 'description':'Description', 'price':'Price'}, rows:${appBean.books}}" /> Data handled by a servlet <a:ajax name="dojo.table" service="myservlet" /> if you need more detail info about how to deal with data through Servlet or Bean from a jMaki widget, have a look to my last blog entry regarding this topic.

Posted by Patrice Goutin on January 23, 2007 at 03:21 AM PST #

Recently, I have investigated 2 approaches to deal with live data to be loaded into a jMaki widgets as a dojo.table.

Could you use one of the following options for you Ajax Tag. It works fine for me.

Data handled by a Bean

<a:ajax id="table2" name="dojo.table" value="{columns: { 'title' : 'Title', 'author':'Author', 'isbn': 'ISBN #', 'description':'Description', 'price':'Price'}, rows:${appBean.books}}" />

Data handled by a servlet

<a:ajax name="dojo.table" service="myservlet" />

If you need more detailled info about how to deal with data through Servlet or Bean from a jMaki widget, have a look to my last blog entry regarding this topic(http://blogs.sun.com/patriceg).

Posted by Patrice Goutin on January 23, 2007 at 03:36 AM PST #

Thank you Patrice (and Jennifer) for your response.

This works great! :)

I used the bean method in my jsf app.

Does this method still allow jMaki attributes to partake of the jsf life cycle? Although I'm not sure they do this out of the box anyway.

Not to be a pest, but do you know how, or can point me to some documentation on how to modify the dojo table attributes such as remove the row highlight or even embed html elements so that every entry in the "Title" column are links?

I've left a post on the jMaki forum but no response yet.

Thanks for your help,

Joe

Posted by Joe Ersinghaus on January 23, 2007 at 10:14 PM PST #

Jennifer,

I think you need a no argument constructor in your Book class for a jsf app.

Am I right?

Joe

Posted by Joe Ersinghaus on January 23, 2007 at 10:57 PM PST #

Hi Joe,

You need to use the deferred EL syntax to take full advantage of the JavaServer Faces life cycle. See Using the Unified EL to Reference Backing Beans

So, are you saying that the #{} syntax gave you the errors, and when you changed it to ${} then they went away?

Yes, backing beans should have no-arg constructors. Did you determine that to be the reason why your JavaServer Faces version didn't work? My example is just a straight JSP application. You can tell because I use the ${} syntax.

The widget.json file in the table widget's resources directory lists the attributes you can set. For style-related changes, you can edit the table widget's component.css file. Do you know where to find these?

Jennifer

Posted by jenniferb on January 24, 2007 at 10:17 PM PST #

Hi Jennifer,

Sorry to get back with you so late.

After I added the no arg constructor (to your bean class), this worked:
<jsp:useBean id="bookBean" 
  class="edu.nmsu.nmda.Book" 
  scope="session"/>
<a:ajax name="dojo.table" 
  value="{columns: {'isbn':'ISBN #',
  'title':'Title',
  'firstName':'First Name',
  'surname':'Last Name'},              
  rows:${bookBean.bookData}}"/>

but this did not:
<a:ajax name="dojo.table"
  args="{columns: {'isbn':'ISBN #',
  'title':'Title',
  'firstName':'First Name',
  'surname':'Last Name'}}"
  value="#{bookBean.bookData}" />

This is my error:
"Error loading jmaki.widgets.dojo.table.Widget : id=dojo_table34
Script: http://localhost:8084/Dairy/resources/dojo/table/component.js (line:64).
Message: self.rows has no properties"

I stepped through component.js a bit, but it looks like the data is just not there; so it trips up sizing through an empty array.

If you can help me with the jsf EL on the <a:ajax tag, that would be tremendous.

Oh, I would like some docs on "style-related" stuff too. :)

Thanks so much,
Joe

Posted by Joe on January 30, 2007 at 07:54 PM PST #

Hi Joe,

I thought that you had to use the rows argument, not the value attribute, to refer to the data for the rows. However, I see that Greg told you on the forum that you can use the value attribute. I haven't tried this yet. I'll ask Greg about and get back to you, or if you prefer, you can ask him on the jMaki forum.

I'll see what I can do on style-related documentation.

Jennifer

Posted by jenniferb on January 30, 2007 at 09:43 PM PST #

[url]http://www.essaytown.com[/url] [url]http://www.essaytown.com[/url] [url]http://www.essaytown.com[/url] [url]http://www.essaytown.com[/url] [url]http://www.essaytown.com[/url] [url]http://www.essaytown.com[/url] [url]http://www.essaytown.com[/url] [url]http://www.essaytown.com[/url] [url]http://www.essaytown.com[/url] [url]http://www.essaytown.com[/url] [url]http://www.essaytown.com[/url]

Posted by Essay Town on May 18, 2007 at 04:52 AM PDT #

what a silly question it is ? 3+18=21

Posted by 59.95.33.14 on May 31, 2007 at 10:01 PM PDT #

good site! http://www.essaytown.com

Posted by Term Papers on June 10, 2007 at 11:54 AM PDT #

Hi ! I'm using Netbeans 5.5.1 with SAS and most libraries up to date, including ajax (jmaki) update center. I'm having problems trying to follow the example on loading data into a Dojo table widget, I'll try to be concise: - If I put <a:ajax name="dojo.table" value="{columns: [{..... I get the following error: org.xml.sax.SAXException: No tag "ajax" defined in tag library associated with uri "http://jmaki/v1.0/jsf" It only works if I use the <a:widget tag. Is this correct ?? - If I use static data for example: <jsp:useBean class="webapplication1.ApplicationBean1" id="appBean" scope="session"/> <h:panelGrid binding="#{Page1.gridPanel1}" border="1" id="gridPanel1" style="height: 216px; left: 48px; top: 96px; position: absolute" width="480"> <a:widget name="dojo.table" value="{columns: [{ 'title' : 'Title'}], rows: [[ 'Hello' ], [ 'World' ]] }"/> I get a table with the first column conforming to the data in the VALUE attribute, followed by 33 columns titled '1' to '33' and then another 33 columns titled by snippets of javascript code, and no value in the rows. This is using Firefox 2, because IE will show the same data but the columns are in reversed order. - If I use value="{columns: [{ 'title' : 'Title'}], rows: #{appBean.regionCount} I get nothing at all in the page, but it doesn't throw errors in the server console. Note the "sharp" sign "#". - If I use the dollar sign "$" instead, I get the following error: org.apache.jasper.JasperException: /Page1.jsp(15,131) According to TLD or attribute directive in tag file, attribute value does not accept any expressions Can somebody show me what I'm doing wrong ?? Thanks in advance, Daniel

Posted by Daniel on June 24, 2007 at 07:55 AM PDT #

Ops, sorry for bad message formatting, it looks like "Enter" was not accepted by the form or something. Daniel

Posted by Daniel on June 24, 2007 at 07:58 AM PDT #

what about ajax SQL injection, is this script secure?

Posted by custom essay on July 24, 2007 at 06:55 AM PDT #

What's the difference between a:widget and a:ajax ?

Posted by Alvaro on August 17, 2007 at 11:02 PM PDT #

I tried this above but used different data, I am getting jmaki is undefined. Can you please help me to figure out this runtime error?

Thanks,

Posted by Narasimha on February 01, 2008 at 02:38 PM PST #

no

Posted by 203.145.145.33 on April 04, 2008 at 02:44 AM PDT #

I am having the same problem Daniel had. And I just can not make it work. I also tried Patrice Goutin's servlet method, and same thing, nothing show up. I am using netbeans 5.5 with latest jmaki module. If someone else experienced the same problem and lucky enough to resolve it, could you please show me how to resolve the problem?

thanks, Jeff Chen

Posted by Jeff on April 08, 2008 at 05:08 PM PDT #

check this out http://www.buy-thesis.com

Posted by Al Gorgon on June 16, 2008 at 04:28 AM PDT #

Hi, thanks for the tuto it was helpful, i used it to get the data into the data i wanted into a table as you did, now I'd like to be notified when a table cell is update, i found that i should use "table.onCellUpdate(row, column, value)", but i don't know how to work with this handler, any example will be great, please help! thanks
https://ajax.dev.java.net/docs/jmdocs/dojo/etable/doc.html

Posted by Stof on July 20, 2008 at 06:47 PM PDT #

Hi Jenni,

This is not related to the previous threads...

I have a requirement and i m new to Dojo. I want to add rows on click of a button. Each row should have a Dojo Filteringselect instead of normal text box. This is b'cose i want the Filteringselect functionality where i m trying to use JavaScript, Ajax with Dojo. How i can achieve this. I tried this, but i am not able to get the Filtering select inside the Table cell. I guess the innerHTML that i used is not able to recognize the Dojo Toolkit. What you suggest ?
This Filteringselect can get values from a text file of from a Ajax XmlResponse.

Posted by Gokul on August 11, 2008 at 04:20 AM PDT #

I totally agree with you, jMaki is really fun especially loading data into a Dojo table.

Posted by Term Papers on August 14, 2009 at 06:43 AM PDT #

Thanks, excellent work
<a href="http://bookwormlab.com/">essays</a>

Posted by essay on October 11, 2009 at 06:31 AM PDT #

http://www.crazypurchase.com China Wholesale

Posted by sdd on October 25, 2009 at 08:52 PM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed

Valid HTML! Valid CSS!

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