Screencast #Web7: Creating Mashups with jMaki - A real-life RIA using jMaki (Sun Tech Days Event Map)
Posted by arungupta on September 11, 2007 at 07:34 AM | Comments (0)
Sun Microsystemskicks
off2007-2008 Tech Days
and marks the 10th anniversary of the developer event. This blog celebrates the
decade by announcing "Sun Tech Days Event Map" - a real-life
RIA created
using jMaki. It allows you to choose the
date on a web page using a rich calendar widget, shows the city where
Sun Tech Days event is
happening during that month and then shows that city location in a map. Play the
video below to see how the application looks like:
This application shows several concepts of jMaki:
Widgets from different toolkits (Dojo Combobox, Yahoo Calendar and
Google Map in this case) co-located on the same page
Right-click in Projects window, select "Web" in "Categories"
and "Web application" in "Projects". Click on
"Next >".
Enter the project name as "SunTechDays" and choose
GlassFish as the "Server" and take all other values
default. Click on "Next >".
Select "jMaki Ajax Framework" and choose "Two
Fixed Right Sidebars" layout.
Click on "Finish".
Add the following widgets in the generated "index.jsp"
Replace "Top Right Column" by dragging-and-dropping "Dojo
Combobox".
Replace "Right Column" with "Yahoo Calendar".
Replace "Left Column" with a "Google Map".
Create and populate the database
In the NetBeans IDE, go to "Runtime" tab, expand "Databases",
right-select the node with the value "jdbc:derby://localhost:1527/sample"
and select "Connect".
Enter both username and password as "app".
Right-select the database and select "Execute Command...".
Create the table using the following SQL
INSERT INTO TECHDAYS_SCHEDULE VALUES ('9/11/2007', '9/12/2007',
'Boston, United States');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('9/24/2007', '9/25/2007', 'Rome,
Italy');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('9/26/2007', '9/28/2007', 'Milan,
Italy');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('10/19/2007', '10/19/2007',
'Taipei, Taiwan');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('10/23/2007', '10/25/2007',
'Shanghai, China');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('11/1/2007', '11/3/2007',
'Beijing, China');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('11/6/2007', '11/8/2007', 'Tokyo,
Japan');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('12/3/2007', '12/5/2007',
'Frankfurt, Germany');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('1/9/2008', '1/10/2008', 'Atlanta,
United States');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('2/27/2008', '2/29/2008',
'Bangalore, India');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('3/4/2008', '3/6/2008', 'Sydney,
Australia');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('3/11/2008', '3/13/2008',
'Johannesburg, South Africa');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('4/1/2008', '4/1/2008', 'St
Petersburg, Russia');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('4/1/2008', '5/1/2008', 'Manila,
Philippines');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('5/21/2008', '5/23/2008', 'Mexico
City, Mexico');
Create a Persistence Unit
In the NetBeans IDE, right-select the project, click on "New",
"Entity Classes from Database...".
In the "New Entity Classes from Database" dialog
window, choose "Data Source" and select "jdbc/sample"
value.
All the available tables are shown in "Available Tables".
Select "TECHDAYS_SCHEDULE" and click on "Add >".
Click on "Next >".
Enter the package name as "suntech".
Click on "Create Persistence Unit...".
In "Create Persistence Unit..." dialog window take all
the default values and click on "Create".
Click on "Finish".
Expand "Configuration Files", open "persistence.xml",
click on "Add Class", click "Cancel", click on
"Add Class" again and now select "suntech.TechdaysSchedule"
and click on "OK".
Expand "Source Packages", "suntech" node
and open "TechdaysSchedule.java".
Add the following NamedQuery to the class. Copy/paste the fragment
as the first line in "@NamedQueries" annotation.
@NamedQuery(name = "TechdaysSchedule.findByMonth", query = "SELECT
t FROM TechdaysSchedule t WHERE t.techdaysSchedulePK.startdate >= :firstdate
and t.techdaysSchedulePK.enddate <= :lastdate"),
Configure the widgets
Expand "Web Pages", open "glue.js" and add
the following code at the end of the file:
jmaki.subscribe("/dojo/combobox/onSelect", function(item) {
var location = item.value.split(',')[0] + ", " + item.value.split(',')[1];
var start = item.value.indexOf('(');
var stop = item.value.lastIndexOf(')');
var encodedLocation = encodeURIComponent("location=" + location);
// jmaki.xhp is provided as part of jmaki and maps to the XMLHttpProxy
var url = jmaki.xhp + "?id=yahoogeocoder&urlparams=" + encodedLocation;
jmaki.doAjax({url: url, callback : function(req) {
if (req.responseText.length > 0) {
// convert the response to an object
var response = eval("(" + req.responseText +
")");
var coordinates = response.coordinates;
v = {results:coordinates};
jmaki.publish("/jmaki/plotmap", coordinates);
} else {
jmaki.log("Failed to get coordinates for " +
location );
}
}
});
});
Right-select the project, select "New" and then "JSP..."
using the name "data". Notice, the IDE automatically picks
up the file extension.
Replace the generated template code with the following. This code
reads a parameter, parses it into a Date, queries the database using the
PersistenceUnit created above and return the result in JSON format.
<%
String dateParam = request.getParameter("date");
Date date = null;
if (dateParam == null || "".equals(dateParam))
date = Calendar.getInstance().getTime();
else {
SimpleDateFormat sdf = new SimpleDateFormat("MMM/dd/yyyy");
date = sdf.parse(dateParam);
}
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("SunTechDaysPU");
EntityManager em = emf.createEntityManager();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DATE, 1);
Date firstDateOfMonth = cal.getTime();
cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
Date lastDateOfMonth = cal.getTime();
List<TechdaysSchedule> list =
em.createNamedQuery("TechdaysSchedule.findByMonth").
setParameter("firstdate",
firstDateOfMonth).
setParameter("lastdate",
lastDateOfMonth).
getResultList();
out.println("[");
boolean first = true;
int count = 0;
SimpleDateFormat sdf = new SimpleDateFormat("MMM d, yyyy");
for (TechdaysSchedule t : list) {
StringBuffer buf = new StringBuffer();
String city = t.getLocation() + ", (" + buf.toString() + ")";
out.println("{");
out.println("name: \"" + t.getLocation() + "\", ");
out.println("label: \"" + city + "\", ");
out.println("value: \"" + city + "\"");
if (first) {
out.println(", selected: " + true);
first = false;
}
out.println("}");
if (count++ < list.size()-1)
out.println(",");
}
out.println("]");
%>
And that's it!
Carla and I conceived
this application together and
Greg and helped with gluing the widgets.
Here are some potential fun improvements:
Instead of randomly selecting a date and then using it's month for
populating the combo box, tap the event published (if any) for changing
month in the calendar widget.
The database structure can be manipulated to include hotel information
and provide more meaningful information.
The dates may be shown in the bubble displayed in the map.
Restaurant recommendations may be pulled from another service and shown
for the event attendees.