아우 씨* 이건 멍미!! 아래 그림의 웹딘프로아밥 뷰 레이아웃을 본 나의 첫 한마디 입니다.
실행 결과는 이렇습니다:
그날은 내가 처음으로 우리 멋진 팀장님으로 부터 동적 UI 생성에 대해서 전해들었습니다. 이런 이야기 입니다.
웹딘프로아밥에는 각 UI 엘리먼트 마다 클래스(예: CL_WD_CHECKBOX , CL_WD_CHECKBOX_GROUP, CL_WD_INPUT_FIELD 등)가 하나씩 있습니다. 이 클래스를 이용하면 뷰의 WDDOMODIFYVIEW 메소드에서 UI 엘리먼트를 뷰에 추가 할 수 있습니다.
간단한 예제로 뷰에 트레이 UI 엘리먼트를 만들어 보겠습니다.
예제 1:
뷰에 트레이 UI 엘리먼트 만들기.
정답:
티코드 SE80에서 웹딘프로아밥 컴포넌트를 하나 만듭니다. MAIN 뷰에 transparent container 아이디 TC_MAIN을 만들고 flow 레이아웃으로 지정합니다. ( 이렇게 transparent container를 만드는게 필수는 아니지만 transparent container가 있으면 나중에 뷰를 조정할때 도움이 됩니다. 그러므로 transparent container를 만들기를 추천합니다)
모든 동적 생성 UI 엘리먼트는 이 transparent container에 배치할 것입니다.
아래 소스코드를 뷰의 WDDOMODIFYVIEW 메소드에 입력하면 트레이 UI 엘리먼트가 준비됩니다.
method WDDOMODIFYVIEW .
"Let's Create Tray
data : lr_tray type REF TO cl_wd_tray.
data : lr_caption TYPE REF TO cl_wd_caption.
DATA : lr_container TYPE REF TO cl_wd_uielement_container.
data : lr_flow type ref to cl_wd_flow_data.
data : lr_matrix_layout type REF TO cl_wd_matrix_layout.
"As we are gonna put the tray in TC_MAIN ( the transperant container )
"fetch it ...
lr_container ?= view->get_element( 'TC_MAIN' ).
"Create a Tray Object
CALL METHOD CL_WD_TRAY=>NEW_TRAY
EXPORTING
ID = 'TR_TRAY'
WIDTH = '100%'
RECEIVING
CONTROL = lr_tray.
"Need to Assign the flow layout information for this Tray
"As it is part if ROOTUIELEMENTCONTAINER ( with layout flow )
lr_flow = cl_wd_flow_data=>new_flow_data( lr_tray ).
lr_tray->set_layout_data( lr_flow ).
"" add tray to container
CALL METHOD lr_container->add_child
EXPORTING
the_child = lr_tray.
"' set layout of tray
CALL METHOD cl_wd_matrix_layout=>new_matrix_layout
EXPORTING
container = lr_tray
RECEIVING
control = lr_matrix_layout.
CALL METHOD cl_wd_caption=>new_caption
EXPORTING
id = 'CA_TRAY'
text = 'Yahoo... Here is my Tray (*_*)'
RECEIVING
control = lr_caption.
"' set header for tray
CALL METHOD lr_tray->set_header
EXPORTING
the_header = lr_caption.
endmethod.
저장하고 활성화하고 실행합니다.
예제 2:
트레이 안에 input field 와 label 그리고 button을 추가합니다.
정답:
input field 의 Value 속성은 반드시 컨텍스트의 어트리뷰트가 바인딩 되어야 합니다. 그러므로 컨택스트 노드/어트리뷰트를 먼저 만들어야 합니다.
컴포넌트 컨트롤러에 RET_CC_CONTEXT 메소드를 만듭니다.
Exporting parameter : ER_CONTEXT type ref to IF_WD_CONTEXT_NODE.
아래 소스 코드를 WDDOMODIFYVIEW 메소드에 입력하고 다시 실행해보세요. 만약 활성화할때 에러가 발생한다면 에러 메시지를 보고 스스로 해결하도록 합니다.
method WDDOMODIFYVIEW .
"Let's Create Tray
data : lr_tray type REF TO cl_wd_tray.
data : lr_caption TYPE REF TO cl_wd_caption.
DATA : lr_container TYPE REF TO cl_wd_uielement_container.
data : lr_flow type ref to cl_wd_flow_data.
data : lr_matrix_layout type REF TO cl_wd_matrix_layout.
"As we are gonna put the tray in TC_MAIN ( the transperant container )
"fetch it ...
lr_container ?= view->get_element( 'TC_MAIN' ).
"Create a Tray Object
CALL METHOD CL_WD_TRAY=>NEW_TRAY
EXPORTING
ID = 'TR_TRAY'
WIDTH = '100%'
RECEIVING
CONTROL = lr_tray.
"Need to Assign the flow layout information for this Tray
"As it is part if ROOTUIELEMENTCONTAINER ( with layout flow )
lr_flow = cl_wd_flow_data=>new_flow_data( lr_tray ).
lr_tray->set_layout_data( lr_flow ).
"" add tray to container
CALL METHOD lr_container->add_child
EXPORTING
the_child = lr_tray.
"' set layout of tray
CALL METHOD cl_wd_matrix_layout=>new_matrix_layout
EXPORTING
container = lr_tray
RECEIVING
control = lr_matrix_layout.
CALL METHOD cl_wd_caption=>new_caption
EXPORTING
id = 'CA_TRAY'
text = 'Yahoo... Here is my Tray (*_*)'
RECEIVING
control = lr_caption.
"' set header for tray
CALL METHOD lr_tray->set_header
EXPORTING
the_header = lr_caption.
"****************Create Input field ********************************
"create Node And Element for input field
"Part 1: stracture creation : with one field called name
TYPE-POOLS: abap.
DATA :
lt_components TYPE abap_component_tab,
lw_component TYPE LINE OF abap_component_tab,
lr_structdescr type ref to CL_ABAP_STRUCTDESCR,
lt_attribs TYPE wdr_context_attr_info_map,
ls_attribs like LINE OF lt_attribs.
lw_component-name = 'NAME'.
TRY.
lw_component-type = cl_abap_elemdescr=>get_c( p_length = 20 ).
CATCH cx_sy_move_cast_error .
ENDTRY.
append lw_component to lt_components.
lr_structdescr = cl_abap_structdescr=>create( lt_components ).
"Part2 : Now Create a Node based on this Dynamic struct.
DATA:
lo_parent_node_info TYPE REF TO if_wd_context_node_info,
lo_child_node_info TYPE REF TO if_wd_context_node_info,
* lo_nd_gen_tab TYPE REF TO if_wd_context_node,
lt_child_node_map TYPE wdr_context_child_info_map,
comp_context type ref to if_wd_context_node.
FIELD-SYMBOLS : <fs_stru> TYPE any .
* DATA dy_stru TYPE REF TO data.
wd_comp_controller->ret_cc_context(
IMPORTING
er_context = comp_context ).
lo_parent_node_info = comp_context->get_node_info( ).
lt_child_node_map = lo_parent_node_info->get_child_nodes( ).
READ TABLE lt_child_node_map TRANSPORTING NO FIELDS WITH TABLE KEY name = 'ND_DETAIL'.
IF sy-subrc = 0.
" REMOVE_CHILD_NODE
lo_parent_node_info->remove_child_node( 'ND_DETAIL' ).
ENDIF.
"" get attrib property
LS_ATTRIBS-name = 'NAME'.
insert ls_attribs into table lt_attribs.
" create Node in Comp Controller
CALL METHOD lo_parent_node_info->add_new_child_node
EXPORTING
name = 'ND_DETAIL'
is_singleton = abap_true
static_element_rtti = lr_structdescr
is_static = abap_true
attributes = lt_attribs
RECEIVING
child_node_info = lo_child_node_info.
DATA lr_wa TYPE REF TO data.
data lo_child_node_detail TYPE ref to if_wd_context_node.
FIELD-SYMBOLS <lfs_dyn> TYPE any.
CREATE DATA lr_wa TYPE HANDLE lr_structdescr.
ASSIGN lr_wa->* TO <lfs_dyn>.
lo_child_node_detail = comp_context->get_child_node( name = 'ND_DETAIL' ).
lo_child_node_detail->bind_structure( EXPORTING new_item = <lfs_dyn> ).
" Map that component controller node to View
DATA: lo_node_info TYPE REF TO if_wd_context_node_info,
lo_node TYPE REF TO if_wd_context_node,
mapping_info TYPE wdr_context_mapping_info,
lv_name TYPE string,
lt_path TYPE wdr_ctx_element_path_segments.
DATA map_path TYPE string.
CLEAR lt_path.
""
DATA:
lr_child_node_info_view TYPE REF TO if_wd_context_node_info,
lt_child_node_map_view TYPE wdr_context_child_info_map.
lo_node_info = WD_CONTEXT->get_node_info( ).
lv_name = 'ND_DETAIL'.
lt_child_node_map_view = lo_node_info->get_child_nodes( ).
READ TABLE lt_child_node_map TRANSPORTING NO FIELDS WITH TABLE KEY name = 'ND_DETAIL'.
IF sy-subrc = 0.
" REMOVE_CHILD_NODE
lo_node = wd_context->get_child_node( name = 'ND_DETAIL' ).
lr_child_node_info_view = lo_node->get_node_info( ).
RETURN.
ELSE.
ENDIF.
CONCATENATE 'COMPONENTCONTROLLER.' lv_name INTO map_path.
APPEND map_path TO lt_path.
mapping_info-controller = 'COMPONENTCONTROLLER'. "conponent name
mapping_info-path = lt_path. "Controller context node name
"" create view node refering component node
CALL METHOD lo_node_info->add_new_mapped_child_node
EXPORTING
child_name = lv_name
mapping_info = mapping_info
is_static = abap_true
RECEIVING
child_node_info = lr_child_node_info_view.
"Now Let's Create An input field along with the label and put it in Try
"Bind the inout field with the Name element of ND_DETAIL Node we created
DATA lr_input TYPE REF TO cl_wd_input_field..
DATA lr_matrix_data TYPE REF TO cl_wd_matrix_data.
DATA lr_matrix TYPE REF TO cl_wd_matrix_head_data.
DATA lv_lbl_id TYPE string.
DATA lv_lbl_txt TYPE string.
DATA lv_lbl_for TYPE string.
DATA lr_label TYPE REF TO cl_wd_label.
DATA inp_id TYPE string.
DATA lv_width TYPE string.
CLEAR : inp_id , lv_width.
CALL METHOD cl_wd_input_field=>new_input_field
EXPORTING
bind_value = 'ND_DETAIL.ND_DETAIL.NAME'
id = 'IF_NAME'
input_prompt = 'Enter Name'
RECEIVING
control = lr_input.
"" create lbl for Input field
CALL METHOD cl_wd_label=>new_label
EXPORTING
id = 'LBL_NAME'
label_for = 'IF_NAME'
text = 'Name'
RECEIVING
control = lr_label. " CONTROL
lr_matrix = cl_wd_matrix_head_data=>new_matrix_head_data( lr_label ).
lr_label->set_layout_data( lr_matrix ).
lr_matrix_data = cl_wd_matrix_data=>new_matrix_data( lr_input ).
lr_input->set_layout_data( lr_matrix_data ).
"Let's Add this couple to the Try
"' get tray as container
lr_container ?= view->get_element( 'TR_TRAY' ).
"" add label and Input field to Tray
CALL METHOD lr_container->add_child
EXPORTING
the_child = lr_label.
CALL METHOD lr_container->add_child
EXPORTING
the_child = lr_input.
"Now let's Create a button and add it to Tray
data : lr_button type REF TO cl_wd_button.
CALL METHOD CL_WD_BUTTON=>NEW_BUTTON
EXPORTING
IMAGE_SOURCE = '~Icon/Search'
on_action = 'PROCESS_EVENT'
ID = 'BTN_SEARCH'
TEXT = 'Sumit'
RECEIVING
CONTROL = lr_button.
"as we want this button to come on new line make it matrix head data
lr_matrix = cl_wd_matrix_head_data=>new_matrix_head_data( lr_button ).
lr_button->set_layout_data( lr_matrix ).
"" add Button to Tray
CALL METHOD lr_container->add_child
EXPORTING
the_child = lr_button.
endmethod.
저장하고 활성화하고 실행합니다.
덕후들을 위한 추가…
예제 3:
SEARCH 버튼을 누르면 팝업화면에 입력한 이름을 표시합니다.
힌트: Search 버튼에 바인딩된 액션 메소드 ONACTIONPROCESS_EVENT 를 구현해야 합니다.
하다가 문제가 있으면 댓글로 질문주세요 ..
해피 코딩….