How to develop a master/detail application that uses data views on a page.
You can run this technique code from:
NOTE First make sure that database is running on your localhost SilverStream Server | |
See the chapter on using HTML-based views in the Programmer's Guide |
In the sample application, you can browse through a database of companies and see the orders for each one. When you click on a particular order, the order details appear on the screen. The application page is bound to a database table called companies (the primary table for the page). It contains the company names and addresses.
The techniques in this page show how to set up the user interface portion of the application to make the master/detail feature work, as well as how to code the buttons and event link.
This section describes how the Orders data view is set up to serve as the master table. The important properties to note in the Property Inspector are:
companies.companyid = orders.customerid
orders.orderdate Desc
orders.orderid
eventLinkPerformed
event, which is explained in a following section.
This section describes how the Order Details data view is set up to serve as the details table. When the user clicks an item in the master Orders data view, details about the order appear in this data view. The important features to note about the Details data view are:
This section describes the two fields that display the shipping costs and grand total for the Order Details data view.
The following code illustrates how to navigate to the first record in the primary database table. Extra lines are added to clear the Order Details data view and the calculated total fields, since the order details would no longer apply to the newly displayed record.
// pageActionPerformed event for First button agData.gotoFirst(); dvOrderDetails.query("orderdetails.orderid=-1"); shippingcosts.setText(""); grandtotal.setText("");
gotoFirst()
to move to the first record.
query()
on it, setting the orderid key to -1.
setText()
with an empty string.
The following code illustrates how to navigate to the previous record in the primary database table. Extra lines are added to clear the Order Details data view and the calculated total fields, since the order details would no longer apply to the newly displayed record.
// pageActionPerformed event for Previous button agData.gotoPrevious(); dvOrderDetails.query("orderdetails.orderid=-1"); shippingcosts.setText(""); grandtotal.setText("");
gotoPrevious()
to move to the previous record.
query()
on it, setting the orderid key to -1.
setText()
with an empty string.
The following code illustrates how to navigate to the next record in the primary database table. Extra lines are added to clear the Order Details data view and the calculated total fields, since the order details would no longer apply to the newly displayed record.
// pageActionPerformed event for Next button agData.gotoNext(); dvOrderDetails.query("orderdetails.orderid=-1"); shippingcosts.setText(""); grandtotal.setText("");
gotoNext()
to move to the next record.
query()
on it, setting the orderid key to -1.
setText()
with an empty string.
The following code illustrates how to navigate to the last record in the primary database table. Extra lines are added to clear the Order Details data view and the calculated total fields, since the order details would no longer apply to the newly displayed record.
// pageActionPerformed event for Last button agData.gotoLast(); dvOrderDetails.query("orderdetails.orderid=-1"); shippingcosts.setText(""); grandtotal.setText("");
gotoLast()
to move to the last record.
query()
on it, setting the orderid key to -1.
setText()
with an empty string.
The following code illustrates how to prepare the page for the user to find a particular record in the database table. The code clears the main database fields to allow the user to enter search parameters. The user completes the operation by clicking the Find! button.
// pageActionPerformed event for Find Mode button agDataMgr.beginFind(); AgiRowCursor rc = dvOrders.getRootRowCursor(); if (rc != null) { while (rc.gotoFirst()) { rc.delete(); } } dvOrders.scrollToFirstRow(); dvOrderDetails.query("orderdetails.orderid=-1"); shippingcosts.setText(""); grandtotal.setText("");
beginFind()
method, which clears the main database fields and accepts subsequent user entries as search parameters.
getRootRowCursor()
.
scrollToFirstRow()
method.
query()
on it, setting the orderid key to -1.
setText()
with an empty string.
The following code illustrates how to complete the process of finding a particular record in the database table. The user will have already clicked the Find Mode button and entered any search parameters.
// pageActionPerformed event for Find button agDataMgr.doFind();
doFind()
method, which brings up a record that matches the search parameters.
The following code illustrates how to get details on the order whose row the user clicks. It uses both the Orders and OrderDetails views as well as the orders, orderdetails, and products database tables to obtain and compute the required data.
// eventLinkPerformed event for orderid label in Orders data view Integer ordID = new Integer(0); BigDecimal total = new BigDecimal(0); // running total BigDecimal one = new BigDecimal(1); // the constant one BigDecimal unitprice; // column unitprice Integer qty; // column quantity BigDecimal bqty; // qty converted to BigDecimal BigDecimal discount; // column discount BigDecimal price; // calculated item total BigDecimal freight; // shipping costs AgiRowCursor ord = dvOrders.getCurrentRowCursor(); if (ord != null) { ordID = (Integer) ord.getProperty("orders.orderid"); dvOrderDetails.query("orderdetails.orderid=" + ordID.toString()); // Loop thru obtaining all the data AgiRowCursor det = dvOrderDetails.getRootRowCursor(); for (boolean gotNextRow = det.gotoFirst(); gotNextRow; gotNextRow = det.gotoNext()) { // Obtain the values for this row. unitprice = (BigDecimal) det.getProperty( "products.unitprice"); qty = (Integer) det.getProperty("orderdetails.quantity"); bqty = new BigDecimal(qty.intValue()); discount = (BigDecimal) det.getProperty( "orderdetails.discount"); // Formula is unitprice * quantity * (1 - discount) price = unitprice.multiply(bqty).multiply( one.subtract(discount)); total = total.add(price); } // Add in freight if not zero freight = (BigDecimal) ord.getProperty("orders.freight"); if (freight != null) total = total.add(freight); try { // Set the value to 2 digits of precision freight = freight.setScale(2, BigDecimal.ROUND_HALF_DOWN); total = total.setScale(2,BigDecimal.ROUND_HALF_DOWN); } catch (Exception e) {} shippingcosts.setText(AgFormat.format(freight,"#,##0.00")); grandtotal.setText(AgFormat.format(total,"#,##0.00")); }
dvOrders.getCurrentRowCursor()
.
dvOrderDetails.query()
and supplying the obtained id as the parameter. The response to the query is contained in dvOrderDetails.
getRootRowCursor()
to get the data object representing the data in the view. This method returns a row cursor.
gotoChild()
on the row cursor to get to the first row. The for loop goes through each row (represented by a product) to get the unit price, quantity, and discount information for that product.
getProperty()
method obtains its value from the products database table.
getProperty()
method obtains its data from the orderdetails database table.
getProperty()
method is called on the Orders (dvOrders)view. ord is the row cursor for that view.
setText()
on the appropriate labels. Both are AgpLabel objects in the Order Details data view.