12-11-2021 4:01 PM
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
12-12-2021 11:38 AM
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( ).
12-11-2021 5:52 PM
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> ).
12-11-2021 11:43 PM
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( ).
12-12-2021 2:11 PM
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
12-12-2021 3:52 PM
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.
12-12-2021 6:38 PM
Thanks a lot. Although always a bit strange to use undocumented kernel functions - this one is great!
12-12-2021 9:27 PM
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 :
12-12-2021 11:38 AM
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( ).