Skip to Content

In most BSP in Action: Strategic Freight Procurement with BASF EPILOG tables are choosen to present data to the user. The tables are often large, not only in regard of the number of records but also in number of columns. In certain cases the number of columns extends even over the size of the client window and users must scroll to get a complete overview.</p>

When dealing with tables, many users are used to certain features which they know from the everydays use of spreadsheet applications. Depending on the client technology, advanced UIs may offer such features.

Common requirements are to be able to reduce the number of columns displayed by removing those including less relevant data and reordering columns in order to see more important data on the left hand side.</p>

Introduction

In the Personalize My BSP (Form Items) about personalization of BSP applications it was shown how the visibility and arrangement of form layout items can be made customizable during runtime. A BSP/MVC application was implemented using the phtmlb:formlayout – tag and server side cookies.

This weblog emphasizes personalization of data displayed in tables. The example application uses the htmlb:tabelView – tag. The htmlb:tabelView – tag of the BSP extension tag library is already offering a number of features to ease handling of data presented in tables, i.e. sorting, filtering, page scrolling etc.
In this weblog it will be shown how the user can be enabled to change the visibility of columns and the order of columns during runtime. As it was implemented in the first personalization weblog, server side cookies are used to store personalized data .

The example application uses the SFLIGHT table which is shipped and available in every WebAS version (ABAP engine provided).

image

By selecting the ‘Personalize’ link another window will be opened including a list of all table columns of the SFLIGHT table. In the same way as it was implemented in the form items example, the user can now select a checkbox for not displaying a particular column and choosing a number from a dropdownlistbox for modifying the position of a column.

image

The SFLIGHT table will be modified in the following way:

1) hide column ‘Client’

2) move ‘Flight Number’ to the first column

3) move ‘Plane’ to third column

image

After setting the values and pressing the button ‘Update’ the modified data is sent from the popup window to the server. The opener window is also forced to do a submit in order to pick up these modifications. With the response arriving at the browser window the personalized layout becomes visible.

image

</br>

Implementation

In order to keep things simple the application consists of just one controller main.do (class zcl_main02_ctr) and two views:

1) main.htm displaying the form items

2) pers.htm displaying the personalization table.

The model class zcl_model02 contains now the attributes representing the table used for the personalization data, i.e. mt_columns and attribute mt_data of type FLIGHTTAB used for the content of SFLIGHT.

Again, we use server side cookies to store personalization data. There are no restrictions in size and number of server side cookies stored on the server.

When the application is run the first time, the cookie is created and initialized (method do_init of zcl_main02_ctr).

For table SFLIGHT we need to determine all of its columns. Using function module TR_NAMETAB_GET will provide the necessary data:


call function 'TR_NAMETAB_GET'
exporting
iv_tabname = 'SFLIGHT'
iv_get_lengths_in_charmode = ' '
iv_get_texts = 'X'
importing
et_dfies = lt_dfies
exceptions
not_found = 1
others = 2.
if sy-subrc <> 0.
endif.

Having all column data of the SFLIGHT table available in lt_dfies we can now extract the data which is used for personalization:</br>

– the description of each column contains field REPTEXT</br>

– the initial position is determined by the row index in of lt_defies</br></p>

By looping over lt_defies we extract the data used to be displayed in the personaliztion tabel mt_columns


loop at lt_dfies into ls_dfies.
ls_column-field_name = ls_dfies-fieldname.
ls_column-text = ls_dfies-reptext.
if syst-tabix < 10. "reduced to first 9 columns
ls_column-halign = syst-index.
else.
exit.
endif.
append ls_column to li_md->mt_columns.
endloop.

mt_columns is defined in the model class zcl_model02 and is of type HTMLBFITEM. The example application uses the fields of structure type HTMLBFITEM to represent the following information:

1) FIELD_NAME – keeps the id of the column

2) TEXT – keeps the text of the column field

3) DISP_TYPE – not needed

4) INVISIBLE – if set to ‘X’ the column is not displayed

5) HALIGN – keeps the column index

After initialization table mt_columns contains the following data:


FIELD_NAME

TEXT

INVISIBLE

HALIGN

MANDT

Clt

 

1

CARRID

ID

 

2

CONNID

No.

 

3

FLDATE

Flgt. date

 

4

PRICE

Airfare

 

5

CURRENCY

Curr.

 

6

PLANETYPE

Plane

 

7

SEATSMAX

Capacity in economy class

 

8

SEATSOCC

Occupied economy class

 

9

After the user has modified the settings according to our example above, mt_columns contains the following data:


FIELD_NAME

TEXT

INVISIBLE

HALIGN

MANDT

Clt

X

1

CARRID

ID

 

2

CONNID

No.

 

1

FLDATE

Flgt. date

 

4

PRICE

Airfare

 

5

CURRENCY

Curr.

 

6

PLANETYPE

Plane

 

3

SEATSMAX

Capacity in economy class

 

8

SEATSOCC

Occupied economy class

 

9

Iterator method get_column_definitions is  building the column definitions of table SFLIGHT according mt_columns.


method if_htmlb_tableview_iterator~get_column_definitions.
data:
ls_tvcolumn type tableviewcontrol,
ls_pcolumn type htmlbfitem.

loop at mt_columns into ls_pcolumn where invisible is initial.
ls_tvcolumn-columnname = ls_pcolumn-field_name.
append ls_tvcolumn to p_column_definitions.
endloop.
endmethod.

  

Coding

class-pool .

class pool for class ZCL_MAIN02_CTR

local type definitions

use this source file for any type declarations (class

definitions, interfaces or data types) you need for method

implementation or private method’s signature

class cl_pl02_iterator definition.

  public section.

    interfaces if_htmlb_tableview_iterator.

    data: mt_columns   type htmlbficat.

    methods: constructor importing it_columns type htmlbficat.

  private section.

    data: m_rowref type ref to sflight.

endclass.                    “cl_pl02_iterator DEFINITION

—-


  •       CLASS cl_pers_iterator DEFINITION

—-


*

—-


class cl_pers_iterator definition.

  public section.

    interfaces if_htmlb_tableview_iterator.

    data: mt_pos   type tihttpnvp.

    methods: constructor importing it_pos type tihttpnvp.

  private section.

    data: m_rowref type ref to htmlbfitem.

endclass.                    “cl_pers_iterator DEFINITION

class ZCL_MAIN02_CTR definition

public declarations

class ZCL_MAIN02_CTR definition

  public

  inheriting from CL_BSP_CONTROLLER2

  final

  create public .

public components of class ZCL_MAIN02_CTR

do not include other source files here!!!

public section.

  data MV_UPDATE_EVENT type STRING .

  methods GET_PERS_ITERATOR

    returning

      value(RI_ITERATOR) type ref to IF_HTMLB_TABLEVIEW_ITERATOR .

  methods GET_PL02_ITERATOR

    returning

      value(RI_ITERATOR) type ref to IF_HTMLB_TABLEVIEW_ITERATOR .

  methods DO_INIT

    redefinition .

  methods DO_REQUEST

    redefinition .

protected declarations

protected components of class ZCL_MAIN02_CTR

do not include other source files here!!!

protected section.

  methods DO_HANDLE_EVENT

    redefinition .

  methods DO_FINISH_INPUT

    redefinition .

private declarations

private components of class ZCL_MAIN02_CTR

do not include other source files here!!!

private section.

endclass. “ZCL_MAIN02_CTR definition

macro definitions

use this source file for any macro definitions you need

in the implementation part of the class

local class implementation

local class implementation for public class

use this source file for the implementation part of

local helper classes

*—-


Implementation application data table

class cl_pl02_iterator implementation.

  method constructor.

    mt_columns = it_columns.

  endmethod.                    “constructor

  method if_htmlb_tableview_iterator~get_column_definitions.

    data:

        ls_tvcolumn             type   tableviewcontrol,

        ls_pcolumn              type   htmlbfitem.

    loop at mt_columns into ls_pcolumn where invisible is initial.

      ls_tvcolumn-columnname   = ls_pcolumn-field_name.

      append ls_tvcolumn to p_column_definitions.

    endloop.

  endmethod.                    “IF_HTMLB_TABLEVIEW_ITERATOR~GET_COLUMN_DEFINITIONS

endclass.                    “cl_pl02_iterator IMPLEMENTATION

*—-


Implementation personalization data table

class cl_pers_iterator implementation.

  method constructor.

    mt_pos = it_pos.

  endmethod.                    “constructor

  method if_htmlb_tableview_iterator~get_column_definitions.

    data: ls_tvcolumn  type tableviewcontrol.

    ls_tvcolumn-columnname   = ‘TEXT’.

    ls_tvcolumn-title        = ‘Field Name’.

    append ls_tvcolumn to p_column_definitions.

    ls_tvcolumn-columnname   = ‘INVISIBLE’.

    ls_tvcolumn-horizontalalignment = ‘middle’.

    ls_tvcolumn-title        = ‘Invisible’.

    append ls_tvcolumn to p_column_definitions.

    ls_tvcolumn-columnname   = ‘HALIGN’.

    ls_tvcolumn-title        = ‘Position’.

    append ls_tvcolumn to p_column_definitions.

  endmethod.                    “IF_HTMLB_TABLEVIEW_ITERATOR~GET_COLUMN_DEFINITIONS

  method if_htmlb_tableview_iterator~render_row_start.

    m_rowref ?= p_row_data_ref.

  endmethod.                    “IF_HTMLB_TABLEVIEW_ITERATOR~RENDER_ROW_START

  method if_htmlb_tableview_iterator~render_cell_start.

    data:

           li_checkbox        type ref to   cl_htmlb_checkbox,

           li_ddlb            type ref to   cl_htmlb_dropdownlistbox.

*——- Render ‘invisible’ checkbox

    if p_column_key eq ‘INVISIBLE’.

      create object li_checkbox.

      li_checkbox->id        = p_cell_id.

      li_checkbox->checked   = m_rowref->invisible.

      p_replacement_bee      = li_checkbox.

    endif.

*——- Render ‘position’ ddlb

    if p_column_key eq ‘HALIGN’.

      create object li_ddlb.

      li_ddlb->id        = p_cell_id.

      li_ddlb->nameofkeycolumn   = ‘NAME’.

      li_ddlb->nameofvaluecolumn = ‘VALUE’.

      get reference of mt_pos into li_ddlb->table.

      li_ddlb->selection         = p_row_index.

      p_replacement_bee  = li_ddlb.

    endif.

  endmethod.                    “IF_HTMLB_TABLEVIEW_ITERATOR~RENDER_CELL_START

endclass.                    “cl_pers_iterator IMPLEMENTATION

class ZCL_MAIN02_CTR implementation.

method’s implementations

method do_init .

*CALL METHOD SUPER->DO_INIT

  •    .

  data:

        lv_data    type             xstring,

        ls_column  type             htmlbfitem,

        lt_dfies   type             ddfields,

        ls_dfies   type             dfies,

        li_md      type ref to      zcl_model02.

  li_md ?= create_model( model_id   = ‘m02’

                         class_name = ‘zcl_model02’ ).

*—– Read server cookie

  call method cl_bsp_server_side_cookie=>get_server_cookie

    exporting

      name                  = ‘table_columns’

      application_name      = runtime->application_name

      application_namespace = runtime->application_namespace

      username              = syst-uname

      session_id            = ‘same_for_all’

      data_name             = ‘table_columns’

    changing

      data_value            = lv_data.

  if lv_data is not initial.

*—– Extract table columns from server cookie

    import table_columns to li_md->mt_columns from data buffer lv_data.

    sort li_md->mt_columns by halign.

  else.

*—– Initialize table columns

    call function ‘TR_NAMETAB_GET’

      exporting

        iv_tabname                 = ‘SFLIGHT’

        iv_get_lengths_in_charmode = ‘ ‘

        iv_get_texts               = ‘X’

      importing

        et_dfies                   = lt_dfies

      exceptions

        not_found                  = 1

        others                     = 2.

    if sy-subrc <> 0.

*— Do nothing in this particular case

    endif.

    loop at lt_dfies into ls_dfies.

      ls_column-field_name = ls_dfies-fieldname.

      ls_column-text       = ls_dfies-reptext.

      if syst-tabix < 10.

        ls_column-halign     = syst-index.

      else.

        exit.

      endif.

      append ls_column to li_md->mt_columns.

    endloop.

*—— Write initial table columns to server cookie

    export table_columns from li_md->mt_columns to data buffer lv_data.

    call method cl_bsp_server_side_cookie=>set_server_cookie

      exporting

        name                  = ‘table_columns’

        application_name      = runtime->application_name

        application_namespace = runtime->application_namespace

        username              = syst-uname

        session_id            = ‘same_for_all’

        data_value            = lv_data

        data_name             = ‘table_columns’

        expiry_date_rel       = 30.

  endif.

endmethod.

method do_request .

*CALL METHOD SUPER->DO_REQUEST

  •    .

  data:

        lv_form_field      type              string,

        li_vw              type ref to       if_bsp_page,

        li_md              type ref to       zcl_model02.

  dispatch_input( ).

  li_md ?= get_model( ‘m02’ ).

  lv_form_field = request->get_form_field( ‘personalize’ ).

  if lv_form_field is initial.

*—— Request to display main page

    li_vw = create_view( view_name = ‘main.htm’ ).

    li_vw->set_attribute( name = ‘model’ value = li_md ).

    call_view( li_vw ).

  elseif lv_form_field eq ‘true’.

*—— Request to display personalization page

    li_vw = create_view( view_name = ‘pers.htm’ ).

    li_vw->set_attribute( name = ‘model’ value = li_md ).

    call_view( li_vw ).

  endif.

endmethod.

method get_pl02_iterator .

  data:

         li_md           type ref to   zcl_model02.

  li_md ?= get_model( ‘m02’ ).

  create object ri_iterator type cl_pl02_iterator exporting it_columns = li_md->mt_columns.

endmethod.

method get_pers_iterator .

  data:

        lv_lines        type          i,

        lt_pos          type          tihttpnvp,

        ls_pos          type          ihttpnvp,

        li_md           type ref to   zcl_model02.

  li_md ?= get_model( ‘m02’ ).

*—— Create value table for field positioning

  describe table li_md->mt_columns lines lv_lines.

  do lv_lines times.

    ls_pos-name  = syst-index.

    ls_pos-value = syst-index.

    append ls_pos to lt_pos.

  enddo.

  create object ri_iterator type cl_pers_iterator exporting it_pos = lt_pos.

endmethod.

method do_handle_event .

*CALL METHOD SUPER->DO_HANDLE_EVENT

  • EXPORTING

  •    EVENT           =

  •    HTMLB_EVENT     =

    •    HTMLB_EVENT_EX  =

  •    GLOBAL_MESSAGES =

  • RECEIVING

  •    GLOBAL_EVENT    =

  •    .

  case event.

    when ‘b02’.                          “update button pressed

      global_event = ‘update_pers’.

    when others.

  endcase.

endmethod.

method DO_FINISH_INPUT .

*CALL METHOD SUPER->DO_FINISH_INPUT

  • EXPORTING

  •    GLOBAL_EVENT    =

  •    GLOBAL_MESSAGES =

  •    .

  data:

         lv_data         type          xstring,

         li_md           type ref to   zcl_model02.

  li_md ?= get_model( ‘m02’ ).

  case global_event.

    when ‘update_pers’.

      sort li_md->mt_columns by halign.

      export table_columns from li_md->mt_columns to data buffer lv_data.

      call method cl_bsp_server_side_cookie=>set_server_cookie

        exporting

          name                  = ‘table_columns’

          application_name      = runtime->application_name

          application_namespace = runtime->application_namespace

          username              = syst-uname

          session_id            = ‘same_for_all’

          data_value            = lv_data

          data_name             = ‘table_columns’

          expiry_date_rel       = 30.

      me->mv_update_event = ‘true’.

    when others.

      clear me->mv_update_event.

  endcase.

endmethod.

endclass. “ZCL_MAIN02_CTR implementation

*===================================================================================

main.htm

      function do_personalize()

      { var s=0; r=1; w=300; h=300; x=screen.width/2;

        x=x-w/2;

        var y=screen.height/4;

        y=y-h/2;

        popUp=window.open(‘main.do?personalize=true’,’win’,’width=’+ w ‘,height=’ h +’,left=’ + x ‘,top=’ y ‘,directories=0,status=0,scrollbars=’s ‘,resizable=’ r + ‘,menubar=0,locationbar=1’);

      }

   

Discussion

Personalization of a table view was described. When implemented, the user can select the visibility
of columns and modify their order. To update the user settings one or more server roundtrips are necessary. A second way of handling modifications of tables would be to execute them in the client. The functionality must then be implemented in Javascript by extending either the htmlb:tableView tag or write a
complete new one.

Some examples of Javascript implementations of tables are available for free download.

Opening the personalization window is triggered by selecting a link. The htmlb:link tag is used which has implemented an onClientClick event handler. The xhtmlb:tabstrip tag offers a popup menu which includes a personalization link (see screen shot below). However, it requires one more server rountrip since there is no onClientClick handler available. For implementation define a controller variable (e.g. ‘on_personalize’) which is set when the menu entry is selected. When the page main.htm is reloaded execute some javascript that opens the personalization popup.


if controller->on_personalize is not initial.
window.open( 'pers.htm', .... );
endif.

!https://weblogs.sdn.sap.com/weblogs/images/2536/03screen05.jpg|height=173|alt=image|width=268|src=https://weblogs.sdn.sap.com/weblogs/images/2536/03screen05.jpg|border=0!

To report this post you need to login first.

2 Comments

You must be Logged on to comment or reply to a post.

  1. Hello Ulli,

    have you ever thought about extending this with layout saving functions like available in ALV? The goal should be to provide the user with the ability of saving different personalizations (layouts).

    Thanks for your answer & regards
    Wolfgang

    (0) 
    1. Ulli Hoffmann Post author
      Hi Wolfgang,

      saving different layouts as it is implemented e.g. in Web Dynpro ALV as well should be possible w/o much effort.
      Are you planning to do this for a customer project or product? In that case you might consider to switch from server
      side cookies to database tables. 

      regards, Ulli

      (0) 

Leave a Reply