BSP a Developers Journal: Part XI – Table View Iterators
Although the SAP supplied BSP extensions are full of a kinds of great User Interface elements, a few stand out as the most important and powerful ones. Without a doubt the table view control falls into that category. With its ability to display or edit tabular data (including all kinds of built in functionality for sorting, filtering, etc.), it would be difficult to imagine doing BSP development without the Table View control.
The starting point for anyone just learning BSP or Table View should be Brian McKellar’s weblog: BSP Programming: HTMLB TableView Iterator (BSP Programming: HTMLB TableView Iterator). There would be no point in trying to duplicate the great explanation that Brian has already created in this weblog. Instead I will share some real world examples from our development. I will add just one comment for readers who come to BSP from an ABAP background. Table Views are your equivalent of the ALV Grid and Table View Iterators are like an ALV Field Catalog on steroids.
The Table View was one of the very first BSP extensions that we really spent a lot of time learning at our company. We didn’t have SDN yet, so we started with the examples provided in the system: SBSPEXT_HTMLB and in more recent support packages SBSPEXT_TABLE. SBSPEXT_TABLE is especially useful in demonstrating the more advanced techniques possible with the Table View.
I want to share with you 3 examples of Table Views that have iterators. We will start with the simplest example. In this example I will only use the iterator to control what columns of the table are displayed and what the titles of each column will be. In this example I had a very dynamic structure to my table I wanted to display, so I wanted more control over what was output. The following is a screen shot of the final results:
I know that I want to generate the column names using the very data in the table itself. The nice thing about the iterator class is that I can just add this data as an attribute of the class and pass it in through the constructor. I actually do this in the DO_REQUEST method of my Controller right before I call my view. Also you might notice that I keep the instance of my iterator class in my Model Class for easy access from both my Controller and my View. The following is the code that I use to create my constructor:
****Create the new iterator. create object model->hst_iterator exporting i_catt = icatt. view = create_view( view_name = ‘Chart1.htm’ ). call_view( view ).
Since this is such a simple example we will only be implementing the get_column_definitions method of our iterator. We have our returning parameter, P_COLUMN_DEFINITIONS, where we will build our column definitions. This is very similar to the columnDefinitions parameter of the Table View itself. I have not noticed a difference in performance between the two options. However I tend to use the Iterator (even when I am just controlling the column definitions), because I feel that it makes the application easier to understand and maintain. By doing so I always know that the definition of my table is in my iterator class not spread out somewhere in the controller or model classes. Finally we have the following snippet of code where I have one fixed column, DATUM, and then my variable category columns:
clear p_column_definitions. clear p_overwrites. data tv_column type tableviewcontrol. clear tv_column. tv_column-columnname = ‘DATUM’. tv_column-sort = ‘X’. append tv_column to p_column_definitions. data: wa_catt like line of catt. data: counter(1) type n. loop at catt into wa_catt. counter = counter + 1. clear tv_column. concatenate ‘HOURS’ counter into tv_column-columnname. condense tv_column-columnname no-gaps. tv_column-title = wa_catt-cat_name. tv_column-sort = ”. append tv_column to p_column_definitions. endloop.
We are ready for a little more ambitious example. This time lets use the table view iterator to add a hyper link column to the table. The following is what the end results will look like:
We will want to custom render at the cell level so we will be implementing method RENDER_CELL_START in our iterator class. All the data we will need to render our link will be contained in the Table View table itself. We will use the fact that the current row of the data table is passed into the RENDER_CELL_START (Parameter p_row_data_ref). We just need to assign this untyped data reference into a more usable typed reference. We then can create the Link BSP extension using the Factory Method. Updated!
After posting my weblog, Brian McKellar sent me a great little tip. There is a way to access the data row without doing a memory copy. I had no idea you could do this, but you actually just cast an untyped data reference into a typed one. I have commented out my original code and replaced it with the new technique.
field-symbols: <news> type any.
data: inews type zes_abap_news_line.
data: inews type ref to zes_abap_news_line.
assign p_row_data_ref->* to <news>.
move <news> to inews.
inews ?= p_row_data_ref.
p_replacement_bee = cl_htmlb_link=>factory(
id = p_cell_id
reference = inews-link_string
reference = inews->link_string
target = ‘_TOP’
text = inews-event_desc ).
text = inews->event_desc ).
Now for our most complex example yet we will have a table view which is open for input. We will have Icons, Icons that can be clicked for an action, and a drop down listbox. The following is the finished results: