Since the introduction of HTML Islands in Web Dynpro for ABAP (WDA) it's possible to integrate more or less any web-based content. And as FPM is based on WDA, this is valid also for freestyle UIBBs in FPM (see for example the blog
How to use a Java Script Chart Library in Floorplan Manager Applications).This is also valid for UI5 based content. In this blog I want to demonstrate how a UI5 control can be integrated into FPM. I chose the timeline control as example, as WDA doesn't offer such a control. By following this example, you should be able to integrate any other UI5 control as well.
To do this we will:
To understand this blog some basic knowledge in Web Dynpro for ABAP programming and FPM configuration is required. It's a very detailed step-by-step description how to create this freestyle UIBB. I will also explain the necessary JavaScript coding, so that you don't need JavaScript knowledge.
This blog is based on functionality available with Netweaver 7.40.
First we need to create our new UIBB. To do this we go to transaction SE80 and create a new Web Dynpro component. The name is arbitrary - I will use ZSCN_TIMELINE_UIBB and use W_TIMELINE as window and V_TIMELINE as View name. I will also use an assistance class named ZCL_TIMELINE_ASSIST and Implement the UIBB interface IF_FPM_UI_BUILDING_BLOCK on this component
In the end the component structure should look like this:
To embed and interact the UI5 control we need to add an HTML island to view V_TIMELINE and assign "<div id="mytimeline" style="height:100%"></div>" as value for property "staticHtml".
To make the UI5 timeline control available to this HTML Island we have to add the necessary script accesses: To do this
This will make sure that UI5 and the needed libraries are loaded at runtime.
Your view should now look like this:
Don't forget to save and activate everything you made so far!
Although our UIBB isn't capable of displaying anything so far, it's now time to create a test application where we can see and test the progress of our work.
As we did not add any content (except an empty DIV tag) to our Html Island there is only an empty space in the Timeline panel.
Now we have to add the necessary client side code to create the timeline control and place it into our Html Island. To do this create a simple text file, add the following code to it and save it (best with extension ".js").
var MY_TIMELINE = MY_TIMELINE || {
timeline: {},
oCallbackApi: {},
init: function (oCallbackApi) {
this.oCallbackApi = oCallbackApi;
this.timeline = new sap.suite.ui.commons.Timeline();
this.timeline.placeAt("mytimeline");
}
}
Let me shortly explain this code: We are creating one instance of object MY_TIMELINE on the client. This object has 3 members:
Now we have to upload this code as MIME object to our new component. Launch SE80 and navigate to our UIBB component. Import your javascript file as Mime object via context menu on the component.
Now add this script as additional script to the Html Island
At runtime the script will be loaded and the Html Island can access the script. However to create and locate the timeline control the init method has to be called. Therefore we need to add a call to this method to our Html Island and this is done by adding the following ABAP code to the view's WDDOMODIFYVIEW method:
METHOD wddomodifyview .
IF first_time = abap_true.
DATA(lo_timeline) = CAST cl_wd_html_island( view->get_element( `TIMELINE` ) ).
lo_timeline->add_script_call( cl_wd_html_script_call=>new_call(
)->variable( `MY_TIMELINE`
)->function( `init`
)->add_callback_api( ) ).
ENDIF.
ENDMETHOD.
We simply add a script call object to our Html Island. The script call is calling the init function on (object) variable MY_TIMELINE and is adding a single parameter to the script call - the call back API. This JavaScript function will now be called on the client. If you run the test application you can see only a small change on the UI, a filter icon. However this filter icon belongs to the UI5 timeline control - we have now successfully instantiated the UI5 control and embedded it into our FPM application.
A timeline control without any data isn't very exciting, therefore let it display some backend data. First let's create some timeline data. We will do this in our assistance class:
types: begin of TY_S_ITEM,
datetime type string,
user_name type string,
title type string,
text type string,
icon type string,
end of ty_s_item.
types: ty_t_item type STANDARD TABLE OF ty_s_item with DEFAULT KEY.
methods GET_TIMELINE_DATA
returning
value(RT_DATA) type TY_T_ITEM .
DATA(lo_version_provider) = cl_wb_object_version_provider=>create_instance( ).
DATA(lo_version_info) = lo_version_provider->get_versions(
pgmid = 'R3TR'
object_type = 'CLAS'
object_name = 'CL_FPM_OVP_ASSIST'
).
LOOP AT lo_version_info->get_list( ) ASSIGNING FIELD-SYMBOL(<version_list>).
DATA(ls_vers_info) = <version_list>->get_info( ).
APPEND INITIAL LINE TO rt_data ASSIGNING FIELD-SYMBOL(<item>).
CONVERT DATE ls_vers_info-datum TIME ls_vers_info-zeit
INTO TIME STAMP DATA(ts) TIME ZONE sy-zonlo.
<item>-datetime = |{ ts TIMESTAMP = ISO TIMEZONE = 'UTC ' }|.
<item>-user_name = ls_vers_info-author.
<item>-title = ls_vers_info-korrnum.
<item>-text = ls_vers_info-trequest_text.
<item>-icon = 'sap-icon://request'.
ENDLOOP.
method WDDOINIT .
data(lo_nd_item) = wd_context->get_child_node( name = wd_this->wdctx_item ).
lo_nd_item->bind_table( new_items = wd_assist->get_timeline_data( ) ).
endmethod.
Pay attention to the name attributes. These are used to access the data in the JavaScript code. I chose "content", "datetime", "userName", "title", "text" and "icon". If you are using other names you have to adjust the script accordingly.
var MY_TIMELINE = MY_TIMELINE || {
timeline: {},
oCallbackApi: {},
init: function (oCallbackApi) {
this.oCallbackApi = oCallbackApi;
this.timeline = new sap.suite.ui.commons.Timeline();
this.timeline.placeAt("mytimeline");
},
setContent: function (content) {
this.timeline.destroyContent();
for(var i=0, max=content.length; i<max; i++) {
var item = new sap.suite.ui.commons.TimelineItem({
dateTime : new Date(content[i].datetime),
userName : content[i].userName,
title : content[i].title,
text : content[i].text,
icon : content[i].icon
});
this.timeline.addContent(item);
}
}
}
To pass the data to the control I added the setContent function to the script. This method will get the timeline data as an array parameter and it will create timeline items for each array entry.
lo_timeline->add_script_call( cl_wd_html_script_call=>new_call(
)->variable( `MY_TIMELINE`
)->function( `setContent`
)->add_ui_elem_data_source( `content` ) ).
Now everything should be done and the test application should show some data (if it doesn't work you have to clear the browser cache😞
Up to now, we have embedded a UI5 control in to an FPM application and filled it with data from the ABAP backend. What's missing is the other direction: Sending data from the control to the backend.
This is done by raising a Web Dynpro Action from the client-side JavaScript code.
method ONACTIONSELECT .
cl_fpm_factory=>get_instance( )->mo_message_manager->report_message(
EXPORTING
iv_message_text = wdevent->get_string( `DATA` )
).
endmethod.
var MY_TIMELINE = MY_TIMELINE || {
timeline: {},
oCallbackApi: {},
init: function (oCallbackApi) {
this.oCallbackApi = oCallbackApi;
this.timeline = new sap.suite.ui.commons.Timeline();
this.timeline.placeAt("mytimeline");
this.timeline.attachSelect(
function(oControlEvent) {
MY_TIMELINE.oCallbackApi.fireEvent('select', oControlEvent.getParameter("selectedItem").getTitle());
}
);
},
setContent: function (content) {
this.timeline.destroyContent();
for(var i=0, max=content.length; i<max; i++) {
var item = new sap.suite.ui.commons.TimelineItem({
dateTime : new Date(content[i].datetime),
userName : content[i].userName,
title : content[i].title,
text : content[i].text,
icon : content[i].icon
});
this.timeline.addContent(item);
}
}
}
The only changes are lines 8-12: There we attach a new function to the control's Select event. In this function we are using the callback api we already stored in the first version of the script to forward this client-side event to the backend, where it then raises the SELECT-Action of our view. As event parameter we pass the selected items title to the backend.
Now if run the test application again and click on any item we should get a (error) message with the item's title as text:
Although this blog is quite lengthy, it's not much effort to integrate a UI5 control. The integration control is the Html Island. Via standard WD Abap methods like context binding the application data is passed to the Html Island. The rendering, and placing of the control as well as the data transport from the Html Island to the control is then done via JavaScript coding attached to the Html Island. The backward direction is done by raising HtmlEvents via JavaScript coding, which then triggers Web Dynpro Actions.
My step-by-step description was reduced to the absolute minimum necessary to demonstrate the integration of a UI5 control. Therefore the result is a bit ugly and there is still a lot of work to be done before such a UIBB can be used productively. But the basic steps are the same as the FPM team used when implementing the Carousel or the Visbiz UIBB.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
14 | |
9 | |
7 | |
7 | |
5 | |
5 | |
4 | |
4 | |
3 | |
3 |