Создадим в CRM окно следующего вида:
Часть информации рассматривалась ранее. И будет опущена, чтобы не дублировать.
- В транзакции BSP_WD_CMPWB создадим новое приложение;
2. Экран будет состоять из двух подэкранов. Создаем первый с именем FirstPart с обычными полем Bla-bla. Действуем вот так:
3. Создаем view TablePart с таблицей. Порядок действий идентичный прошлому. Набор полей можно выбрать как из структуры, так и указать самостоятельно. В моем случае будет выбрано из структуры.
4. Создаем вариант отображения View с таблицей. Редактор экранов имеет чуть другой вид, но не критично. В целом все похоже на обычный
5. Создание набора ракурсов для объединения двух View:
6. Переходим на вкладку "Редактор динамического репозитария" и добавляем ракурсы во ViewSets.
7.Добавляем ракурс
8. Для возможности навигации добавляем ракурс интерфейса.
9. Т.к. в данном случае у нас окно, добавляем кнопку выхода. Ее можно добавить на любой View(точнее, какие либо другие кнопки имеет смысл располагать на нужных View). В текущем случае кнопка нужна в самом низу, поэтому нарисуем ее на MainView
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<%@page language="abap" %> <%@extension name="thtmlb" prefix="thtmlb" %> <%@extension name="chtmlb" prefix="chtmlb" %> <%@extension name="bsp" prefix="bsp" %> <thtmlb:grid cellSpacing = "1" columnSize = "1" height = "100%" rowSize = "2" width = "100%" > <thtmlb:gridCell colSpan = "1" columnIndex = "1" rowIndex = "1" rowSpan = "1" > <bsp:call comp_id = "<%= controller->GET_VIEWAREA_CONTENT_ID( 'FirstPart' ) %>" url = "<%= controller->GET_VIEWAREA_CONTENT_URL( 'FirstPart' ) %>" /> </thtmlb:gridCell> <thtmlb:gridCell colSpan = "1" columnIndex = "1" rowIndex = "2" rowSpan = "1" > <bsp:call comp_id = "<%= controller->GET_VIEWAREA_CONTENT_ID( 'TablePart' ) %>" url = "<%= controller->GET_VIEWAREA_CONTENT_URL( 'TablePart' ) %>" /> </thtmlb:gridCell> </thtmlb:grid> </br></br></br></br> <thtmlb:grid cellSpacing = "1" columnSize = "8" height = "30%" rowSize = "6" width = "100%" > <thtmlb:gridCell colSpan = "8" columnIndex = "1" horizontalAlignment = "LEFT" rowIndex = "1" > <thtmlb:button id = "CANCEL" onClientClick = "Javascript: window.close() ;" onClick = "CANCEL" text = "Выход" /> </thtmlb:gridCell> </thtmlb:grid> |
10. Обрабатываем событие Cancel кнопки и переопределяем Plug выхода окна.
Окно готово. Осталось заполнить данными.
Заполнение таблицы при запуске можно сделать в методе.
11. Таблицу можно заполнить в методе DO_PREPARE_OUTPUT. Если требуется не просто отображение данных, а будут происходить какие либо действия в таблице, например, нажатие чекбокса. Следует предусмотреть переменную, запрещающую заново установить начальные данные, переписав измененные.
Как один из вариантов завести переменную, указывающую, что данный метод вызывается в первый раз.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
METHOD do_prepare_output. DATA:lr_table TYPE REF TO zsb_test_struct, lr_struct TYPE zsb_test_struct, lt_tabledata TYPE TABLE OF zsb_test_struct, lr_valuenode TYPE REF TO cl_bsp_wd_value_node, lr_col TYPE REF TO cl_crm_bol_bo_col. IF gv_first_show = abap_true. gv_first_show = abap_false. lt_tabledata = VALUE #( ( zz_id = '1' zz_field1 = 'SomeInfo' zz_field2 = 'SomeInfo' zz_field3 = 'SomeInfo ') ( zz_id = '2' zz_field1 = 'SomeInfo' zz_field2 = 'SomeInfo' zz_field3 = 'SomeInfo ') ( zz_id = '3' zz_field1 = 'SomeInfo' zz_field2 = 'SomeInfo' zz_field3 = 'SomeInfo ') ( zz_id = '4' zz_field1 = 'SomeInfo' zz_field2 = 'SomeInfo' zz_field3 = 'SomeInfo ') ). "create collection object. CREATE OBJECT lr_col. CREATE DATA lr_table. LOOP AT lt_tabledata INTO DATA(ls_tabledata). CREATE OBJECT lr_valuenode EXPORTING iv_data_ref = lr_table. "set the data into the value node. lr_valuenode->if_bol_bo_property_access~set_properties( is_attributes = ls_tabledata ). "add node to the collection. lr_col->if_bol_bo_col~add( lr_valuenode ). ENDLOOP. me->typed_context->nodet->collection_wrapper->set_collection( lr_col ). ENDIF. ENDMETHOD. |
Получили вот такое окно с данными
Создание возможности вставки\удаления\редактирования строк в таблице.
Создаем атрибут для хранения кнопок
2. Добавляем заполнение этой таблицы кнопками в методе DO_PREPARE_OUTPUT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
METHOD do_prepare_output. DATA:lr_table TYPE REF TO zsb_test_struct, lr_struct TYPE zsb_test_struct, lt_tabledata TYPE TABLE OF zsb_test_struct, lr_valuenode TYPE REF TO cl_bsp_wd_value_node, lr_col TYPE REF TO cl_crm_bol_bo_col. IF gv_first_show = abap_true. gv_first_show = abap_false. lt_tabledata = VALUE #( ( zz_id = '1' zz_field1 = 'SomeInfo' zz_field2 = 'SomeInfo' zz_field3 = 'SomeInfo ') ( zz_id = '2' zz_field1 = 'SomeInfo' zz_field2 = 'SomeInfo' zz_field3 = 'SomeInfo ') ( zz_id = '3' zz_field1 = 'SomeInfo' zz_field2 = 'SomeInfo' zz_field3 = 'SomeInfo ') ( zz_id = '4' zz_field1 = 'SomeInfo' zz_field2 = 'SomeInfo' zz_field3 = 'SomeInfo ') ). "create collection object. CREATE OBJECT lr_col. CREATE DATA lr_table. LOOP AT lt_tabledata INTO DATA(ls_tabledata). CREATE OBJECT lr_valuenode EXPORTING iv_data_ref = lr_table. "set the data into the value node. lr_valuenode->if_bol_bo_property_access~set_properties( is_attributes = ls_tabledata ). "add node to the collection. lr_col->if_bol_bo_col~add( lr_valuenode ). ENDLOOP. me->typed_context->nodet->collection_wrapper->set_collection( lr_col ). * gt_button = VALUE #( ( text = 'Edit' on_click = 'EDIT' enabled = abap_true ) ( type = cl_thtmlb_util=>gc_icon_add on_click = 'CREATE' enabled = abap_false ) ( type = cl_thtmlb_util=>gc_icon_delete on_click = 'DELETE' enabled = abap_false ) ). ENDIF. ENDMETHOD. |
3. Далее создаем атрибут являющийся признаком редатируемости таблицы
4. Его, а также табличку с кнопками необходимо прописать в HTML нашей таблички
Изменения производятся вот здесь:
В виде кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<%@page language="abap" %> <%@extension name="thtmlb" prefix="thtmlb" %> <%@extension name="chtmlb" prefix="chtmlb" %> <%@extension name="bsp" prefix="bsp" %> <% * Conversion Cnode SelectionMode to Tag data: lv_cellerator_selectionmode type string, lv_cellerator_editmode type string, lv_cellerator_selectioncolumn type string. cl_thtmlb_util=>translate_selection_mode( exporting iv_selection_mode = nodeT->SELECTION_MODE iv_all_rows_editable = nodeT->mv_edit importing ev_selection_mode = lv_cellerator_selectionmode ev_edit_mode = lv_cellerator_editmode ev_selection_column = lv_cellerator_selectioncolumn ). %> <chtmlb:configCellerator downloadToExcel = "TRUE" editMode = "<%= lv_cellerator_editmode %>" id = "ConfCellTable" onRowSelection = "select" personalizable = "TRUE" selectedRowIndex = "<%= nodeT->SELECTED_INDEX %>" selectedRowIndexTable = "<%= nodeT->SELECTION_TAB %>" selectionColumn = "<%= lv_cellerator_selectioncolumn %>" selectionMode = "<%= lv_cellerator_selectionmode %>" table = "//nodeT/Table" usage = "EDITLIST" visibleFirstRow = "<%= nodeT->VISIBLE_FIRST_ROW_INDEX %>" visibleRowCount = "6" width = "100%" actions = "<%= controller->gt_button %>" xml = "<%= controller->configuration_descr->get_config_data( ) %>" /> |
5. Создадим события с теми же именами, которые мы прописали в таблице gt_button.
6. Реализуем метод Edit;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
METHOD eh_onedit. DATA: lr_tx TYPE REF TO if_bol_transaction_context, lr_entity TYPE REF TO if_bol_bo_property_access. IF typed_context->nodet->mv_edit IS INITIAL. typed_context->nodet->mv_edit = abap_true. gt_button[ on_click = 'CREATE' ]-enabled = abap_true. gt_button[ on_click = 'DELETE' ]-enabled = abap_true. ELSE. CLEAR typed_context->nodet->mv_edit. gt_button[ on_click = 'CREATE' ]-enabled = abap_false. gt_button[ on_click = 'DELETE' ]-enabled = abap_false. ENDIF. ENDMETHOD. |
7. Метод Delete;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
METHOD eh_ondelete. * DATA : lr_current TYPE REF TO if_bol_bo_property_access, lr_col TYPE REF TO if_bol_bo_col, lv_size TYPE i. lr_col ?= typed_context->nodet->collection_wrapper->get_marked( ). lv_size = lr_col->size( ). IF lv_size > 0. DO lv_size TIMES. IF sy-index = 1. lr_current ?= lr_col->get_first( ). ELSE. lr_current ?= lr_col->get_next( ). ENDIF. typed_context->nodet->collection_wrapper->remove( lr_current ). ENDDO. ENDIF. ENDMETHOD. |
8. Метод Create
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
METHOD eh_oncreate. DATA:lr_table TYPE REF TO zsb_test_struct, lr_valuenode TYPE REF TO cl_bsp_wd_value_node. DATA ls_tabledata TYPE zsb_test_struct. CREATE DATA lr_table. CREATE OBJECT lr_valuenode EXPORTING iv_data_ref = lr_table. ls_tabledata-zz_id = 'XX'. ls_tabledata-zz_field1 = 'SomeInfo'. ls_tabledata-zz_field2 = 'SomeInfo'. ls_tabledata-zz_field3 = 'SomeInfo '. ls_tabledata-flag = abap_false. lr_valuenode->if_bol_bo_property_access~set_properties( is_attributes = ls_tabledata ). typed_context->nodet->collection_wrapper->add( lr_valuenode ). ENDMETHOD. |
В результате получим следующее окно до нажатия Edit
После нажатия Edit кнопки активируются и работают
9. Как можно увидеть, чекбокс работает нормально. Для усложнения сделаем так, чтобы можно было выбрать только один. Для этого при выборе нового значения, будем чистить остальные. По умолчанию, событие установки значения(Метод SET_FLAG ) не сработает до нажатия enter или сабмита какой либо кнопки. Такой режим работы не подходит. Поэтому надо переопределить метод GET_P_FLAG и указать, что у нас тут есть событие.
1 2 3 4 5 6 7 8 9 10 |
METHOD GET_P_FLAG. CASE iv_property. WHEN if_bsp_wd_model_setter_getter=>fp_fieldtype. rv_value = cl_bsp_dlc_view_descriptor=>field_type_checkbox. WHEN if_bsp_wd_model_setter_getter=>fp_onclick. rv_value = 'CLICKFLAG'. ENDCASE. ENDMETHOD. |
Теперь в создадим метод события CLICKFLAG
Реализуем его, чтобы после установки нового значения, очищать предыдущие.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
METHOD eh_onclickflag. DATA lv_index TYPE i. DATA: lr_entity TYPE REF TO cl_bsp_wd_value_node, lr_current TYPE REF TO if_bol_bo_property_access, lr_col TYPE REF TO if_bol_bo_col, lr_core TYPE REF TO cl_crm_bol_core. FIELD-SYMBOLS <lv_flag> TYPE any. CALL METHOD cl_thtmlb_util=>get_event_info EXPORTING iv_event = htmlb_event_ex IMPORTING ev_index = lv_index. CHECK lv_index IS NOT INITIAL. * Get the current entity me->typed_context->nodet->collection_wrapper->find( iv_index = lv_index ). lr_current = typed_context->nodet->collection_wrapper->get_current( ). lr_entity ?= lr_current. DATA(lv_current_index) = typed_context->nodet->collection_wrapper->get_current_index( ). DATA(lv_current_flag) = lr_current->get_property( 'FLAG' ). ASSIGN lv_current_flag->* TO <lv_flag>. IF <lv_flag> = 'X'. DATA(lo_line) = typed_context->nodet->collection_wrapper->get_first( ). WHILE lo_line IS BOUND. IF lv_current_index <> typed_context->nodet->collection_wrapper->get_current_index( ). lo_line->set_property( iv_attr_name = 'FLAG' "#EC NOTEXT iv_value = '' ). ENDIF. lo_line = typed_context->nodet->collection_wrapper->get_next( ). ENDWHILE. ENDIF. ENDMETHOD. |