Tuesday Jun 05, 2007
Tuesday Jun 05, 2007
In an earlier blog, we showed how to build coordinated drop down lists in a NetBeans Visual Web application. One problem with the techniques in that blog you is that you have to submit the whole page whenever a new selection is made from any of the drop down lists. If you have other components that get validated on page submission, it gets a bit messy, as you have to distinguish between when the page is submitted because of a new list selection and when the user is actually submitting the form.
The Dynamic Faces component library provides a solution to this problem. You can put the Drop Down List components in a Dynamic Faces Ajax Zone so that only the input from those components is sent to the server (as part of an Ajax request) when the user makes a new drop down selection. You can also specify which components to rerender when the server returns the Ajax response.
The following steps show how to do this using the tables from the sample Travel database. This example involves a coordinated person-trip-flight selection and the detail data for the selected flight. When you select a new person, the trip drop-down list shows all the person's trips and pre-selects the first trip on the list. The flight drop-down list shows all the flights for the selected trip, and pre-selects the first flight on the list. The page also redisplays the detail data for the selected flight. All other fields are not touched unless the whole page is submitted.
If you haven't already done so, you need to install the Dynamic Faces component library into the NetBeans IDE. Follow the steps in the Installing the Dynamic Faces Component Library section of the Installing the Currency Trader Sample Application tutorial.
Dynamic Faces provides a custom Lifecycle object that enables the
JavaServer Faces lifecycle to handle Ajax transactions and to re-render portions
of a component tree without requiring a full-page refresh.
To make the runtime
aware of the custom Lifecycle object:
The Ajax Zone component arms its children with the capability of sending Ajax requests. In this example, you add the three Drop Down List components to an Ajax Zone. The default behavior for an Ajax Zone component is to submit, execute, and rerender all the components in the zone whenever there is an onclick event for an input component within the zone.
You next add a Property List component to display the flight details, and you configure the Ajax Zone to render the Property List in addition to the components in the Ajax Zone.
Now, add a Text Field and a Button component to the page. By doing this, you can see for yourself how the Ajax Zone is a partial page submit, whereas, when the button is clicked, the whole page is submitted.
Add the following code to the backing bean for coordinating the drop-down lists and flight detail data. (See http://blogs.sun.com/divas/entry/coordinated_drop_down_lists for more information about coordinated drop-down lists).
public void initFlightDropDown() {
try {
tripDataProvider.cursorFirst();
getSessionBean1().getFlightRowSet().setObject(
1, tripDataProvider.getValue("TRIP.TRIPID"));
flightDataProvider.refresh();
tripDD.setSelected(tripDataProvider.getValue("TRIP.TRIPID"));
} catch (Exception e) {
error("Cannot switch trips");
log("Cannot switch trips", e);
}
}
public void initFlightDetail() {
try {
flightDataProvider.cursorFirst();
// detail data is in the page bean
flightRowSet.setObject(
1, flightDataProvider.getValue("FLIGHT.FLIGHTID"));
detailFlightDataProvider.refresh();
flightDD.setSelected(flightDataProvider.getValue("FLIGHT.FLIGHTID"));
} catch (Exception e) {
error("Cannot switch flights");
log("Cannot switch flights", e);
}
}
|
public void prerender() {
if ( personDD.getSelected() == null ) {
try {
personDataProvider.cursorFirst();
getSessionBean1().getTripRowSet().setObject(
1, personDataProvider.getValue("PERSON.PERSONID"));
tripDataProvider.refresh();
personDD.setSelected(
personDataProvider.getValue("PERSON.PERSONID"));
} catch (Exception e) {
error("Cannot switch to selections");
log("Cannot switch to selections", e);
}
initFlightDropDown();
initFlightDetail();
} else {
try {
// Synchronize data providers with current selections
personDataProvider.setCursorRow(
personDataProvider.findFirst(
"PERSON.PERSONID", personDD.getSelected()));
tripDataProvider.setCursorRow(
tripDataProvider.findFirst(
"TRIP.TRIPID", tripDD.getSelected()));
flightDataProvider.setCursorRow(
flightDataProvider.findFirst(
"FLIGHT.FLIGHTID", flightDD.getSelected()));
// rowset for the detail flight is in the page bean
flightRowSet.setObject(
1, flightDD.getSelected());
detailFlightDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch to selections");
log("Cannot switch to selections", e);
}
}
}
|
public void personDD_processValueChange(ValueChangeEvent event) {
try {
getSessionBean1().getTripRowSet().setObject(
1, personDD.getSelected());
tripDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch person id");
log("Cannot switch person id", e);
}
initFlightDropDown();
initFlightDetail();
}
|
public void tripDD_processValueChange(ValueChangeEvent event) {
try {
getSessionBean1().getFlightRowSet().setObject(
1, tripDD.getSelected());
flightDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch trips");
log("Cannot switch to trips", e);
}
initFlightDetail();
}
|
public void flightDD_processValueChange(ValueChangeEvent event) {
try {
flightRowSet.setObject(
1, flightDD.getSelected());
detailFlightDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch flights");
log("Cannot switch flights", e);
}
}
|
Click the Run Main Project button to test out the web application. Select different people, trips, and flights to see the partial form updates. Notice how even though the text field is required, you do not see any validation errors, because the Text Field component is not part of the partial page submission. However, if you submit the form by clicking the Submit button, an error message appears in the Message Group component if the text field is blank.
Posted by sree on June 21, 2007 at 10:24 PM PDT #
Posted by Diva #2 on June 22, 2007 at 07:49 AM PDT #
Hi,
I tried this to the letter but it didn't work! When I select a dropdown (anyone of the 3) nothing happens! (no partial update). I'm using netbeans 6.0 jdk 6.0 update 3 on win xp sp2 with firefox 2.0.0.12. When i click the submit button though, the page refreshes and the dropdowns are updated as expected
Posted by Musa Musa on February 14, 2008 at 09:36 AM PST #
Sorry I forgot to add that I updated the Netbeans (installed the sample currency trader app., Visual JSF backwards compatibility kit, everything!). Help me out here!
Posted by Musa Musa on February 14, 2008 at 09:39 AM PST #
I got it! I just had to set the Java EE version to 1.4 (the jsp page now uses the ui: tags instead of the webuijsf tags when you use Java EE 5)
Posted by Musa Musa on February 15, 2008 at 04:32 AM PST #
Musa Musa,
Glad you figured it out. I had sent email to the engineer, but he was out yesterday.
Posted by Diva #2 on February 15, 2008 at 08:28 AM PST #
I tried to do this example but it didn't work! When I select a dropdown (anyone of the 3) nothing happens! (no partial update). I'm using netbeans 6.1 jdk 1.6 When i click the submit button though, the page refreshes and the dropdowns are updated as expected
Posted by Roberto on August 10, 2008 at 07:18 PM PDT #
Roberto,
There have been changes to the VWP components and to Dynamic Faces since this blog entry was written over a year ago. I was switched from writing about VWP to writing about Ruby and I have not kept up with the changes, so I cannot say why this isn't working with 6.1. Maybe someone else reading this can help. Here is a 6.1 tutorial that might help: http://www.netbeans.org/kb/60/web/ajaxchatroom.html
Posted by diva#2 on August 11, 2008 at 10:00 AM PDT #