Project jMaki supports a topic-based publish/subscribe system in which widgets can act as producers or consumers. In this system, producers publish messages to topics and consumers receive the messages from topics to which they have subscribed.
This system makes it easy for your application to respond to widget events and to get two widgets to interact by listening for each other's events. This section describes how you can get widgets to publish and subscribe to a topic so that your application can respond to a widget event.
To make event-handling easier, jMaki provides default topics for the most common widget events. For example, a Dojo combobox widget will publish its value to the /onSelect topic when the user selects a value from the widget. Likewise, a Dojo combobox widget automatically subscribes to the /setValues topic, and so it gets its value from there. Most often, though, you will need to create your own topics, as the plotCity example does.
Usually, you go through the following steps to handle a widget event using the publish and subscribe system:
Add a publish attribute to a widget tag and set it to a topic string so that the widget will publish its current value to that topic when it experiences an event.
Write a handler in glue.js that will be called when the widget experiences an event. When the handler is called, it retrieves the value from the topic, performs some task with the value, and publishes the result of the task to a different topic.
Add a subscribe attribute to another widget tag and set the subscribe attribute to the topic to which the handler publishes the result of its task.
In addition to the publish/subscribe mechanism, jMaki provides the doAjax function to make it easy to use Ajax within your event handler function to asynchronously retrieve data from the server and return it to the client.
The plotCity application uses the publish/subscribe mechanism and doAjax so that the following happens:
When the user selects a state from the thisState combobox, the thisCity combobox repopulates with the list of cities located in that state.
When the user selects a city from the thisCity combobox, the city is plotted on the map.
In the plotCity example, the thisState widget's publish attribute is set to the topic, /cb/getState:
<a:widget id="thisState" name="dojo.combobox" publish="/cb/getState" value="${StateBean.states}" />
This makes the widget publish its selected value to the developer-defined /cb/getState topic whenever the user selects a value from the widget.
The following event handler in the glue.js file subscribes to the /cb/getState topic:
jmaki.subscribe("/cb/getState/*", function(args) { var message = args.value; jmaki.doAjax({method: "POST", url: "Service?message=" + encodeURIComponent(message), callback: function(_req) { var tmp = _req.responseText; var obj = eval("(" + tmp + ")"); jmaki.publish('/cb/setValues', obj); // handle any errors } }); });
Because the handler subscribes to the topic, it executes when the widget publishes a new value to the topic. The handler does the following:
Subscribes to the topic, /cb/getState/*. Because of the wildcard character, the subscribe function subscribes to all subtopics of the /cb/getState/ topic.
Receives the state code as an args variable from the /cb/getState topic. The thisState widget publishes to /cb/getState, and therefore passes its args argument to it when the widget experiences an onSelect event.
Uses the jmaki.doAjax function to pass the state code to the Service servlet, retrieves the list of cities from the servlet, and publishes the list to the /cb/setValue topic. Writing a Servlet to Obtain the Server-Side Data for the Handler gives more detail on the Service servlet.
All combobox widgets automatically obtain their values in response to a user action by subscribing to the global /setValues topic that jMaki provides unless the developer specifies otherwise. In this example, thisCity subscribes to a /setValues subtopic of the developer-defined parent topic, cb. Because the thisCity combobox subscribes to the parent topic, it also subscribes to the /setValues subtopic by default and is therefore automatically updated with the new set of cities.
If you have only one combobox in a page, you do not have to create a parent topic for the purpose of updating values in the combobox. Instead, you can publish the new values to the global /setValues topic. This example needs a parent topic because it has two comboboxes. If the handler published to the global /setValues topic, both comboboxes would be populated with the set of cities returned by the Service servlet.
Handling Events in the plotCity Application gives the step-by-step instructions for implementing event handling in plotCity.