Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Set focus on edit control in dialogbox

Clemenss
Active Contributor
0 Kudos

My situation:

In an ALV fullscreen grid (used CL_SALV_TABLE) a handler for hotspot field creates a dialog box (CL_GUI_DIALOGBOX_CONTAINER) and places a CL_GUI_TEXTEDIT in it.

We use this to show specific order long texts in the CL_GUI_TEXTEDIT control. We call SET_READONLY_MODE( abap_true ) because the text should be read-only.

I can't set the focus neither on TEXTEDIT control nor on the dialog box.

If I click on the text it has better readability and I can use ESC key or hit the close icon to close the dialogbox (CLOSE handler uses FREE method of dialogbox and textedit).

If I don't click on the text, ESC key leaves the grid list which is not wanted.

I tried various combinations of SET_FOCUS methods, also static method CL_GUI_CONTROL=>SET_FOCUS( <dialogbox object> or <textedit object> ). Nothing will move the focus from ALV grid to textedit/dialog control.

Any good ideas appreciated, recommendations without having tried not specially welcome.

Thank you, best regards, Clemens

1 ACCEPTED SOLUTION

Sandra_Rossi
Active Contributor

The problem is that when you display in full screen, CL_SALV_TABLE forces a flush (PAI/PBO) and does a SET_FOCUS to the grid just before displaying again, which overrides your own SET_FOCUS.

You can solve the issue by instantiating CL_SALV_TABLE with a container.

For instance, this works (changes are marked CHA12345):

*&---------------------------------------------------------------------*
*& Report ZZCLIDIALOG
*&---------------------------------------------------------------------*
REPORT zzclidialog.<br>DATA gt_t100 TYPE STANDARD TABLE OF t100 WITH DEFAULT KEY.
CLASS zcl_bc_dialog DEFINITION
  CREATE PUBLIC .
  PUBLIC SECTION.
    CLASS-METHODS display_string
      IMPORTING
        !width     TYPE int4 DEFAULT 800
        !height    TYPE int4 DEFAULT 500
        !top       TYPE int4 DEFAULT 10
        !left      TYPE int4 DEFAULT 50
        !iv_string TYPE string .
    CLASS-METHODS handle_link_click FOR EVENT link_click OF cl_salv_events_table
      IMPORTING row column.
  PROTECTED SECTION.
  PRIVATE SECTION.
    CLASS-DATA mo_textedit TYPE REF TO cl_gui_textedit .
    CLASS-DATA mo_container TYPE REF TO cl_gui_dialogbox_container .
    CLASS-METHODS close
        FOR EVENT close OF cl_gui_dialogbox_container .
ENDCLASS.
CLASS zcl_bc_dialog IMPLEMENTATION.
  METHOD close.
    IF mo_textedit IS BOUND.
      mo_textedit->free( ).
      mo_container->free( ).
      FREE:
        mo_textedit,
        mo_container.
    ENDIF.
  ENDMETHOD.
  METHOD display_string.
    close( ).
    mo_container =
      NEW #(
        width  = width
        height = height
        top    = top
        left   = left   ).
    SET HANDLER close FOR mo_container.
    mo_textedit = NEW #(
      parent = mo_container ).
    mo_textedit->set_readonly_mode( 1 ).
    mo_textedit->set_textstream( iv_string ).
    cl_gui_control=>set_focus( mo_textedit )."also tried mo_container
  ENDMETHOD.
  METHOD handle_link_click.
* whatever is clicked - just display something
    DATA lv_string TYPE string.
    LOOP AT gt_t100 ASSIGNING FIELD-SYMBOL(<t100>).
      lv_string = lv_string
        && <t100>-sprsl && cl_abap_char_utilities=>horizontal_tab
        && <t100>-arbgb && cl_abap_char_utilities=>horizontal_tab
        && <t100>-msgnr && cl_abap_char_utilities=>horizontal_tab
        && <t100>-text  && cl_abap_char_utilities=>cr_lf.
    ENDLOOP.
    display_string( lv_string ).
  ENDMETHOD.
ENDCLASS.

PARAMETERS dummy.                                           " CHA12345
AT SELECTION-SCREEN OUTPUT.                                 " CHA12345
  CHECK gt_t100 IS INITIAL.                                 " CHA12345
*START-OF-SELECTION.                                        " CHA12345
  SELECT
    *
    FROM t100
    INTO TABLE gt_t100
  UP TO 50 ROWS.
  cl_salv_table=>factory(
    EXPORTING r_container  = cl_gui_container=>screen0      " CHA12345
    IMPORTING r_salv_table = DATA(lr_salv)
    CHANGING t_table = gt_t100 ).
  DATA:
  lo_col_tab  TYPE REF TO cl_salv_column_table.
  lo_col_tab ?= lr_salv->get_columns( )->get_column( 'ARBGB' ).
  lo_col_tab->set_cell_type( if_salv_c_cell_type=>hotspot ).
  SET HANDLER zcl_bc_dialog=>handle_link_click FOR lr_salv->get_event( ).
  lr_salv->display( ).
7 REPLIES 7

Sandra_Rossi
Active Contributor
0 Kudos

Although you said it doesn't work for you, my program with the same scenario works when I use CL_GUI_CONTROL=>SET_FOCUS( <dialogbox object> or <textedit object> ).

Clemenss
Active Contributor
0 Kudos

Hi Sandra, please let me know the trick: Here's my test program - sorry 77 lines for the little demo, still focus remains on the grid. Thank you, Best regards Clemens

*&---------------------------------------------------------------------*
*& Report ZZCLIDIALOG
*&---------------------------------------------------------------------*
REPORT zzclidialog.
DATA gt_t100 TYPE STANDARD TABLE OF t100 WITH DEFAULT KEY.
CLASS zcl_bc_dialog DEFINITION
  CREATE PUBLIC .
  PUBLIC SECTION.
    CLASS-METHODS display_string
      IMPORTING
        !width     TYPE int4 DEFAULT 800
        !height    TYPE int4 DEFAULT 500
        !top       TYPE int4 DEFAULT 10
        !left      TYPE int4 DEFAULT 50
        !iv_string TYPE string .
    CLASS-METHODS handle_link_click FOR EVENT link_click OF cl_salv_events_table
      IMPORTING row column.
  PROTECTED SECTION.
  PRIVATE SECTION.
    CLASS-DATA mo_textedit TYPE REF TO cl_gui_textedit .
    CLASS-DATA mo_container TYPE REF TO cl_gui_dialogbox_container .
    CLASS-METHODS close
        FOR EVENT close OF cl_gui_dialogbox_container .
ENDCLASS.
CLASS zcl_bc_dialog IMPLEMENTATION.
  METHOD close.
    IF mo_textedit IS BOUND.
      mo_textedit->free( ).
      mo_container->free( ).
      FREE:
        mo_textedit,
        mo_container.
    ENDIF.
  ENDMETHOD.
  METHOD display_string.
    close( ).
    mo_container =
      NEW #(
        width  = width
        height = height
        top    = top
        left   = left   ).
    SET HANDLER close FOR mo_container.
    mo_textedit = NEW #(
      parent = mo_container ).
    mo_textedit->set_readonly_mode( 1 ).
    mo_textedit->set_textstream( iv_string ).
    cl_gui_control=>set_focus( mo_textedit )."also tried mo_container
  ENDMETHOD.
  METHOD handle_link_click.
* whatever is clicked - just display something
    DATA lv_string TYPE string.
    LOOP AT gt_t100 ASSIGNING FIELD-SYMBOL(<t100>).
      lv_string = lv_string
        && <t100>-sprsl && cl_abap_char_utilities=>horizontal_tab
        && <t100>-arbgb && cl_abap_char_utilities=>horizontal_tab
        && <t100>-msgnr && cl_abap_char_utilities=>horizontal_tab
        && <t100>-text  && cl_abap_char_utilities=>cr_lf.
    ENDLOOP.
    display_string( lv_string ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  SELECT
    *
    FROM t100
    INTO TABLE gt_t100
  UP TO 50 ROWS.
  cl_salv_table=>factory(
    IMPORTING r_salv_table = DATA(lr_salv)
    CHANGING t_table = gt_t100 ).
  DATA:
  lo_col_tab  TYPE REF TO cl_salv_column_table.
  lo_col_tab ?= lr_salv->get_columns( )->get_column( 'ARBGB' ).
  lo_col_tab->set_cell_type( if_salv_c_cell_type=>hotspot ).
  SET HANDLER zcl_bc_dialog=>handle_link_click FOR lr_salv->get_event( ).
  lr_salv->display( ).

For information, in the method display_string, if you add the following lines after the call of "cl_gui_control=>set_focus" then it solves the problem on my side.

* Set final focus (suppress other set focus commands)
CALL 'DYNP_SET_STATUS' ID 'FUNCTION' FIELD 14
ID 'VALUE' FIELD 1. "#EC CI_CCALL

chaouki.akir Nice finding, it's worth a separate answer! For information, I found a reference of this solution also in note 434257 - Performance Assistant in the background: final focus.

Clemenss
Active Contributor

Thanks a lot. Although always a bit strange to use undocumented kernel functions - this one is great!

Yes, I agree. To find these two lines of code, I called in your program, the function DOKU_OBJECT_SHOW.

The function DOKU_OBJECT_SHOW is using SET_FOCUS but is not having the problem of focusing.

    DATA dialogbox TYPE REF TO cl_gui_dialogbox_container.<br>    DATA: links TYPE STANDARD TABLE OF tline.<br><br>    CALL FUNCTION 'DOKU_OBJECT_SHOW'<br>      EXPORTING<br>        dokclass         = 'CHAP'<br>        dokname          = 'PROXY_DOC000'<br>      TABLES<br>        links            = links<br>      EXCEPTIONS<br>        object_not_found = 1<br>        sapscript_error  = 2<br>        OTHERS           = 3.<br><br>    IF sy-subrc <> 0.<br>      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.<br>    ENDIF.<br><br><br>

Debugging, I found the below code where these two lines of code are coming from (class CL_EPSS_GENERIC and method

set_focus) and then I decided to try to use them :

Sandra_Rossi
Active Contributor

The problem is that when you display in full screen, CL_SALV_TABLE forces a flush (PAI/PBO) and does a SET_FOCUS to the grid just before displaying again, which overrides your own SET_FOCUS.

You can solve the issue by instantiating CL_SALV_TABLE with a container.

For instance, this works (changes are marked CHA12345):

*&---------------------------------------------------------------------*
*& Report ZZCLIDIALOG
*&---------------------------------------------------------------------*
REPORT zzclidialog.<br>DATA gt_t100 TYPE STANDARD TABLE OF t100 WITH DEFAULT KEY.
CLASS zcl_bc_dialog DEFINITION
  CREATE PUBLIC .
  PUBLIC SECTION.
    CLASS-METHODS display_string
      IMPORTING
        !width     TYPE int4 DEFAULT 800
        !height    TYPE int4 DEFAULT 500
        !top       TYPE int4 DEFAULT 10
        !left      TYPE int4 DEFAULT 50
        !iv_string TYPE string .
    CLASS-METHODS handle_link_click FOR EVENT link_click OF cl_salv_events_table
      IMPORTING row column.
  PROTECTED SECTION.
  PRIVATE SECTION.
    CLASS-DATA mo_textedit TYPE REF TO cl_gui_textedit .
    CLASS-DATA mo_container TYPE REF TO cl_gui_dialogbox_container .
    CLASS-METHODS close
        FOR EVENT close OF cl_gui_dialogbox_container .
ENDCLASS.
CLASS zcl_bc_dialog IMPLEMENTATION.
  METHOD close.
    IF mo_textedit IS BOUND.
      mo_textedit->free( ).
      mo_container->free( ).
      FREE:
        mo_textedit,
        mo_container.
    ENDIF.
  ENDMETHOD.
  METHOD display_string.
    close( ).
    mo_container =
      NEW #(
        width  = width
        height = height
        top    = top
        left   = left   ).
    SET HANDLER close FOR mo_container.
    mo_textedit = NEW #(
      parent = mo_container ).
    mo_textedit->set_readonly_mode( 1 ).
    mo_textedit->set_textstream( iv_string ).
    cl_gui_control=>set_focus( mo_textedit )."also tried mo_container
  ENDMETHOD.
  METHOD handle_link_click.
* whatever is clicked - just display something
    DATA lv_string TYPE string.
    LOOP AT gt_t100 ASSIGNING FIELD-SYMBOL(<t100>).
      lv_string = lv_string
        && <t100>-sprsl && cl_abap_char_utilities=>horizontal_tab
        && <t100>-arbgb && cl_abap_char_utilities=>horizontal_tab
        && <t100>-msgnr && cl_abap_char_utilities=>horizontal_tab
        && <t100>-text  && cl_abap_char_utilities=>cr_lf.
    ENDLOOP.
    display_string( lv_string ).
  ENDMETHOD.
ENDCLASS.

PARAMETERS dummy.                                           " CHA12345
AT SELECTION-SCREEN OUTPUT.                                 " CHA12345
  CHECK gt_t100 IS INITIAL.                                 " CHA12345
*START-OF-SELECTION.                                        " CHA12345
  SELECT
    *
    FROM t100
    INTO TABLE gt_t100
  UP TO 50 ROWS.
  cl_salv_table=>factory(
    EXPORTING r_container  = cl_gui_container=>screen0      " CHA12345
    IMPORTING r_salv_table = DATA(lr_salv)
    CHANGING t_table = gt_t100 ).
  DATA:
  lo_col_tab  TYPE REF TO cl_salv_column_table.
  lo_col_tab ?= lr_salv->get_columns( )->get_column( 'ARBGB' ).
  lo_col_tab->set_cell_type( if_salv_c_cell_type=>hotspot ).
  SET HANDLER zcl_bc_dialog=>handle_link_click FOR lr_salv->get_event( ).
  lr_salv->display( ).