In the last couple of months I saw a lot of forms that had issues with binding tables to data. I’d like to give some insight to help avoiding the most common mistakes when using tables. The content of this blog is based on Adobe LifeCycle Designer 7.1 and SAP NetWeaver 2004s. Starting with Designer 7.1 tables are available as fields that can be dragged&dropped from the field library directly on the form. On the server side you need SAP NetWeaver 2004s to render a form that makes use of this feature.
I want to start with tables on an InteractiveForm UIElement in Web Dynpro. A table can be used to display a node and subnodes structure of the Web Dynpro context. For a table with multiple rows the node has to have a cardinality of n. Each instance of the node represents one row of the table. When you design the form, you have to bind the table row of the form to a(context) node that has a cardinality of n. Cardinality n means that the node is repeated in the data stream for the form. Subnodes contain data that goes into the cells of each row. Hence, you have to bind the fields of the cells to the subnodes of the node representing the data row. The node for the pdfDatasource (the property of the Web Dynpro UIElement InteractiveForm) points to should be of cardinality one and hence shouldn’t be used as the node a table row is bound to. If you do so the table will show only one row.
When you design a form using transaction SFP of the ABAP workbench you can use tables on a form if you have a Dictionary type for a table-based data structure. Each table row of the data is presented by a data node that is a subnote of the context node or the node in the Designer data view. The node of the table has the name as you defined it in the interface (parameter name) and the subnode representing a table row has the name “data”. Table-like structures get a table icon on the context tab. On your form design you have to bind the table to the node representing the table in your data view (the node gets it’s name from the parameter name in the interface). A table row is bound to the (repeating) node with the name “data”. Cells in a table row are bound to subnodes of the “data” node. Tables in transaction SFP are easier to use since you get the table structure automatically. In Web Dynpro you have to create that structure in the view context on your own.
The following tips are independent of the integration environment.
For table rows the option “Repeat row for each data item” should be selected. You’ll find that option on the “Binding” tab of the table row. I saw a couple of form designs that had the “Repeat table for each data item” selected instead what led to a different, unintended result (a repetition of the table not the row). If your table shows only one row, you probably forgot to select this option. You can find additional options on the “Binding” tab like minimum number of rows or maximum number of rows.
If you do not know the number of rows during design time of the form (what’s usually the case) you have to carefully design the layout so that it can grow according to the amount of data. That means that you have to use subforms with flowed content. And if you have a lot of rows that might lead to page breaks you have to make sure that also your body page has flowed content. If your table overwrites other parts of your form design or grows outside a page it’s a hint that a subform in your form hierarchy does not have flowed content. And it is not necessarily the subform that contains the table so take a look at the whole path from the subform containing the table up to the body page.
If a table spans multiple pages you may want to decide if the header of the table should be included in subsequent pages. To do so you have to select the table header in the form hierarchy and go to the “Pagination” tab. There you will find the option “Include header in subsequent pages”. Select this option if you want to have a header for the table on every page. If the option is grayed out you might want to check if your subforms have flowed content.
Displaying the same data in two tables is not possible. A binding to repeated data “consumes” all data nodes and afterwards this data is not available for further bindings because it’s already “consumed”. A binding to repeated data looks like “$record.row[*]”. The important part is “[*]” that denotes that the data node might appear multiple times in the data stream.