В общем по заданию начальства пришлось делать интерфейс с использованием класса cl_gui_html_viewer. Попытаюсь рассказать какие грабли встретились при решении этой задачи и какие из них удалось обойти.
Для работы с HTML использовал класс cl_gui_html_viewer - через него осуществляется заполнение и отображение HTML контента. Вот пример создания экземпляра класса, загрузки шаблона из репозитария и отображения в контейнере:
data:
creat_html_control TYPE REF TO cl_gui_html_viewer, "Непосредственно экземпляр класса
creat_container TYPE REF TO cl_gui_custom_container, "Конейнер на форме для размещения
doc_url(80). "Имя, которое будет присвоено шаблону после выгрузки. По этому имени внутри HTML можно делать ссылки
IF creat_html_control IS INITIAL.
CREATE OBJECT creat_container"Создаем контейнер
EXPORTING
container_name = 'HTML_CONTAINER'."Имя контейнера на форме
CREATE OBJECT creat_html_control"Создаем экземпляр
EXPORTING
parent = creat_container.
IF sy-subrc NE 0.
ENDIF.
ENDIF.
doc_url = 'htm1.htm'.
CALL METHOD creat_html_control->load_html_document "Загружаем шаблон
EXPORTING
document_id = 'ZPA_TEMPL_9840_ADV' "Имя шаблона в репозитории - транзакция SMW0
IMPORTING
assigned_url = doc_url
EXCEPTIONS
OTHERS = 1.
CALL METHOD creat_html_control->show_url
EXPORTING
url = doc_url.
CL_GUI_HTML_VIEWER=>set_focus( creat_html_control ).
Следующий шаг при работе с HTML - это обработка событий. Событие, связанное с действиями внутри HTML кода у класса всего одно - SAPEVENT. Параметров у события немного:
Я использовал только ACTION - имя события, которое можно задать в HTML и QUERY_TABLE - представляет из себя таблицу с двумя полями - NAME и VALUE, что позволяет передавать через него несколько значений за раз. Вот пример реализации обработки событий, в примере реализована обработка события с передачей одного значения:
Код
При первом подходе к реализации интерфейса я не пользовался никакими дополнительными ресурсами - только шаблон в WEB репозитории SAP (транзакция SMW0) и код в SAP. Вот что получилось:
Код
а вот как выглядит скрипт, который обрабатывает событие (указывается в HTML шаблоне в <HEAD>):
Для работы с HTML использовал класс cl_gui_html_viewer - через него осуществляется заполнение и отображение HTML контента. Вот пример создания экземпляра класса, загрузки шаблона из репозитария и отображения в контейнере:
data:
creat_html_control TYPE REF TO cl_gui_html_viewer, "Непосредственно экземпляр класса
creat_container TYPE REF TO cl_gui_custom_container, "Конейнер на форме для размещения
doc_url(80). "Имя, которое будет присвоено шаблону после выгрузки. По этому имени внутри HTML можно делать ссылки
IF creat_html_control IS INITIAL.
CREATE OBJECT creat_container"Создаем контейнер
EXPORTING
container_name = 'HTML_CONTAINER'."Имя контейнера на форме
CREATE OBJECT creat_html_control"Создаем экземпляр
EXPORTING
parent = creat_container.
IF sy-subrc NE 0.
ENDIF.
ENDIF.
doc_url = 'htm1.htm'.
CALL METHOD creat_html_control->load_html_document "Загружаем шаблон
EXPORTING
document_id = 'ZPA_TEMPL_9840_ADV' "Имя шаблона в репозитории - транзакция SMW0
IMPORTING
assigned_url = doc_url
EXCEPTIONS
OTHERS = 1.
CALL METHOD creat_html_control->show_url
EXPORTING
url = doc_url.
CL_GUI_HTML_VIEWER=>set_focus( creat_html_control ).
Следующий шаг при работе с HTML - это обработка событий. Событие, связанное с действиями внутри HTML кода у класса всего одно - SAPEVENT. Параметров у события немного:
- ACTION
- FRAME
- GETDATA
- POSTDATA
- QUERY_TABLE
Я использовал только ACTION - имя события, которое можно задать в HTML и QUERY_TABLE - представляет из себя таблицу с двумя полями - NAME и VALUE, что позволяет передавать через него несколько значений за раз. Вот пример реализации обработки событий, в примере реализована обработка события с передачей одного значения:
Код
CLASS cl_creat_handler IMPLEMENTATION. METHOD on_sapevent. data: ls_q_table like line of query_table, ls_frontend_val like line of gt_frontend_val, edaction(100). field-symbols: <fs_val> type gty_frontend_values. edaction = action. "Имя события case edaction. when 'GetData' or 'KeyData'. loop at query_table into ls_q_table. "Смотрим таблицу с получаемыми значениями condense ls_q_table-name. ls_frontend_val-name = ls_q_table-name. concatenate ls_frontend_val-value ls_q_table-value into ls_frontend_val-value. "Если в таблице значений больше одной записи, то соберем их все в оду переменную endloop. read table gt_frontend_val assigning <fs_val> with key name = ls_frontend_val-name. if sy-subrc <> 0. append ls_frontend_val to gt_frontend_val. else. <fs_val>-value = ls_frontend_val-value. endif. endcase. ENDMETHOD. ENDCLASS. " cl_creat_handler implementation "Ну и вот так присваивается обработчик: DAT A: creat_evt_receiver TYPE REF TO cl_creat_handler, myevent_tab TYPE cntl_simple_events, myevent TYPE cntl_simple_event. myevent-eventid = creat_html_control->m_id_sapevent. myevent-appl_event = 'x'. APPEND myevent TO myevent_tab. CALL METHOD creat_html_control->set_registered_events EXPORTING events = myevent_tab. CREATE OBJECT creat_evt_receiver. SET HANDLER creat_evt_receiver->on_sapevent FOR creat_html_control. |
При первом подходе к реализации интерфейса я не пользовался никакими дополнительными ресурсами - только шаблон в WEB репозитории SAP (транзакция SMW0) и код в SAP. Вот что получилось:
Для реализации этого интерфейса пришлось очень много писать в SAP кода оформления, плюс отслеживать события нажатия на вкладки и перерисовывать всю страницу каждый раз при переключении вкладок.
Теперь про обещанные грабли:
Первое - разметка HTML - все размеры, смещения, отступы надо задавать в пикселях (px), иначе есть вероятность что у какого-нибудь пользователя вся красота расползется.
Второе и самое главное - результаты заполнения полей ввода. Так как класс SAP не имеет никакого представления об объектах внутри шаблона HTML, то за передачу правильных данных отвечает исключительно HTML шаблон. Вот здесь и появляется обещанный в заголовке JScript.
Итак для полей ввода возможны несколько ситуаций, когда надо передать данные:
Теперь про обещанные грабли:
Первое - разметка HTML - все размеры, смещения, отступы надо задавать в пикселях (px), иначе есть вероятность что у какого-нибудь пользователя вся красота расползется.
Второе и самое главное - результаты заполнения полей ввода. Так как класс SAP не имеет никакого представления об объектах внутри шаблона HTML, то за передачу правильных данных отвечает исключительно HTML шаблон. Вот здесь и появляется обещанный в заголовке JScript.
Итак для полей ввода возможны несколько ситуаций, когда надо передать данные:
- ввод значения завершен и пользователь переходит в другое поле для продолжения ввода
- ввод значения завершен и пользователь нажимает кнопку "Сохранить" в интерфейсе SAP
Первое событие отловить очень просто - это onChange тэга <input>. Вот пример привязки обработчика:
Код
<input type="text" name="Z_OB_1" size=2" onc hange="sendVal(this)"> |
Код
В скрипте осуществляется разбиение значения поля ввода на куски по 250 символов (на стороне SAP значение большего размера обрезаются), затем формируется SAP ссылка, которая инициирует событие SAPEVENT на стороне SAP. Ссылка должна иметь следующий вид: SAPEVENT:Имя_события?имя_переменной1 = значение1&имя_переменной2 = значение2 теоретически переменных и значений может быть сколь угодно много. Далее командой location.href передаем полученное значение в SAP.function sendVal(e) { var l_str=e.value; var la_array=l_str.match(/.{1,250}/g); var vl_str='SAPEVENT:KeyData?'; for(var i=0; i<la_array.length; i++){ if (i>0) {vl_str=vl_str+'&';} vl_str=vl_str+e.name+'_'+i+'='+la_array[i]; } location.href=vl_str; } |
Комментариев нет:
Отправить комментарий