Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

Introduction

In my continuing quest to recreate some of the better user interface elements of the SAPGui for Windows/Classic Dynpro experience; I recently set out to try and recreate one of my personal favorites - the F1 field level help.
My goal was to recreate not just the context help, but also the technical information about the field that is exposed like in the classic dynpro. As we have developed large and complex BSP applications (especially very dynamic ones), the lack of some mechanism to identify what part of the code houses a particular element is greatly missed.



New!

Now you can download this document in PDF format and you can download a package with the code, class defintions, and screen shots.

Code Sample Explaination

Code and Class Definitions



My search for this functionality actually began by studying some of the CRM BSP functionality that now is part of the Basis layer in WebAS 640. There is a lot of very impressive functionality in the CRM framework. Unfortunately the individual components are very dependent upon the CRM Framework. It was going to require considerable changes to try to adapt their implementation of F1 help for use as a standalone component.


Therefore I set out to create my own Field help control as a reusable BSP Extension Element. Although the finished solution is rather complex internally (like any generic object usually is), I wanted to make sure that the using the component was as simple as possible. To that end I decided to wrap my functionality to fire the field help around the HTMLB label element. I will generate a Hyperlink that will open the context help in a modal window when clicked. The final solution ended up being so simple to implement in your code that all you have to do is change the name of the element from label to f1Label if you are using Model View Binding. If you aren't using Binding or if you want to override the data element from the binding attribute, you only need to add on attribute in addition to the standard label attributes to provide this data element name. The easy that this new element can be introduced into existing views is especially important considering the amount of code that I want to go back and retrofit with this new functionality. Add to this that my company has a number of new developers just beginning to learn BSP. I also wanted to make this solution as approachable for this group as any of the other simple HTMLB elements.


Before we get started, I want to note that I developed this solution on WebAS 640 SP12. However looking over the solution I don't see anything that you shouldn't be able to implement in earlier support packages or even in WebAS 620.


The Solution

Let's have a look at the finished solution before we go any further into exploring the coding. First we will have a look at what the hyper linked labels look like in a sample application.

!https://weblogs.sdn.sap.com/weblogs/images/1918/F1_Appl.gif|height=258|alt=image|width=421|src=https...!




When we click on the label hyperlink we get basic browser modal window where we display two tabs. In the first and default tab, we have the Data Element Help itself. The Internal ITF (SAPScript) format for the Help has been converted to HTML.




Now you might notice the internal hyperlink in the example Help for material. In the converted HTML, this link actually points to a SAPEVENT. If you have ever done any programming for HTML content in the SAPGui HTML viewer you might remember that this is a special event that will be caught and returned to our Dynpro Event processing. However this SAPEVENT link is useless in the BSP context. Therefore we will have to convert this to a normal hyperlink to make it functional. Also most of these internal links point to glossary entries instead of Data Element texts. Therefore we will need internal processing in our Help Viewer to support the processing of both. The following is a screen shot of the help after we navigate through the material link.




Next up we have the second tab (and the one that as a developer I am more interested in). This is the tab that displays our technical information about the field in question. In order to get the maximum amount of information displayed here, you will obviously want to use Model View Binding for the BSP Extension Element. That way we will have visibility to the hosting Controller, View, Model Class, Model Attribute, Model Binding String, and the data element types for the field in question. The following is a screen shot for our Material Field information.

wrapping

          design            = me->design

          for               = me->for

          required          = me->required

          text              = me->text

          tooltip           = me->tooltip ).

****Render the Text label

      WHILE m_page_context->element_process( element = label ) = co_element_continue.

      ENDWHILE. "End label Render

    ENDWHILE. "End Link Render

  ELSE.

****Normal Label - no Link because we couldn't determine a data element

    label ?= cl_htmlb_label=>factory(

           design             = me->design

           encode             = me->encode

           for                = me->for

           id                 = me->id

           id_postfix         = '__F1'

           labeledcontrolname = me->labeledcontrolname

           labeltype          = me->labeltype

           required           = me->required

           text               = me->text

           textdirection      = me->textdirection

           tooltip            = me->tooltip

           width              = me->width

           wrapping           = me->wrapping

           design            = me->design

           for               = me->for

           required          = me->required

           text              = me->text

           tooltip           = me->tooltip ).

****Render the Text label

    WHILE m_page_context->element_process( element = label ) = co_element_continue.

    ENDWHILE. "End label Render

  ENDIF.

ENDMETHOD.





BSP Element Class Methods - resolve_model_binding

If you use model view binding, this method will determine the class and its attribute that correspond to the provided binding string. This method will also use the RTTS (RunTime Type System) to determine information about the model class and details about the model attribute data type.

get_relative_name( ).

  ENDIF.

  •   FOR-attribute

  l_for = model->get_attribute_name( attribute_path = value_path ).

  •   ID-attribute

  IF id IS INITIAL.

    CONCATENATE l_for '_l' INTO id.

  ENDIF.

****Get Data Reference to bound data object

  DATA: l_data TYPE REF TO data.

  l_data = model->get_attribute_data_ref( attribute_path = value_path ).

  CHECK l_data IS NOT INITIAL.

****Get the RTTI Drescriptor for this data reference

  DATA: descriptor TYPE REF TO cl_abap_elemdescr.

  descriptor ?= cl_abap_elemdescr=>describe_by_data_ref( l_data ).

****Read Data Dictionary information for this reference

  DATA: flddescr TYPE dfies.

  flddescr = descriptor->get_ddic_field( ).

  me->dataelement = flddescr-rollname.

  system_state->rollname = me->dataelement.

  system_state->leng     = flddescr-leng.

  system_state->datatype = flddescr-datatype.

  system_state->inttype  = flddescr-inttype.

  system_state->model_class = class_name.

ENDMETHOD.





BSP Element Class Methods - record_system_state

This is the final method of our Element Class. This method is responsible for completing the model class. It then serializes it to XML and writes the XML string into a server cookie for later consumption. Finally the method creates the URL with the included keys to read the server cookie that will point to the Field Help Modal BSP application.

m_page_name.

  ENDIF.

  DATA: ostream TYPE string,

           xslt_err TYPE REF TO cx_xslt_exception.

          • serialize model class

  TRY.

      CALL TRANSFORMATION id

      SOURCE model = system_state

      RESULT XML ostream.

****Write cookie it into the Server Cookie

      cl_bsp_server_side_cookie=>set_server_cookie( name = data_name

        application_name = ''

        application_namespace = ''

        username = 'F1HELP'

        session_id = mc_runtime->session_id

        data_name = data_name

        data_value = ostream

        expiry_time_rel = '1200' ).

    CATCH cx_xslt_exception INTO xslt_err.

  ENDTRY.

****Send the Keys for the Model Class to the Popup via the URL

  DATA: url  TYPE string.

  DATA: page TYPE string.

  page = 'F1_Help.do'.

  DATA:  params TYPE tihttpnvp.

  FIELD-SYMBOLS: rfcdest ).

  • if input is available, dispatch this input to subcomponent.

  • this call is only necessary for toplevel controllers.

  • ( if this is not a toplevel controller or no input is present,

  •   this call returns without any action)

  dispatch_input( ).

  • if any of the controllers has requested a navigation,

  • do not try to display, but leave current processing

  if is_navigation_requested( ) is not initial.

    return.

  endif.

****Call our View

  view = create_view( view_name = 'F1_Help.bsp' ).

  view->set_attribute( name = 'model'      value = model2 ).

  call_view( view ).

endmethod.





BSP F1 Help Controller Method - do_handle_event

This is our only other inherited method. This has our logic for event handling. We only have one event - the switch of the selected tab.



BSP F1 Help Controller Method - load_values_from_formfield

This method has our logic to read our Server Cookie Keys from the URL.



BSP F1 Help Controller Method - read_model

This method has our logic to restore our model class instance back from the Server Cookie.

method read_model.

*@7BQReturning@     VALUE( R_MODEL )     TYPE REF TO IF_BSP_MODEL     BSP: Basis Interface for Models

  data: istream type string,

          xslt_err type ref to cx_xslt_exception.

        • Read Server cookie

  call method cl_bsp_server_side_cookie=>get_server_cookie

    exporting

      name                  = data_name

      application_name      = ''

      application_namespace = ''

      username              = 'F1HELP'

      session_id            = session_id

      data_name             = data_name

    changing

      data_value            = istream.

        • deserialize the Class

  if istream is not initial.

    try.

        call transformation id

        source xml istream

        result model = r_model.

      catch cx_xslt_exception into xslt_err.

    endtry.

  endif.

endmethod.





Implementing The BSP F1 Help Application - Model

The final component in our Field Help BSP application is the Model Class. This class has all the logic to read our Field Help or Glossary Entry. It also has the logic to convert the SAPEVENT hyperlinks. Don't forget to include the IF_SERIALIZABLE_OBJECT interface in this class definition. This is the interface that will allow us to convert the class instance to XML.



BSP F1 Help Model - Attributes

The following are the definition for all the attributes for our model class. Many of the fields contain the system information that will be bound to our View. There are also some attributes used in the internal manipulation of the Help Text.



















!https://weblogs.sdn.sap.com/weblogs/images/1918/spacer.gif|height=1|alt=|width=598|src=https://weblo...!

!https://weblogs.sdn.sap.com/weblogs/images/1918/spacer.gif|height=1|alt=|width=1|src=https://weblogs...!

!https://weblogs.sdn.sap.com/weblogs/images/1918/F1_Model_Attributes_r1_c1.gif|id=F1_Model_Attributes...!

!spacer.gif|height=306|alt=|width=1|src=spacer.gif|border=0!

!https://weblogs.sdn.sap.com/weblogs/images/1918/F1_Model_Attributes_r2_c1.gif|id=F1_Model_Attributes...!

!https://weblogs.sdn.sap.com/weblogs/images/1918/spacer.gif|height=150|alt=|width=1|src=https://weblo...!





BSP F1 Help Model Local Declarations

There is an SAP provided local class that we will use later to convert our SAPScript Help to HTML. The following are the local declarations for that class.



BSP F1 Help Model Methods - Initialize

This is the main public method of this class. This method is called from the Controller and triggers all the Method processing. It sets the keys of the method and begins the reading of the help text.



BSP F1 Help Model Methods - call_rfc

This method will call the SAP Function modules to read the Help Text or Glossary Entry. You might notice some static method calls to a class instance called converter. My study of the CRM BSP extensions did pay off, because I was able to reuse this nice SAPScript to HTML converter class. The actual coding for the converter class is contained in an include so it was easy to integrate into my model class.

method call_rfc.

  • DATA: html_page TYPE TABLE OF htmlline.

  data: html_page type w3htmltab.

  data: msg_text(80) type c.

  clear me->message.

  clear me->html_string.

  data: name type tdobname.

  data: begriff type termbegr.

  data: iline type table of tline.

  data: ihead type thead.

  if docuobject cp 'DE*'.

    name = docuobject+2.

    call function 'ABAP_DOCU_ITF_TO_HTML'

      exporting

        id            = 'DE'

        area          = ''

        name          = name

        file_flag     = ''

      changing

        html          = html_page

      exceptions

        docu_not_read = 1

        others        = 2.

    if sy-subrc <> 0.

    endif.

  elseif docuobject cp 'GLOS*'.

    begriff = docuobject+4.

    call function 'GLOSSARY_READ'

      exporting

        begriff = begriff

        sprache = sy-langu

        owner   = ''

      importing

        head    = ihead

      tables

        iline   = iline.

  • replace include texts, text symbols and control commands

    call method converter=>replace_itf_text

      exporting

        p_header   = ihead

        file_flag  = ''

      changing

        p_itf_text = iline.

  • my own itf-html conversion ...

    call method converter=>conversion

      exporting

        name        = ''

        p_langu     = sy-langu

        file_flag   = ''

        link_prefix = ''

      changing

        itf         = iline[]

        html        = html_page[].

  endif.

  field-symbols:

method build_url.

*@78QImporting@     I_NEW_ELEMENT     TYPE STRING     New Data Element Name

*@7BQReturning@     VALUE( R_URL )     TYPE STRING     

****Send the Keys for the Model Class to the Popup via the URL

  • DATA: url  TYPE string.

  data: page type string.

  page = 'F1_Help.do'.

  data:  params type tihttpnvp.

  field-symbols:

I have tried to share this solution in considerable detail. I know that many people in the BSP community have developments such as this. They have reusable code (possibly in the form of BSP extension elements) that forms useful low level objects. I am hoping that others in the community will share their developments as well. I am interested if there was some way that we, as the SDN Community, could start some sort of code exchange for these types of elements. Perhaps long term there is even a way for the community to enhance and maintain such shared objects.

5 Comments