Introduction
This tutorial focuses on the Table UI element and shows you how to use Java classes to add custom functionality in Web Dynpro. This tutorial shows you how to write custom Java classes that can react to the Table UI element’s sorting and filtering events.
First, you see how to display and edit context data using the Table UI element, which is rather easy. We implement methods for the sorting and filtering of table data.
The two classes needed for sorting and filtering are bound to the relevant context attributes, instantiated, and associated with the Table via its event properties.
Step 1
Creating a New Web Dynpro DC
Create a new Web Dynpro DC called tc/wd/tut/table/sofi containing a Web Dynpro application TutorialApp and a Web Dynpro component Tutorial. Leave the Default Window and Views option selected in order to get them applied by default. Then rebuild the project so that the various Java source files are created.
Creating the Context for the Table Data
To provide a table with data, we must first store that data in the context of the Component Controller.
- 1. Add a new node to the context root node and name it DataSet. The collection cardinality of the node
should be left at the default value 0...n.
- 2. Change the selection cardinality to 0...n. Both properties can be found in the Properties view for the controller.
Designing the View Layout
After the view controller context has been created, we can start to add UI elements to the view layout in order to display the context data on the screen.
To present all the articles on the browser screen, we just have to add some UI elements to the view layout.
- 1. Open the TutorialView editor by double-clicking the icon or using the context menu. Switch to the Layout tab.
- 2. In the Outline view, delete the DefaultTextView element if necessary.
- 3. Right-click the Root Element of the view and choose Apply Template.
Select the Table icon, overwrite the Template Instance Name with the value ProductsCatalogue, and choose Next. (You can use any valid identifier here but it is important to use the same identifier later in the code that accesses the table at runtime.)
- 4. Select the DataSet context node. By default, all attributes are selected automatically, so just choose Next:
- 5. Change the editor for the Quantity attribute from TextView to InputField and confirm by choosing Finish.
The following screenshots show the complete property settings for the table and how the UI appears in the preview area: Providing Sample
Providing Sample Data
In order for the table to display some data, we implement a supply function for the DataSet context node.
- 1. Double-click the Component Controller
- 2. Switch to the Context tab and select the DataSet node.
- 3. Set the node’s property Supply Function. Click inside the value cell and choose the button with the ellipsis (three dots). In the dialog box, confirm the proposed name, supplyDataSet.
Make sure that in the Project menu the Build Automatically option is selected and subsequently saved. Otherwise, you have to (re)build the project manually each time a declarative change is made, such as the addition of a new method. |
- 4. Choose Ctrl+S to save the changed controller and rerun the code generator. This recreates the Java code for the controller, including the new supply function we have just declared.
- 5. Navigate to the new supplyDataSet() method by choosing Go.
- 6. Between the //@@begin and //@@end tags, insert the following code:
Calendar myCalendar = Calendar.getInstance();
- myCalendar.setLenient(false);
- java.sql.Date tmpDate = new java.sql.Date(0);
int stockLen = STOCK.length;
int m = 1, d = 1,y = 1980;
CctCode eur = new CctCode("EUR", null, null, null, null, null);
for ( int i = 0; i < stockLen; i++ ) {
IDataSetElement product = node.createAndAddDataSetElement();
- product.setAvailable((i%6 == 0) ? false : true);
- product.setArticle(STOCK[i][0]);
- product.setColor(STOCK[i][1]);
- product.setPrice(new CctAmount(new BigDecimal(STOCK[i][2]), eur));
d = ( i % 2 == 0 ) ? (i+4)%30 : d;
m = ( i % 2 == 0 ) ? i%12 : (i-1)%12;
y = ( i % 3 == 0 ) ? 2000+i : y;
- myCalendar.set(y,m,d);
- tmpDate.setTime(myCalendar.getTimeInMillis());
Date date = new Date(myCalendar.getTime().getTime());
- product.setDate(new CctDate(date));
}
- 7. There is no need to write any code that calls the supply method explicitly. Instead it is called by the 1framework automatically whenever the node is empty or invalid and its data is requested, for example when a Table UI element is bound to that node.
- 8. Organize Imports (Ctrl+Shift+O) Choose com.sap.test.tc.wd.tut.table.sofi.wdp.IPublicTutorial.IDataSetElement and confirm by choosing Finish.
- 9. Between the //@@begin others and //@@end tags, which can be found at the end of the file, insert the following code:
private static final String STOCK[][] = { {"Jacket","blue","34.60"}, {"Skirt","red","24.95"}, {"T-Shirt","orange","29.90"}, {"Trousers","black","64.90"}, {"Top","black","44.90"}, {"Dress","colored","78.90"}, {"Blouse","white","35.50"}, {"Jeans","blue","89.90"}, {"Pullover","red","69.00"}, {"Sweatshirt","green","61.60"}, {"Polo Shirt","yellow","14.65"}, {"Shorts","dark blue","44.90"}, {"Blouse","white","49.90"}, {"Skirt","white","55.00"}, {"Pullover","white","127.00"}, {"Dress","black","178.90"}, {"Top","red","54.00"}, {"Trousers","black","79.00"}, {"T-Shirt","red","45.60"}, {"Jacket","white","55.80"}, {"Pullover","white","130.90"}, {"Jacket","blue","200.90"}, {"Skirt","brown","89.90"}, {"Alpaca Pullover","brown","230.00"}, {"Lambswool Pullover","yellow","130.00"} }; |
- 10. Save the project and select Deploy New Archive and Run from the context menu of the application.
The following screen should be displayed in your browser:
Implementing Sorting
In the releases SAP NetWeaver 2004 and SAP NetWeaver 7.0, Web Dynpro did not provide any sorting logic by default, this had to be implemented explicitly by the application developer. The SAP NetWeaver 7.0 version of this tutorial offers a separate Java class (called TableSorter) to help the application developer with this task. Although the NW 7.1 version of Web Dynpro is now able to sort a node directly, this tutorial continues to use an updated version of the TableSorter class that supports the new 7.1 features.
Web Dynpro can sort a node via the sortElements(ICMISortCriterion) method. This method is even able to sort by multiple columns.
Importing the TableSorter Class
- 1. Select Import from the File menu.
- 2. Choose General → File System and choose Next.
- 3. Specify the folder where the Java classes are stored (TableSorter.java and its base class TableHelper.java) and select them by selecting the corresponding checkbox. You may also import TableFilter.java, we will need it later.
- 4. Now specify where to store the class in the current project structure by using the second browse button Into Folder. Navigate through the project structure as follows: Resources → src → packages → com → sap → test → tc → wd → tut → table → sofi → util and confirm by choosing OK.
- 5. Manually append a new folder to this path and name it util, so that the path specified describes the location src\packages\com\sap\test\tc\wd\tut\table\sofi\util.
Confirm by choosing Finish.
If you choose a different location, you need to change the package for the Java class accordingly.
Import Window | Resulting project struture |
| |
|
|
|
Enhancing the Context
We need to store the TableSorter instance in a context attribute to be able to access it at runtime. Each time the user clicks a table column header, we need to trigger the table’s onSort event to sort the table correctly.
- 1. Double-click the Component Controller and switch to the Context tab.
- 2. Add an attribute named TableSorter to the context root node and browse for its Java Native Type by typing its class name TableSorter into the filter input field. The class should be found and displayed in the lower area, Matching Items. If more than one item of the same class name is found, select the one matching your project´s structure path, for example util, choose OK and confirm by choosing Finish.
- 3. Double-click the Tutorial component in the project structure, double-click the data link between the TutorialView and Component Controller icons and map the TableSorter attribute to TutorialView.
- 4. Double-click TutorialView and add a new action. Switch to the Action tab and choose the New… button on the upper right-hand side. Name the action Sort and choose Finish.
- 5. Open its method implementation by pressing the F3 key or via the context menu. Add the following code between the //@@begin and //@@end tags:
- wdContext.currentContextElement().
getTableSorter().sort(wdEvent, wdContext.nodeDataSet());
- 6. Switch to the wdDoModifyView() method and insert the following code between the //@@begin and //@@end tags:
if (firstTime) {
IWDTable table = (IWDTable)view.getElement("ProductsCatalogue");
- wdContext.currentContextElement().setTableSorter(
new TableSorter(table, wdThis.wdGetSortAction(), null));
}
- 7. Organize Imports (Ctrl+Shift+O),
- 8. Switch to the Layout tab of TutorialView and select the ProductsCatalogue table UI element from the Outline view in the bottom left pane. Select the Properties tab and associate the table’s onSort event with the Sort action we just created.
- 9. Save, deploy the new archive, and run it.
Now, when you click a column header a sort order icon appears on the sorted column.
Implementing Filtering
Filtering is a tedious topic in Web Dynpro in SAP NetWeaver 7.0. In order to apply filtering to a table, we previously needed a total of three context nodes:
One for the table data (which we already have)
One to hold the filter values
One to hold the subset of rows after filtering has been applied
All three nodes needed to have the same structure and had to be located directly under the root node (I.E. Independent nodes). Additionally, we needed an attribute that uniquely identifies each element.
With Web Dynpro 7.1 however, this has become much easier. Now Web Dynpro can apply filtering at the level of context mapping. The application can decide for each element of the data node whether it is visible in the mapped node or not. This can be achieved by attaching an IWDMappingFilter to the mapped node’s IWDNodeInfo.
Nonetheless, there is still some work left to do for the application developer. For this reason, this tutorial provides a pre-written class, called TableFilter, which makes filtering really easy.
Filtering Capabilities
The table filter has the following capabilities:
Strings: If the filter value contains simply the letter “a”, this is treated as if you had entered “*a*” and returns any field that contains an “a” at any position. The search is not case sensitive!
It also accepts the operators “#” (for exclude) or “=” (for include) in the first position.
Numeric values, dates, and times: The filter searches either for the exact value, or if the following operators are used, ranges, inclusions, and exclusions can be specified.
If you use the inclusion (“=”) or exclusion (“#”) operators, then these should always appear first.
For ranges: “~100” specifies all values up to and including 100 ”1~100” specifies all values between 1 and 100 inclusive ”100~” specifies all values greater than or equal to 100
Boolean values: Booleans can be filtered using the inclusion (“=”) or the exclusion (“#”) operators in the first position.
Importing the TableFilter Class
If you did not import the TableFilter together with TableSorter and TableHelper, do it now. Proceed as described in the Implementing Sorting section.
Enhancing the Context
We have to create and save a TableFilter just like the TableSorter and we need to have various context attributes available that can store the filter values. Since these attributes are only relevant for filtering, they will reside in the view controller’s context rather than being mapped from the component controller.
- 1. Double-click the View Controller and switch to the context tab.
- 2. Directly under the context root node, add a new Java Native Type attribute named TableFilter. Set the data type of this attribute to TableFilter in the same way as you did for the TableSorter attribute.
- 3. Create a new node under the context root node called FilterAttributes. Set its collection cardinality property to 1..1. Additionally, the initializeLeadSelection property should be set.
- 4. Add the attributes Article, Available, Color, Date, Price, Quantity, and Total_per_Article, all of type string, not calculated and not read-only. These attributes correspond to the table columns that can be used for filtering.
The context should now look as follows:
Methods and Actions
TutorialView Controller
- 1. Double-click the TutorialView and switch to the Actions tab.
- 2. Add another action and name it Filter.
- 3. Switch to the Java Editor of TutorialView. In the Outline View, select the wdDoModifyView() method and insert the highlighted line of code:
if (firstTime) {
IWDTable table = (IWDTable)view.getElement("ProductsCatalogue");
- wdContext.currentContextElement().setTableSorter(
new TableSorter(table, wdThis.wdGetSortAction(), null));
- wdContext.currentContextElement().setTableFilter(
new TableFilter(table,
- wdThis.wdGetFilterAction(),
- wdContext.nodeDataSet(), null));
}
- 4. Organize Imports (Ctrl+Shift+O), save the project, and then rebuild it.
- 5. Jump to the Filter method implementation, insert the following code between the //@@begin and //@@end tags, and save it:
- wdContext.currentContextElement().getTableFilter().filter();
Binding the Filter Action and Values
In order to make the Table UI element aware that it has filtering capability, you must associate the Table UI element’s onFilter event with the Filter action.
- 1. Double-click TutorialView and switch to the Layout tab. Then switch to the Properties tab in the lower screen section and select in the Outline view the table element ProductsCatalogue. In the dropdown list for the onFilter event, select the Filter action.
As soon as a TableColumn is bound to an appropriate filter action, a new first row is created automatically in which you can enter the filter values.
- 2. Select the TableColumn named Article. Bind its filterValue property to the corresponding context attribute in the FilterAttributes node.
Repeat the above step for each table column.
- 3. Save the project, deploy the new archive and run it.
Filtering and sorting should now be working.