Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
uladzislau_pralat
Contributor
0 Kudos

Web Dynpro ABAP provides an extensive set of UI Elements. In most cases standard UI Elements suit developer needs. If not, there is an option to create your own UI element, for example, with the help of HTML5 islands or Adobe Flash Islands. If you do not have Flex Builder knowledge or your system is not on right release level (7.31 SP5 for HLTML5 island) then IFrame UI Element is the only choice.

Lets say you have a requirement to display notes that users add to a document in form of a chat. Standard UI Elements like Table, FormattedTextView or TextView can not satisfy the requirement. It is easy to model Chat UI Element with the help of IFrame UI Element, InputField UI Element and some basic knowlege of HTML, CSS, JavaScript, XML and XSLT.

What it takes is:

1) Transform notes internal table into XML using Simple Transformation;

2) Tranform XML into HTML using XSLT transformation;

3) Save HTML document in repository;

4) Map HTML document URL into Source property of IFrame UI Element.

Here is how modeled Chat UI Element looks:

It is easy to using Modeled Chat UI Element - just key in text and press enter:

Below are step by step instructions how to implement the demo application:

1) In trx. XSLT_TOOL create ZIFRAME_DEMO_ST Simple Transformation that transforms note internal table data into XML

In Source Cde tab add following code:

<?sap.transform simple?>
<tt:transform xmlns:tt=
"http://www.sap.com/transformation-templates">

<tt:root name=
"NOTE"/>

<tt:template>
<ZIFRAME_DEMO>
  <tt:loop ref=
".NOTE" name="line">
    <NOTE>
      <CREATED_BY>
          <tt:value ref=
"$line.CREATED_BY" />
      </CREATED_BY>
      <CREATED_ON>
          <tt:value ref=
"$line.CREATED_ON" />
      </CREATED_ON>
      <CREATED_AT>
          <tt:value ref=
"$line.CREATED_AT" />
      </CREATED_AT>
      <NOTE>
          <tt:value ref=
"$line.NOTE" />
      </NOTE>
    </NOTE>
  </tt:loop>
</ZIFRAME_DEMO>
</tt:template>

</tt:transform>

2) In trx. XSLT_TOOL create ZIFRAME_DEMO_XSLT XSLT Transformation that transforms XML to HTML

In Source Cde tab add following code:

<xsl:transform version="1.0"
  xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform"
  xmlns:sap=
"http://www.sap.com/sapxsl"
>

<xsl:strip-space elements=
"*"/>


<xsl:template match=
"/">
  <html>
<head>
<script>
window.onload=toBottom;
function toBottom()
{
setTimeout(function(){window.scrollTo(0, document.body.scrollHeight);},250);
}
</script>
</head>

  <style>
    html {height: 100%; width:100%; padding:0px; margin:0px;}
    body {background-color:#e7eff7; height:100%; width:100%; padding:0px; margin: 0px;border-style:solid;border-width:1px;border-color:#A5ADB5;}
    table.props1 td { font-family:Arial,Helvetica,sans-serif; font-size: 0.7em; }
    table.props { background:#999999; }
    table.props td { background:#FFFFFF; padding:1 1; vertical-align:top; font:normal
10 verdana; padding-left=4px; padding-right=4px; }
    table.props th { background:#EEEEEE; padding:1 1; vertical-align:top; font:normal
10 verdana; padding-left=4px; padding-right=4px; }
  </style>

  <body >
  <table class=
"props1" width="100%">
    <xsl:for-each select=
"ZIFRAME_DEMO/NOTE">
      <tr>
      <td title=
"{CREATED_BY}" width="120p" style="color:#296394;vertical-align:top;"><xsl:value-of select="CREATED_BY"/>
      <br/><xsl:value-of select=
"CREATED_ON"/><xsl:text> </xsl:text><xsl:value-of select="CREATED_AT"/></td>
      <td valign=
"top"><xsl:value-of select="NOTE"/></td>
    </tr>
  </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:transform>

Note: XSLT transformation formats output using HTML and CSS and also scrolls to last note using JavaScript

3) Create ZIFRAME_DEMO Component

4) Add NOTE context node to MAIN view.

Set cardinality of NOTE node to 0..n, then CREATED_BY, CREATED_ON, CREATED_AT and NOTE attributes of types NAME1, DATS, TIMS and STRING respectively

5) Add NOTE_URL attribute to MAIN view context. Set type to STRING.

6) Add NOTE_NEW attribute to MAIN view context. Set type to STRING

7) On MAIN view set ROOTUIELEMENTCONTAINER UI Element layout to MatrixLayout

😎 Add IFRAME UI element to MAIN view layout. Set Layout Data to MatrixHeadData, set width to 400px and map Source to MAIN.NOTE_URL

9) Add INPUTFIELD UI element. Layout Data to MatrixHeadData, set width to 400px, map Value to MAIN.NOTE_NEW, create ENTER action and assign it to onEnter event (it will be implemented later).

10) Create GET_HTML method of MAIN view. This method Note data into XML and then into HTML.

METHOD get_html.
DATA: w_xml TYPE string.

* Transform Note data into XML
 
CALL TRANSFORMATION ziframe_demo_st
   
SOURCE note = it_note
   
RESULT XML w_xml.
* Transform XML into HTML
 
CALL TRANSFORMATION ziframe_demo_xslt
   
SOURCE XML w_xml
   
RESULT XML rv_html.

ENDMETHOD.

11) Create GET_URL method in MAIN view. This method creates HTML document in respository and returns its URL.

METHOD get_url.
DATA: cached_response TYPE REF TO if_http_response.
DATA: w_guid TYPE guid_32.
DATA: w_url TYPE string.

* Creat response object
 
CREATE OBJECT cached_response
   
TYPE
      cl_http_response
   
EXPORTING add_c_msg        = 1.
 
TRY. " ignore, if compression can not be switched on
   
CALL METHOD cached_response->set_compression
     
EXPORTING  options = cached_response->co_compress_based_on_mime_type
       
EXCEPTIONS
         
OTHERS  = 1.
   
CATCH cx_root.
 
ENDTRY.
* Set response object header and data
  cached_response
->set_cdata( iv_html ).
  cached_response
->set_header_field( name  = if_http_header_fields=>content_type
                                   
value = 'text/html' ).
  cached_response
->set_status( code = 200 reason = 'OK' ).
  cached_response
->server_cache_expire_rel( expires_rel = 3600 ).
* Generate URL
 
CALL FUNCTION 'GUID_CREATE'
     
IMPORTING
            ev_guid_32
= w_guid.
 
CONCATENATE '/sap/public/' w_guid '.' 'html' INTO rv_url.
* Cache the URL
  cl_http_server
=>server_cache_upload( url      = rv_url
                                      response
= cached_response ).

ENDMETHOD.

12) Implement WDDOINIT method of MAIN view. This method initializes IFRAME with notes

METHOD wddoinit.
DATA: w_html TYPE string,
      w_url 
TYPE string.
DATA: wa_note TYPE wd_this->element_note,
      wt_note
TYPE wd_this->elements_note.
DATA: node_note TYPE REF TO if_wd_context_node.
DATA: w_note_1 TYPE string,
      w_note_2
TYPE string,
      w_note_3
TYPE string,
      w_note_4
TYPE string,
      w_note_5
TYPE string,
      w_note_6
TYPE string.

 
CONCATENATE: 'Web Dynpro ABAP provides an extensive set of UI Elements.'
             
'In most cases standard UI Elements suit developer needs.'
             
'If not, there are options to create your own UI element,'
             
'for example, with the help of HTML5 islands or Adobe Flash Islands.'
             
'If you do not have Flex Builder knowledge or your system is not on right release level'
             
'(7.31 SP5 for HLTML5 island) then IFrame UI Element is your only option.' INTO w_note_1 SEPARATED BY SPACE,
             
'Lets say you have a requirement to display notes that users add to a document in form of a chat.'
             
'Standard UI Elements like Table, FormattedTextView or TextView can satisfy the requirement.'
             
'It is easy to model Chat UI Element with the help of IFrame UI Element and some basic knowlege of HTML, CSS, JavaScript, XML and XSLT.'
             
'What it takes:' INTO w_note_2 SEPARATED BY SPACE.
  w_note_3
'1) Serialize notes internal into XML form using Simple Transformation;'.
  w_note_4
'2) Tranform XML into HTML using XSLT transformation;'.
  w_note_5
'3) Save HTML document in repository;'.
  w_note_6
'4) Map HTML document URL into Source property of IFrame UI Element'.

* Set initial notes
  wa_note
-created_by = 'Uladzislau Pralat'.
  wa_note
-created_on = '20140924'.
  wa_note
-created_at = 135903.
  wa_note
-note      = w_note_1.
 
APPEND wa_note TO wt_note.
  wa_note
-note      = w_note_2.
 
APPEND wa_note TO wt_note.
  wa_note
-note      = w_note_3.
 
APPEND wa_note TO wt_note.
  wa_note
-note      = w_note_4.
 
APPEND wa_note TO wt_note.
  wa_note
-note      = w_note_5.
 
APPEND wa_note TO wt_note.
  wa_note
-note      = w_note_6.
 
APPEND wa_note TO wt_note.

  node_note
= wd_context->get_child_node( wd_this->wdctx_note ).
  node_note
->bind_table( wt_note ).
* Generate HTML
  w_html
= get_html( wt_note ).
* Generate URL
  w_url
= get_url( w_html ).
* Bind URL to IFrame
  wd_context
->set_attribute( name 'NOTE_URL'
                           
value = w_url ).

ENDMETHOD.

13) Implement ONACTIONENTER method of MAIN view to reach on ENTER action. This method adds new note to IFRAME and clears INPUTFIELD.

METHOD onactionenter.
DATA: w_html TYPE string,
      w_url 
TYPE string.
DATA: w_note_new TYPE wd_this->element_context-note_new.
DATA: ws_note TYPE wd_this->element_note,
      wt_note
TYPE wd_this->elements_note.
DATA: node_note TYPE REF TO if_wd_context_node.
DATA: element_note TYPE REF TO if_wd_context_element.

* Get new note
  wd_context
->get_attribute( EXPORTING name  = 'NOTE_NEW'
                           
IMPORTING value = w_note_new ).
* Add new note to context
  node_note
= wd_context->get_child_node( wd_this->wdctx_note ).
  element_note
= node_note->create_element( ).
  ws_note-created_by
= 'Uladzislau Pralat'.
  ws_note-created_on
= sy-datum.
  ws_note-created_at
= sy-uzeit.
  ws_note
-note      = w_note_new.
  element_note
->set_static_attributes( ws_note ).
  node_note
->bind_element( new_item            = element_note
                          set_initial_elements
= abap_false ).
* Get all notes from context
  node_note
->get_static_attributes_table( IMPORTING table = wt_note ).
* Generate HTML
  w_html
= get_html( wt_note ).
* Generate URL
  w_url
= get_url( w_html ).
* Bind URL to IFrame
  wd_context
->set_attribute( name 'NOTE_URL'
                            value
= w_url ).
* Clear new note
  wd_context
->set_attribute( name  = 'NOTE_NEW'
                            value
= SPACE ).

ENDMETHOD.

14) Create ZIFRAME_DEMO Application

Labels in this area