웹딘프로 layout에 HTML_FRAGMENT를 하나 그려줍니다.

WDDOMODIFYVIEW 메소드에서

IF first_time EQ abap_true. 으로 한번만 실행되도록 하고

HTML_FRAGMENT 엘리먼트의 html 속성에 HTML tag를 하나 넣겠습니다.

<img src="/sap/public/bc/ur/nw5/1x1.gif" style="display: none;" onload="alert('script test');" />

ABAP 코드는 이렇습니다.

CAST cl_wd_html_fragment( io_view->get_element( 'HTML_FRAGMENT' ) )->set_html(
  `<img src="/sap/public/bc/ur/nw5/1x1.gif" style="display: none;" onload="alert('script test');" />`
).

내용을 설명드리겠습니다.

IMG tag를 이용해서 onload 시점에 실행할 JavaScript를 넣으면 됩니다. 예를 들어 아래 테스트 코드를 넣어 봤습니다.

alert('script test');

IMG의 onload가 실행되는 시점은 웹브라우저가 화면을 그리고 src 속성의 파일을 읽어와서야 실행됩니다. 매우 나중에 실행되는 타이밍입니다.

 

 

좀 더 복잡한 스크립트가 들어간 예제를 보여드리겠습니다.

파일 업로드 팝업인데 팝업이 뜨면 웹딘프로의 파일업로드 엘리먼트를 클릭하지 않아도 자동으로 클릭해서 파일 선택 창이 나오고 파일을 선택하면 자동으로 팝업의 OK 버튼을 눌러 닫힙니다.

CAST cl_wd_html_fragment( io_view->get_element( 'HTML_FRAGMENT' ) )->set_html(
  `<img src="/sap/public/bc/ur/nw5/1x1.gif" style="display: none;" ` &&
  `onload="` &&
  `var el = this;` &&
  `while( !el.classList.contains('lsPopupWindow') ) {` &&                 " popup div
  `  el = el.parentElement;` &&
  `}` &&
  `var file = el.querySelector('input[type=file]');` &&                   " file input box
  `var ok = el.querySelector('.urPWFooterBottomLine .lsButton');` &&      " ok button
  `file.oninput = function() { UCF_JsUtil.delayedCall( 200, ok, 'click' ); };` &&
  `file.click();` &&
  `" />`
).

IMG tag를 이용한 onload에 스크립트 넣기 방식은 동일합니다. JavaScript만 가져와서 보겠습니다.

var el = this;
while( !el.classList.contains('lsPopupWindow') ) {
  el = el.parentElement;
}
var file = el.querySelector('input[type=file]');
var ok = el.querySelector('.urPWFooterBottomLine .lsButton');
file.oninput = function() { UCF_JsUtil.delayedCall( 200, ok, 'click' ); };
file.click();

처음 4줄은 el 변수에 lsPopupWindow 이라는 class 속성을 가진 엘리먼트를 찾습니다. (웹딘프로 팝업의 태두리입니다)

5번째줄은 file 변수에 input tag의 type 속성이 file인 엘리먼트를 찾습니다. (웹딘프로 FILE_UPLOAD 엘리먼트에 해당합니다)

6번째줄은 ok 변수에 urPWFooterBottomLine 이라는 class 속성을 가진 엘리먼트 아래에 lsButton 이라는 class 속성을 가진 엘리먼트를 찾습니다. (웹딘프로 팝업의 아래쪽 OK 버튼에 해당합니다)

7번째줄은 파일 업로드 엘리먼트에 oninput 시점에 200ms 딜레이를 주고나서 OK 버튼을 click 하라는 뜻입니다. (이것은 파일 선택후 자동으로 팝업을 닫기 위한 코드 입니다)

8번째줄은 파일 업로드 엘리먼트를 click 하라는 뜻입니다. (파일 선택 창이 열립니다)

 

이 코드는 아래 프로젝트에 포함되어 있습니다.

https://github.com/boy0korea/ABAP2XLSX_HELPER

 

GitHub - boy0korea/ABAP2XLSX_HELPER: abap2xlsx helper

abap2xlsx helper. Contribute to boy0korea/ABAP2XLSX_HELPER development by creating an account on GitHub.

github.com

 

 

공식적으로 부모 컴포넌트를 찾는 방법은 없습니다.

여기서는 data_container_superior 를 활용합니다.

 

서버버전은 731 기준입니다.

 

 

  DATA: lo_wdr_comp TYPE REF TO cl_wdr_component,
  lo_wdr_client_comp TYPE REF TO cl_wdr_client_component,
  lv_parent_comp_name TYPE string.
  lo_wdr_comp ?= wd_this->wd_get_api( ).
  lo_wdr_client_comp ?= lo_wdr_comp->data_container_superior.
  lv_parent_comp_name = lo_wdr_client_comp->parent->component_name.

 

서버버전 SAP NW ABAP 7.31 이상에서 가능합니다.

wdr_task=>application->get_api( )->get_client_information( )->get_client_width( ).

또는

wd_this->wd_get_api( )->get_component( )->get_application( )->get_client_information( )->get_client_width( ).

 

참고:

https://help.sap.com/viewer/7b44f2a7728810148a4b1a83b0e91070/7.5.9/en-US/d1c9f41cf86348d3851f07e90966bbd5.html

테마가 ABAP(ERP) 서버에 있다면:

WD_GLOBAL_PARAMETERS 을 실행하여서 테마를 지정하면 됩니다.

 

테마가 포탈(EP) 서버에 있다면:

인핸스먼트가 필요합니다.

 

서버버전은 731 기준입니다.

위치는 CL_WDY_WB_LS_RENDERING_SERVICE 클래스의 CONSTRUCTOR 메소드 끝나는 부분입니다.

 

ENHANCEMENT 1  YE_CL_WDY_WB_LS_RENDERING_SERV.    "active version
* EP 테마 적용
  concatenate 'http://테마주소/'
              m_ur_system->themepartid '/ls_' css_device '.css'
              into m_ur_system->cssurl. "#EC NOTEXT
ENDENHANCEMENT.

 

서버버전은 701 기준입니다.

위치는 CL_WDY_WB_RENDERING_SERVICE 클래스의 RENDER_NW5 메소드 끝나는 부분입니다.

 

ENHANCEMENT 1  YE_CL_WDY_WB_RENDERING_SERVICE.    "active version
* 웹딘 테마 적용
  REPLACE ALL OCCURRENCES OF themeroot IN header WITH 'http://테마주소'.
ENDENHANCEMENT.

IE 호환성 보기를 사용하는 사이트에서 이 인핸스먼트를 적용하면, 웹딘 개발이 편해집니다.

SE80에서 웹딘 뷰 레이아웃 미리보기(뷰디자이너)에 강제로 호환성보기 모드를 지정하는 내용입니다.

미리보기 부분에 마우스로 클릭해도 반응하지 않던 웹딘이

인핸스먼트 후에는 잘 반응하게 됩니다.

 

Activate compatibility mode in your Internet Explorer - otherwise the application will not work correctly or visualization errors may occur

 

 

 

 

구현 위치: CL_HTTP_EXT_VIEWDESIGNER -> IF_HTTP_EXTENSION~HANDLE_REQUEST  끝부분

  server->response->set_header_field( name  = 'X-UA-Compatible'
                                      value = 'IE=5' ).

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://blogs.sap.com/2013/11/25/how-to-close-ovs-popup-window/

How to Close OVS Popup window

November 25, 2013

 

소개

이글은 웹딘프로아밥에서 OVS 팝업 윈도우를 닫는 코드에 대해 설명합니다.

 

요구사항은 다음 글에서 시작되었습니다: https://scn.sap.com/thread/3456054 - OVS에서 검색 결과가 없을때 새 팝업을 열고 OVS는 닫는 방법을 알고 싶습니다.

 

준비물

OVS 서치 헬프  작성법.

 

이 글에서는 OVS 서치 헬프 작성법을 설명하지 않겠습니다. 이미 인터넷에 비슷한 글이 많이 있습니다. OVS 작성법을 먼저 공부하려면 대표적으로 Amy King의 다음 글을 참고하세요: https://scn.sap.com/docs/DOC-32690.

 

단계별 진행

OVS를 만들었다면 다음 단계를 따라가세요. 목표는 OVS에서 검색결과가 없을때 새 팝업을 열고 자동으로 OVS 윈도우를 닫는 것입니다.

 

주의: 지금 설명하는 방법은 여러 해결방법중 한가지를 보여주는 것으로 유일한 해결책은 아닙니다.

 

 

뷰의 어트리뷰트 탭으로 이동하여 어트리뷰트 GR_HANDLE 을 타입 TYPE REF TO IF_WDR_OVS_LISTENER 으로 만듭니다.

/wp-content/uploads/2013/11/1_331155.jpg

 

이제 아래 코드를 ON_OVS 메소드(OVS의 이벤트 핸들러)에 입력합니다.

 

ON_OVS
METHOD onovs .
* declare data structures for the fields to be displayed and
* for the table columns of the selection list, if necessary
   TYPES:
     BEGIN OF lty_stru_input,
*   add fields for the display of your search input here
       carrid TYPE string,
     END OF lty_stru_input.
   TYPES:
     BEGIN OF lty_stru_list,
*   add fields for the selection list here
       carrid TYPE string,
     END OF lty_stru_list.


   DATA: ls_search_input  TYPE lty_stru_input,
         lt_select_list   TYPE STANDARD TABLE OF lty_stru_list,
         ls_text          TYPE wdr_name_value,
         lt_label_texts   TYPE wdr_name_value_list,
         lt_column_texts  TYPE wdr_name_value_list,
         lv_window_title  TYPE string,
         lv_group_header  TYPE string,
         lv_table_header  TYPE string.


   DATA: lo_window_manager TYPE REF TO if_wd_window_manager,
         lr_view_controller TYPE REF TO if_wd_view_controller,
         lo_api_component  TYPE REF TO if_wd_component,
         lo_window         TYPE REF TO if_wd_window,
         l_text            TYPE string_table.


   FIELD-SYMBOLS: <ls_query_params> TYPE lty_stru_input,
                  <ls_selection>    TYPE lty_stru_list.


   CASE ovs_callback_object->phase_indicator.


     WHEN if_wd_ovs=>co_phase_0.  "configuration phase, may be omitted
*   in this phase you have the possibility to define the texts,
*   if you do not want to use the defaults (DDIC-texts)


       ls_textname = `CARRID`.  "must match a field name of search
       ls_textvalue = `Airline`. "wd_assist->get_text( `001` ).
       INSERT ls_text INTO TABLE lt_label_texts.


       ls_textname = `CARRID`"must match a field in list structure
       ls_textvalue = `Airline`. "wd_assist->get_text( `002` ).
       INSERT ls_text INTO TABLE lt_column_texts.


*      lv_window_title = wd_assist->get_text( `003` ).
*      lv_group_header = wd_assist->get_text( `004` ).
*      lv_table_header = wd_assist->get_text( `005` ).


       ovs_callback_object->set_configuration(
                 label_texts  = lt_label_texts
                 column_texts = lt_column_texts
                 group_header = lv_group_header
                 window_title = lv_window_title
                 table_header = lv_table_header
                 col_count    = 2
                 row_count    = 20 ).




     WHEN if_wd_ovs=>co_phase_1"set search structure and defaults
*   In this phase you can set the structure and default values
*   of the search structure. If this phase is omitted, the search
*   fields will not be displayed, but the selection table is
*   displayed directly.
*   Read values of the original context (not necessary, but you
*   may set these as the defaults). A reference to the context
*   element is available in the callback object.


       ovs_callback_object->context_element->get_static_attributes(
           IMPORTING static_attributes = ls_search_input ).
*     pass the values to the OVS component
       ovs_callback_object->set_input_structure(
           input = ls_search_input ).




     WHEN if_wd_ovs=>co_phase_2.
*   If phase 1 is implemented, use the field input for the
*   selection of the table.
*   If phase 1 is omitted, use values from your own context.


       IF ovs_callback_object->query_parameters IS NOT BOUND.
******** TODO exception handling
       ENDIF.
       ASSIGN ovs_callback_object->query_parameters->*
                               TO <ls_query_params>.
       IF NOT <ls_query_params> IS ASSIGNED.
******** TODO exception handling
       ENDIF.


*     call business logic for a table of possible values
       SELECT carrid FROM sflight INTO TABLE lt_select_list.
       ovs_callback_object->set_output_table( output = lt_select_list ).
 
       IF lt_select_list IS INITIAL.     
*     Open a popup if no entries found 
         lo_api_component  = wd_comp_controller->wd_get_api( ).
         lo_window_manager = lo_api_component->get_window_manager( ).
 
         INSERT `No Entries Found! Do you want to create new entries?` INTO TABLE l_text.
 
         lo_window   = lo_window_manager->create_popup_to_confirm(
                           text = l_text
                           button_kind = if_wd_window=>co_buttons_yesno
                           message_type = if_wd_window=>co_msg_type_question
                           window_position = if_wd_window=>co_center
                            ).
 
*     Get View Controller Reference
         lr_view_controller = wd_this->wd_get_api( ).
 
*     Subscribe to No button Event
         lo_window->subscribe_to_button_event(
               button = if_wd_window=>co_button_no
               action_name = ‘CLOSE_OVS’           ” Create this Action
               action_view = lr_view_controller
               is_default_button = abap_false ).
 
         lo_window->open( ).
 
*     Store OVS Listener instance globally
         wd_this->gr_handle ?= ovs_callback_object.
       ENDIF.


     WHEN if_wd_ovs=>co_phase_3.
*   apply result


       IF ovs_callback_object->selection IS NOT BOUND.
******** TODO exception handling
       ENDIF.


       ASSIGN ovs_callback_object->selection->* TO <ls_selection>.
       IF <ls_selection> IS ASSIGNED.
         ovs_callback_object->context_element->set_attribute(
                                name  = `VAL`   ” Context Attribute Name
                                value = <ls_selection>carrid ).


       ENDIF.
   ENDCASE.


ENDMETHOD.

 

 

다음은 뷰의 액션 탭으로 이동하여 액션 CLOSE_OVS를 만듭니다.

 

/wp-content/uploads/2013/11/2_331180.jpg

 

 

아래 코드를 ONACTIONCLOSE_OVS 메소드에 입력합니다.

 

ONACTIONCLOSE_OVS
METHOD onactionclose_ovs .
* Work around to close the OVS search help window
   wd_this->gr_handle->on_cancel( ).


ENDMETHOD.

 

컴포넌트를 저장하고 활성화 합니다.

 

실행 결과

웹딘프로 어플리케이션을 테스트하겠습니다.

 

입력 필드에서 F4 헬프를 선택합니다.

 

/wp-content/uploads/2013/11/3_331186.jpg

검색 버튼을 누릅니다. ( co_phase_1 이 생략 된 경우 안눌러도 됩니다 ).

 

/wp-content/uploads/2013/11/4_331193.jpg

 

만약 검색 결과가 없다면 팝업이 열린 것을 볼 수 있습니다!

/wp-content/uploads/2013/11/5_331194.jpg

( 테스트로 팝업을 보기 위해 디버거로 테이블을 비웠습니다 ).

 

No 버튼에 대해서만 OVS를 닫는 이벤트 처리를 해두었습니다. No 를 클릭하면 OVS 윈도우도 자동으로 닫히는 것을 볼 수 있습니다.

 

/wp-content/uploads/2013/11/6_331195.jpg

 

 

 

결론

 

이번 데모에서는 No 버튼만 OVS를 닫는 이벤트 처리를 했지만, 비슷하게 Yes 버튼에도 신규 항목을 작성하는 화면으로 이동하도록 이벤트 처리를 할 수 있습니다. 이글이 비슷한 문제로 어려움을 겪는 분들에게 도움이 되었으면 좋겠습니다.   

 

 

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://blogs.sap.com/2013/11/25/how-to-close-ovs-popup-window/

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://blogs.sap.com/2013/12/18/how-to-check-supported-web-browser-version/

 

How to check supported web browser version

December 18, 2013 

 

최근까지도 내가(SAP직원으로) 지원 나가는 로컬 고객들에게서 가장 많이 듣는 질문중 하나는 "우리 서버의 웹딘프로아밥 / BSP는 인터넷 익스플로러 버전 몇까지 지원되나요? 파이어폭스, 크롬도 지원되지요?" 입니다.

그 질문에 대한 답을 기록으로 남기기 위해 여기에 적어 둡니다.

 

 

1. 홈페이지 http://service.sap.com 에 접속합니다. "Products" -> "Product availability" 로 이동합니다.

/wp-content/uploads/2013/12/clipboard1_346203.png

(번역자 의견: 구글에서 Product Availability Matrix를 검색하는게 더 편합니다)


 

2. Product Availability Matrix 페이지가 열립니다. 우리 서버의 서버 버전을 선택합니다. 예를들어 SAP NETWEAVER 7.4 를 선택합니다.

/wp-content/uploads/2013/12/clipboard2_346204.png

 

3. "Technical Release Information"->"Web Browser Platforms" 탭을 선택합니다. 웹딘프로 아밥과 BSP의 웹브라우저 호환성을 확인하고 싶다면 Product Instnce에서 "Application Server ABAP"을 선택합니다. 필터에서는 파이어폭스, 크롬, IE 를 선택할 수 있습니다.

/wp-content/uploads/2013/12/clipboard3_346211.png

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://blogs.sap.com/2013/12/18/how-to-check-supported-web-browser-version/

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://blogs.sap.com/2013/12/30/how-to-validate-the-fields-on-ovs-window-webdynpro-abap/

 

How to validate the fields on OVS window – Webdynpro ABAP

December 30, 2013 

 

목표:

 

OVS 화면에서 어트리뷰트(필드 강조) 에러 메시지 출력하기.

 

시나리오:

 

이 글에서는 OVS 창에 있는 필드에 대해 값 점검을 하고 에러 메시지를 출력하는 방법을 설명합니다.

 

  • 스탠다드/T100 메시지 출력하기
    • 스탠다드/T100 메시지를 출력하는 방법은 인터페이스 IF_WD_OVS의 메소드 SET_MESSAGES를 사용하면 됩니다.
    • 또는 인터페이스 IF_WD_MESSAGE_MANAGER의 여러 메소드를 사용할 수도 있습니다.

 

  • 어트리뷰트(필드 강조) 에러 메시지 출력하기
    • 컴포넌트 재사용에 접근하여 OVS 컴포넌트의 컨텍스트 엘리먼트를 가져와야 합니다.
    • 어트리뷰트 에러 메시지를 출력하는 방법은 인터페이스 IF_WD_MESSAGE_MANAGER의 메소드 REPORT_ATTRIBUTE_ERROR_MESSAGE를 사용하면 됩니다.

 

          주요 로직: Getti컴포넌트 WDR_OVS의 컨텍스트 노드 "INPUT"에 대한 커텍스트 엘리먼트 참조변수를 가져오는 로직입니다.

 

        DATA lo_ovs             TYPE REF TO iwci_wdr_ovs. 
        DATA lo_context         TYPE REF TO if_wd_context. 
        DATA lo_context_node    TYPE REF TO if_wd_context_node. 
        DATA lo_el              TYPE REF TO if_wd_context_element. 
       " get reference of ovs component usage 
       lo_ovs = wd_this->wd_cpifc_test_ovs( ). 
       " get the context of ovs component 
        lo_context = lo_ovs->wd_get_api( )->get_context( ). 
       " get input node reference 
        lo_context_node = lo_context->root_node->get_child_node( ‘INPUT’). 
       " get reference to the context element by using lead index 
        lo_el = lo_context_node->get_element( ).

 

준비물:

 

Webdynpro ABAP 기본지식, OVS concept & OO ABAP

 

단계별 진행:

 

예제로 간단한 웹딘프로 어플리케이션을 하나 만들어 보겠습니다. 인풋필드 2개 CARRID & CARRNAME 을 만듭니다. 필드 CARRID에는 OVS 헬프를 붙여줍니다.

 

Step 1:

 

웹딘프로아밥 컴포넌트를 아래 그림처럼 만듭니다.

1.PNG

Step 2:

 

컴포넌트 WDR_OVS를 컴포넌트 재사용으로 등록합니다.

 

/wp-content/uploads/2013/12/2_352512.png

 

Step 3:

 

컴포넌트 재사용 TEST_OVS를 뷰 V_MAIN에 등록합니다.

 

2_1.PNG

Step 4:

 

컨텍스트 노드 SCARR를 만들고 어트리뷰트 CARRID 와 CARRNAME 을 추가합니다. 어트리뷰트 CARRID 에는 ovs를 지정합니다.

 

3.PNG

Step 5:

 

뷰 레이아웃에서 노드 SCARR에 대한 입력 필드를 2개 만듭니다.

 

4.PNG

Step 6:

 

이벤트 핸들러 ON_OVS를 만듭니다.

5.PNG

 

아래 코드를 ON_OVS에 입력합니다.

 

METHOD on_ovs .
TYPES:
    BEGIN OF lty_stru_input,
      carrid TYPE scarr-carrid,
    END OF lty_stru_input.
TYPES:
    BEGIN OF lty_stru_output,
      carrid TYPE scarr-carrid,
      carrname   TYPE scarr-carrname,
    END OF lty_stru_output.
DATA: ls_search_input  TYPE lty_stru_input,
        lt_select_list   TYPE STANDARD TABLE OF lty_stru_output,
        ls_text          TYPE wdr_name_value,
        lt_label_texts   TYPE wdr_name_value_list,
        lt_column_texts  TYPE wdr_name_value_list,
        lv_window_title  TYPE string,
        lv_table_header  TYPE string.
FIELD-SYMBOLS: <ls_query_params> TYPE lty_stru_input,
                 <ls_selection>    TYPE lty_stru_output.
CASE ovs_callback_object->phase_indicator.
   WHEN if_wd_ovs=>co_phase_0.  "configuration phase, may be omitted
     ls_text-name = 'CARRNAME'.  "must match a field name of search
      ls_text-value = 'Airline Name'. "wd_assist->get_text( '001' ).
      INSERT ls_text INTO TABLE lt_label_texts.
      INSERT ls_text INTO TABLE lt_column_texts.
     ovs_callback_object->set_configuration(
                label_texts  = lt_label_texts
                column_texts = lt_column_texts
                window_title = lv_window_title
                table_header = lv_table_header ).
   WHEN if_wd_ovs=>co_phase_1.  "set search structure and defaults
     ovs_callback_object->context_element->get_static_attributes(
          IMPORTING static_attributes = ls_search_input ).
     "pass the values to the OVS component
      ovs_callback_object->set_input_structure(
          input = ls_search_input ).
    WHEN if_wd_ovs=>co_phase_2.
      IF ovs_callback_object->query_parameters IS NOT BOUND.
******** TODO exception handling
      ENDIF.
      ASSIGN ovs_callback_object->query_parameters->*
                              TO <ls_query_params>.
      IF NOT <ls_query_params> IS ASSIGNED.
******** TODO exception handling
      ENDIF.
     "==========================================
      " Report query parameter table
      "==========================================
      DATA ls_so_carrid TYPE selopt.
      DATA lt_so_carrid TYPE TABLE OF selopt.
     CLEAR ls_so_carrid.
      CLEAR lt_so_carrid.
   IF <ls_query_params>-carrid IS NOT INITIAL.
        ls_so_carrid-sign = 'I'.
        ls_so_carrid-option = 'EQ'.
        ls_so_carrid-low = <ls_query_params>-carrid.
        FIND '*' IN ls_so_carrid-low.
        IF sy-subrc IS INITIAL .
          ls_so_carrid-option = 'CP'.
        ENDIF.
        APPEND ls_so_carrid TO lt_so_carrid.
      ENDIF.
     "=================================================
      "Note: Do not query database directy inside view, instead
      " call a method/function module to get data
      " call business logic for a table of possible values
      "=================================================
      SELECT carrid
             carrname
        FROM scarr
        INTO TABLE lt_select_list
        WHERE carrid IN lt_so_carrid.
      IF lt_select_list[] IS INITIAL.
       "==========================================
        " Report attribute error message here
        "==========================================
        DATA lo_ovs             TYPE REF TO iwci_wdr_ovs.
        DATA lo_context         TYPE REF TO if_wd_context.
        DATA lo_context_node    TYPE REF TO if_wd_context_node.
        DATA lo_el              TYPE REF TO if_wd_context_element.
        DATA lo_ovs_listener    TYPE REF TO if_wdr_ovs_listener.
        DATA lo_message_manager TYPE REF TO if_wd_message_manager.
       " get reference of ovs component usage
        lo_ovs = wd_this->wd_cpifc_test_ovs( ).
       " get the context of ovs component
        lo_context = lo_ovs->wd_get_api( )->get_context( ).
       " get input node reference
        lo_context_node = lo_context->root_node->get_child_node( 'INPUT').
       " get reference to the context element by using lead index
        lo_el = lo_context_node->get_element( ).
       " get reference to message manager
        lo_message_manager = wd_this->wd_get_api( )->get_message_manager( ).
*         report message
        CALL METHOD lo_message_manager->report_attribute_error_message
          EXPORTING
            message_text   = 'Invalid entry - ( Attribute error message )'
            element        = lo_el
            attribute_name = 'CARRID'.  " Attribute Name
       "==========================================
        " Report standard error message here
        "==========================================
        DATA lt_messages TYPE if_wd_ovs=>ty_t_messages.
        DATA ls_messages LIKE LINE OF lt_messages.
       CLEAR ls_messages.
        CLEAR lt_messages.
       ls_messages-standard_message-text = 'Invalid entry ( Standard message )' .
        ls_messages-standard_message-type = if_wd_message_manager=>co_type_error.
        APPEND ls_messages TO lt_messages.
       ovs_callback_object->set_messages( messages = lt_messages ).
      ENDIF.
      ovs_callback_object->set_output_table( output = lt_select_list ).
   WHEN if_wd_ovs=>co_phase_3.
*   apply result
      IF ovs_callback_object->selection IS NOT BOUND.
******** TODO exception handling
      ENDIF.
      ASSIGN ovs_callback_object->selection->* TO <ls_selection>.
      IF <ls_selection> IS ASSIGNED.
        ovs_callback_object->context_element->set_static_attributes(
                               static_attributes = <ls_selection> ).
      ENDIF.
  ENDCASE.
ENDMETHOD.

저장하고 활성화 합니다.

 

 

Step 7:

 

웹딘프로 어플리케이션을 만듭니다.

6.PNG

 

실행 결과: (최초 OVS 모습)

O1.PNG

실행 결과: (검색 결과)

o2.PNG

 

실행 결과: (CARRID 필드에 에러 발생)

o3.PNG

 

이 글이 OVS 입력 필드 점검 메시지 처리에 도움이 되시길 바랍니다.

 

댓글 언제나 환영합니다.

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://blogs.sap.com/2013/12/30/how-to-validate-the-fields-on-ovs-window-webdynpro-abap/

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://blogs.sap.com/2014/03/10/custom-timeout-page-for-web-dynpro-applications/

Custom timeout page for Web Dynpro applications

March 10, 2014 

 

 

     사용자들은 가끔 여러창에 웹딘프로 어플리케이션 여러개를 열어둘 떄가 있습니다. 일정시간(BC 설정에 따라 다름)이 흐른후 세션이 자동으로 닫힙니다. 그러면 어플리케이션 서버(Web AS)는 다임아웃 결과를 보여줍니다. 사용자 입장에서는 이런 동작이 혼란스러울 수 있습니다.


요구사항:

     세션 타임아웃 페이지를 만들고 싶습니다. 원래 스탠다드 페이지는 이렇습니다:


     대신 아래처럼 커스텀(회사 고유의) 페이지를 만들고 싶습니다. 여기에는 F5(새로고침) 기능과 아주 큰 "새로고침" 버튼을 넣고 싶습니다:

/wp-content/uploads/2014/03/timeout_406882.png

     티코드 SICF에서 덤프날때와 세션 타임아웃에 대한 에러 처리를 application errors탭에서 지정할 수 있습니다:

/wp-content/uploads/2014/03/sicf_406884.png

     만약 explicit response page를 선택한다면 모든 종류의 어플리케이션 에러에 대해서 동작하는 에러 처리 페이지를 만들게 됩니다. 하지만 지금 원하는 것은 약간 다릅니다. 다른 에러는 아니고 오직 타임아웃에 대해서만 커스텀 페이지를 만들고 싶습니다.

     explicit page는 HTML+CSS로 만들 수 있습니다. 그러나 가장 불편한 점은 자바스크립트를 쓸 수 없다는 것입니다. 즉, 에러 타입을 검사하여 각자 다른 에러 페이지를 보여주도록 만들 수 가 없습니다.

  

해결방법:

     리다이렉트나 시스템 태그 <%=MESSAGE%> 등 여러가지 시행착오 끝에 아주 간단한 해결방법을 찾았습니다. (오컴의 면도날: "같은 현상을 설명하는 두 개의 주장이 있다면, 간단한 쪽을 선택하라"):

     1. 에러 페이지를 .html로 만듭니다. (Notepad++ 등의 프로그램을 사용, 시스템에 기록을 남기고 싶다면 BSP로 저장하는것도 좋습니다).

BSP.png

     2. 티코드 SOTR_EDIT에서 OTR 롱 텍스트를 만들고 앞서 만든 파일내용을 복사하여 붙여넣기 합니다. (이 OTR이 실제 explicit page로 보여질 내용입니다)

 

     3. 스탠다드 클래스 CL_WDR_CLIENT_ABSTRACT_HTTP의 메소드 PREPROCESS_REQUEST를 수정해야 합니다. (이 작업은 enhancement로 할 수 없고 반드시 modify해야 합니다.)

/wp-content/uploads/2014/03/wdr_406888.png

     여기에 직접 코드를 나열하기 보다는 다른 클래스에 코드를 넣고 메소드를 호출하도록 구현하였습니다. 또한 모든 어플리케이션의 타임아웃 페이지에 사용하고자 하는것이 안니라 특정 어플리케이션만 지정하여 적용할 것입니다. 특정 어플리케이션만 지정하기 위해서 테이블을 하나 만들어서 거기에 웹딘프로아밥 어플리케이션 아이디와 사용여부 플래그를 저장했습니다.

 

method handle.

  data:
    lr_server    type ref to cl_http_server,
    lt_path      type string_table,
    ls_appl      type ytpf_t_appl_list,                       "#EC NEEDED
    ls_page      type icf_response_page,
    lv_index     type i,
    lv_service  type string.

lr_server ?= ir_server.
  if lr_server is bound.

     "cl_wdr_task=>application->name can NOT be used here, as the instance is already destroyed…
    split lr_server->m_runtime_memory_id at '/' into table lt_path[].

    if not lt_path[] is initial.
      describe table lt_path[] lines lv_index.
      read table lt_path[] into lv_service index lv_index. refresh lt_path[].

      if sy–subrc is initial.
        translate lv_service to upper case.

        select single service_name active
                             from ytpf_t_appl_list
                             into corresponding fields of ls_appl
                             where service_name eq lv_service
                                 and active       eq abap_true.

        if sy–subrc is initial.
          ls_page–body = '2C768A4E40741EE3A7A55C5708059340' "SOTR automatically generated GUID

          ir_server->set_page(
            exporting
              response_page_type   = ir_server->co_page_error_type
              response_option_page = ls_page
            exceptions
              invalid_parameter    = 1
              document_not_found   = 2
              others               = 3 ).

        endif.
      endif.
    endif.
  endif.

endmethod.

 

실행중에 어플리케이션 에러 타입이 세션 타임아웃인 경우 explicit page가 OTR 롱 텍스트에 저장해둔 커스텀 페이지로 바뀌어 보여집니다.

이방법은 IE 와 NWBC 모두 동작합니다.

 

오래전 부터 관련 논쟁이 게시판에 있었습니다. 참고: Custom timeout page in SICF

 

감사합니다. 댓글 환영합니다!

 

Tudor

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://blogs.sap.com/2014/03/10/custom-timeout-page-for-web-dynpro-applications/

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://blogs.sap.com/2014/03/12/providing-explicite-page-up-and-page-down-functionallity-for-table-in-webdynpro-abap/

Providing explicite page up and page down functionallity for Table in Webdynpro ABAP

March 12, 2014 | 8 Views |

 

요약:
테이블 엘리먼트의 속성 firstVisibleRow를 활용하면 명시적 페이지 표시가 가능합니다.

 

단계별 구현:

1. 메인 뷰의 컨텍스트에서 어트리뷰트 PAGE_NO를 I 타입으로 만듭니다.

/wp-content/uploads/2014/03/hai1_408652.png

2. 테이블의 속성 firstVisibleRow에 컨텍스트 어트리뷰트 PAGE_NO를 바인딩 합니다.

 

/wp-content/uploads/2014/03/hai2_408651.png

3. 아래 코드를 WDDOINIT()에 입력합니다.

 

method WDDOINIT.

DATA lo_nd_vbak

TYPE REF TO if_wd_context_node.

data lv_no_of_records type i. "to count no of records in internal table

TYPES :

BEGIN OF type_vbak,
vbeln type vbak-vbeln,
erdat type vbak-erdat,
erzet type vbak-erzet,

checkbox(1) type c,

END OF type_vbak.

data lt_vbak type TABLE OF type_vbak.

* navigate from <CONTEXT> to <VBAK> via lead selection
lo_nd_vbak = wd_context->get_child_node( name = 'VBAK' ).

SELECT vbeln erdat erzet from vbak INTO CORRESPONDING FIELDS OF TABLE lt_vbak UP TO 18 ROWS.if sy-subrc = 0.
no_of_records = sy-dbcnt.
ENDIF.

lo_nd_vbak->bind_table( lt_vbak ).

DATA lo_el_context TYPE REF TO if_wd_context_element.
DATA ls_context TYPE wd_this->element_context.
* get element via lead selection
lo_el_context = wd_context->get_element(  ).
* get single attribute
CALL METHOD LO_EL_CONTEXT->SET_ATTRIBUTE
EXPORTING
VALUE  = lv_no_of_records
NAME   = 'NO_OF_RECORDS'
.
endmethod.

 


4. 버튼 Page Up 과 Page Down 2개를 만듭니다. 두곳 모두에 액션 이벤트에 BUTTON_EVENT를 등록합니다.

/wp-content/uploads/2014/03/hai3_408662.png

5. 아래 코드를 ONACTIONBUTTON_EVENT( )에 입력합니다.

 

 

method ONACTIONBUTTON_ACTION .

data element_id type string.CALL METHOD WDEVENT->GET_STRING
EXPORTING
NAME   = 'ID'
RECEIVING
VALUE  = element_id.

DATA lo_el_context TYPE REF TO if_wd_context_element.
DATA ls_context TYPE wd_this->element_context.
DATA lv_page_no LIKE ls_context-page_no.
data lv_no_of_records LIKE ls_context-no_of_records.
* get element via lead selection
lo_el_context = wd_context->get_element(  ).
* get single attribute
lo_el_context->get_attribute(
EXPORTING
name =  `PAGE_NO`
IMPORTING
value = lv_page_no ).
* get single attribute
lo_el_context->get_attribute(
EXPORTING
name =  `NO_OF_RECORDS`
IMPORTING
value = lv_no_of_records ).

case element_id.

when 'PAGE_UP'.
if lv_page_no <= 0.

exit.

else.

lv_page_no = lv_page_no – 5.

endif.

WHEN 'PAGE_DOWN'.

if lv_page_no >= lv_no_of_records.
exit.

else.

lv_page_no = lv_page_no + 5 . "5 is default size of the table element
ENDIF.
ENDCASE.

CALL METHOD lo_el_context->set_attribute
EXPORTING
value  = lv_page_no
name   = 'PAGE_NO'
.

endmethod.

 


6. 활성화 하고 어플리케이션을 만들어서 테스트 합니다.

 

/wp-content/uploads/2014/03/hai4_408663.png

 

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://blogs.sap.com/2014/03/12/providing-explicite-page-up-and-page-down-functionallity-for-table-in-webdynpro-abap/

+ Recent posts