Screencast #Web7: Creating Mashups with jMaki - A real-life RIA using jMaki (Sun Tech Days Event Map)
Sun Microsystems kicks off 2007-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
- Multiple widgets from different toolkits communicate with each other using the publish/subscribe mechanism & Actions (and here)
- Populate widgets by accessing services from the backend
- Using Java Persistence API to return the data understood by jMaki widgets
This application is built using NetBeans IDE 5.5.1, jMaki 0.9.7.3 and deployed on GlassFish RC4. Let's get started.
- In the NetBeans IDE, create a new project
- 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".
- Right-click in Projects window, select "
- 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".
- Replace "
- 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
create table TECHDAYS_SCHEDULE (startDate date,
endDate date,
location varchar(255),
PRIMARY KEY (startDate, endDate)) - Populate the database for
Sun Tech Days
2007-2008 schedule 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');
- In the NetBeans IDE, go to "
- 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"),
- In the NetBeans IDE, right-select the project, click on "
- Configure the widgets
- Expand "
Web Pages", open "glue.js" and add the following code at the end of the file:
jmaki.subscribe("/yahoo/calendar/onSelect", function(args) {
var newDate;
if (typeof args.value == "undefined") {
var tempDate = new Date();
newDate = (tempDate.getMonth()+1) + "/" + tempDate.getDate() + "/" + tempDate.getFullYear();
} else {
var str = "" + args.value;
newDate = str.split(" ")[1] + "/" + str.split(" ")[2] + "/" + str.split(" ")[3];
}
jmaki.doAjax({method: "POST",
url: "data.jsp?date=" + encodeURIComponent(newDate),
callback: function(_req) {
var tmp = _req.responseText;
var obj = eval("(" + tmp + ")");
jmaki.log("tmp "+ obj);
jmaki.publish('/dojo/combobox/setValues', obj);
// handle any errors
}
});
});
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 );
}
}
});
});
- Expand "
- Configure widgets on the page
- Change the Dojo Combobox generated fragment with
<a:widget name="dojo.combobox" service="data.jsp"/> - 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.
<%@ page import="java.util.*" %>
<%@ page import="suntech.*" %>
<%@ page import="javax.persistence.*" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%
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();
buf.append(sdf.format(t.getTechdaysSchedulePK().getStartdate()));
buf.append(" - ");
buf.append(sdf.format(t.getTechdaysSchedulePK().getEnddate()));
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("]");
%>
- Change the Dojo Combobox generated fragment with
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.
Technorati: jmaki netbeans glassfish suntechdays jpa screencast web2.0
- Login or register to post comments
- Printer-friendly version
- arungupta's blog
- 1396 reads





