Skip Navigation Links

Client Programming gifts

Posted by ngawor on January 12th, 2008. Other posts by ngawor

This is a continuation of my previous posts on the gift organizer application I built. Once I knew my model was working, I started on the client interface. My first goal was just to list all the gifts. I started with a .gt file for my main client-side interface, but quickly changed the extension to .zhtml so I could leverage the web app programming model. I decided to use the grid widget from dojo. Normally I would have used a dojo datastore connecting remotely back to the zero server to get its data, but I wanted to leverage the client zone which is part of the web app programming model. I couldn’t find a good way to integrate the two together (I know the client team is working on this for M4), so I decided to rebuild a read-only datastore from the data in the client zone every time the gift data needed to be relisted. This meant that operations that required writes couldn’t be done through the datastore but needed to be handled separately. This didn’t work initially as it caused a “too much recursion” error. It turns out that when you put data in a datastore, it attaches some information to that data which contains a recursive reference. When this information is then stored in the client zone, it cannot be serialized correctly. It is therefore necessary to clone the data before passing it to the datstore:

giftsMeta.items = dojo.clone(zget("/client/data/gifts"));
var giftsStore = new dojo.data.ItemFileReadStore({data: giftsMeta});

The grid displayed my data, but since the data was coming right from the datastore, I couldn’t initially figure out how to format it the way I would like. I also wanted to add links to each entry for edit and delete, but again I couldn’t figure out how to do that without modifying the data coming from the server-side. Here is where I discovered that each field in the grid can be assigned a formatting function, which takes in a value and returns a string. I was able to take in a value of something like the image url, and return an image link(”<img…”) which displayed the image correctly within the grid. I also created two formatting methods that took in the id field (not actually displayed anywhere in the grid) and displayed edit and delete links.

Next I tried getting the edit link to work. The webapp programming model allowed me to define an action which would be taken in response to certain events. When I created my edit link, I gave it a class of editItem, so I thought the following would work in my zhtml file:

<%
on(".editItem:click").fire("showForm")
%>

This, however, didn’t work. It turns out that because this link, with its associated class, is only generated during the rendering of the grid, the web app programming model doesn’t know about it. In order to get this to work, I had to fire an event when the grid was finished rendering:

dojo.connect(grid, "postrender", function(){ zfire("forceEventRefresh"); });

The onForceEventRefresh method had an empty body and did nothing, but it made the client programming model aware of the newly added link so that my onShowForm handler would now be called. Because the onShowForm handler needed to display a form on the client-side, I defined it within a gifts.js file. In order to show the edit form, I needed to populate it with data about the gift the user wanted to edit. When I defined the edit link, I included a query param with the id of the item:

function formatEditLink(value) {
return "<a class='editItem' href='?id=" + value + "'>Edit</a>"
}

The web app programming model makes all query parameters from links available in the event zone. I was therefore able to retrieve it within my handler by doing:

var id = zget("/event/input/id")

Once I had the id, I could find the details about the item, which were stored in the client zone. The web app programming model has a way for you to load fragments dynamically and pass them some data using the zupdate method. In this case I created a gifts.gift_form.zhtml file and then called the following:

zupdate("giftInfoDiv", "gift_form", payload);

This replaced the content of giftInfoDiv (a placeholder) with the gifts.gift_form.zhtml file. In the payload, I passed details about the data for the particular gift to be editing. I could then access this data from within the gifts.gift_form.zhtml file:

<%
if (event.item[]) {
nameValue = event.item[].name
urlValue = event.item[].url
imageValue = event.item[].image_url
priceValue = event.item[].price
recValue = event.item[].recipient
}
%>

I used the same form both for creating new items and editing existing items, which is why I checked for the existence of event.item first. If it wasn’t there, that meant I was actually creating a new item.

I know work is underway towards better integration of the web app programming model with both dojo and our resources model. I’m looking forward to trying this work out in the next version of my application.

– Nell Gawor

Comments are closed.