Wednesday Feb 07, 2007
Wednesday Feb 07, 2007
I have seen a lot of inquiries in the users alias and the forum about how to do coordinated drop-down lists. Coordinated drop-downs are basically a set of nested master-detail records that follow the same pattern that we show in Using Databound Components to Access a Database. With coordinated drop-downs, whenever the user selects a new item from the master drop-down, you need to refresh the list in the detail drop-down.
In the following example, I show how to coordinate drop-down lists that contain data from the Travel database. The first drop-down lists all the PERSON records. The second drop-down shows all the TRIP records for the selected PERSON, and the third drop-down shows all the FLIGHT records for the selected TRIP. Finally, the detail data shows data from the selected FLIGHT.
The trick with coordinating multiple drop-downs, is that you need to trickle down the refreshing of the lists. A change in the first drop-down's selection requires refreshing the second list, which in turn, requires refreshing the third list, and so on.
In this example, I took the easy route. When the user makes a new selection from the PERSON drop-down, I select the first record by default and coordinate the TRIP drop-down by showing all the trips for the first-person. Then, I show all the flights for the first TRIP record, and the detail data for the first FLIGHT record.
public void initFlightDropDown() {
try {
tripDataProvider.cursorFirst();
getSessionBean1().getFlightRowSet().setObject(
1, tripDataProvider.getValue("TRIP.TRIPID"));
flightDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch to trip " +
tripDataProvider.getValue("TRIP.TRIPID"));
log("Cannot switch to person " +
tripDataProvider.getValue("TRIP.TRIPID"), e);
}
}
public void initFlightDetail() {
try {
flightDataProvider.cursorFirst();
flightRowSet.setObject(
1, flightDataProvider.getValue("FLIGHT.FLIGHTID"));
flightDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch to flight " +
flightDataProvider.getValue("FLIGHT.FLIGHTID"));
log("Cannot switch to flight " +
flightDataProvider.getValue("FLIGHT.FLIGHTID"), e);
}
}
public void prerender() {
if ( personDD.getSelected() == null ) {
try {
personDataProvider.cursorFirst();
getSessionBean1().getTripRowSet().setObject(
1, personDataProvider.getValue("PERSON.PERSONID"));
tripDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch to person " +
personDataProvider.getValue("PERSON.PERSONID"));
log("Cannot switch to person " +
personDataProvider.getValue("PERSON.PERSONID"), 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()));
} 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 to person " +
personDataProvider.getValue(
"PERSON.PERSONID"));
log("Cannot switch to person " +
personDataProvider.getValue(
"PERSON.PERSONID"), e);
}
initFlightDropDown();
initFlightDetail();
}
public void tripDD_processValueChange(ValueChangeEvent event) {
try {
getSessionBean1().getFlightRowSet().setObject(
1, tripDD.getSelected());
flightDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch to trip " +
tripDataProvider.getValue(
"TRIP.TRIPID"));
log("Cannot switch to trip " +
tripDataProvider.getValue(
"TRIP.TRIPID"), e);
}
initFlightDetail();
}
public void flightDD_processValueChange(ValueChangeEvent event) {
try {
flightRowSet.setObject(
1, flightDD.getSelected());
flightDataProvider1.refresh();
} catch (Exception e) {
error("Cannot switch to flight " +
flightDataProvider.getValue(
"FLIGHT.FLIGHTID"));
log("Cannot switch to flight " +
flightDataProvider.getValue(
"FLIGHT.FLIGHTID"), e);
}
}
Tuesday Feb 28, 2006
The tutorials show how to display a database column in a drop-down list. But what if you want to show multiple database columns in the list. For example, the VIR database table that comes bundled with the product has a FIRSTNAME column and a LASTNAME column. You might want the drop-down list to show both fields, such as "Jane Doe".
One solution is to add an alias to the database query. Using the VIR database table as an example, you drop the VIR database table on the page, and use the Query Editor to add VIR.EMPLOYEE.FIRSTNAME || ' ' || VIR.EMPLOYEE.LASTNAME AS FULLNAME to the query statement, as shown below.
SELECT ALL VIR.EMPLOYEE.ID,
VIR.EMPLOYEE.FIRSTNAME,
VIR.EMPLOYEE.LASTNAME,
VIR.EMPLOYEE.EMAIL,
VIR.EMPLOYEE.FIRSTNAME || ' ' || VIR.EMPLOYEE.LASTNAME AS FULLNAME
FROM VIR.EMPLOYEE
To test the statement, right-click in the query pane of the Query Editor and choose Run Query. A dialog pops up explaining that the the IDE's parser only knows a small subset of common SQL syntax. Click continue and the Query Editor should output the query results.
You will also see that the the visual panes in the Query Editor for this particular rowset no longer work. This is because of the same reason that the IDE's parser only knows a small subset of common SQL syntax. This problem only affects the Query Editor.
To see the query in action, drop a Drop Down List component on the page, right-click the component and choose Bind to Data. Click the Bind to Data Provider tab, choose employeeDataProvider, select EMPLOYEE.ID for the Value Field, and select FULLNAME for the Display Field.
Click OK. Test and Run.
The above query works with the bundled database. You have to adjust based on the syntax of your database. For example, for MySQL, use something like select concat(member.lastname, ", ", member.firstname).
Wednesday Feb 22, 2006
A new tutorial writer, Joe, recently joined the Creator Tutorials team. While working on the Tabset tutorial, he came up with this useful tidbit: how to make a selection from a drop-down list navigate to a different page.
1. Right-click the Drop Down List component and select Auto-Submit on Change.
2. Use the Page Navigation Editor to create links from the page with the drop-down list to the other pages. The rest of the steps assume that you have 3 links -- case1, case2, and case3.
3. Close the Page Navigation editor and return to the page with the Drop Down List component in the Visual Designer. Right-click the Drop Down List component and choose Configure Default Options. (The Delving into Components tutorial shows how to set the list items programmatically.)
4. Make the Value for each option be one of the link names that you added in the Page Navigation editor, such as case1, case2, and case3.
5. In the Visual Designer, double-click the Drop Down List component. The Java Source editor opens up on the process value change event handler for the compnent.
6. Make the body of the method similar to the following code that is shown in bold (using the correct id for your Drop Down List component).
public void dropDown1_processValueChange(ValueChangeEvent event) {
Application application = getApplication();
NavigationHandler navigator = application.getNavigationHandler();
FacesContext facesContext = getFacesContext();
try {
navigator.handleNavigation(facesContext, null,(String) getDropDown1().getSelected());
} catch (Exception e) {
log("can't navigate to " + (String) getDropDown1().getSelected());
}
}
7. Fix imports.
8. Run and test. You will see that the process value change doesn't get called if you try to select the first item when the page is first displayed. One way to fix that is to make the first item's Display value be something like "Choose One" and have its Value be something like "none." Then wrap the body of the process value change method in an if statement something like this.if (!"none".equals(getDropDown2().getSelected()))
Thursday Dec 15, 2005
I just finished upgrading the
Using Databound Components to Access Databases
for the final release of the product. Because this upgraded tutorial won't be published until after the final Creator 2 release comes out, I thought I would share the following piece of information that I added to the tutorial. I have seen several posts on the EA forum where people are asking how to reposition the cursor to a different table row. The answer is to call tableRowGroup1.setFirst(zero-based-index-value);.
If you use the table paging feature on a master detail page that is like the one in the tutorial (a drop-down list for the master data and a table for the detail data), you will see that when the user selects a different choice from the dropdown list, the table displays new data, but stays on the current page. For example, if the user switches to page 2 and then chooses a new item from the dropdown list, the table shows the second page of data for the new selection. To fix the problem, add the following code after the tripDataProvider.refresh() statement in the master component's value change event handler: tableRowGroup1.setFirst(0);. This ensures that the first page is always displayed when a new name is selected from the drop-down list.
A new tutorial, GoogleSearch Web Service Portlet, will be added to the EA tutorials page, hopefully today or tomorrow.
The upgrading of the Referencing Class Libraries tutorial from Creator 1 to Creator 2 was low on our priority list. However, several people sent a request for this tutorial to the CreatorDocsFeedback@Sun.Com alias. So, we have upgraded this tutorial and it is going through the engineering review process. Your input matters to us, so please continue to submit tutorial suggestions.