Quantcast
Channel: Web Dynpro ABAP
Viewing all 141 articles
Browse latest View live

Some Simple Innovative Ways - Upload files to content server from WDA

$
0
0

Sometimes negotiating on a standard solution with the customer is like waving a red flag to a bull,  "Consultant proposes, Customer Disposes" had become a norm in my recent endeavours. Few at times, there is good reason behind their intransigence, but more often than not it is display of effrontery to say that was is there is the best and should continue, but hidden behind the veil is the resistance towards any kind of change.

 

Rather than pressing your point home, it is better to give in and get things going beofore customers says my way or the highway . We advocating use of HCM processes and forms to standardize all their HR processes did not get their buying. Firstly, they wanted the look and feel exactly as it was and also the functionality, one major bone of contention was to have file upload at different sections in the form as each section will be used by different stakeholder, the standard HCM processes and form framework would not offer such an option as all the attachments are available in only one section at the top, and also then flexibility of making certain attachment available for certain groups is not an option.

 

In this blog I shall describe how to incorporate file uploads in different sections and load it to the content server, a prequisite being that the content server is configured by doing the basic customizing for the archivelink. if you are unware, then just take a note of the below steps.

 

1. Create a content repository - here you create a content repository id along with other parameters.

 

Contrep1.JPG

Enter the required details related to the content server.

contrep2.JPG

 

2. Create a document type and use the document class as * so that you can use any document type.

document.JPG

 

 

3. Now link the object type, document type, and the content repository using the below customization view.

Enter the other details as required.

LinkDocs.JPG

4. Also, ensure that during storage the document type is not copied from document class. Keep the below box unchecked in the customizing.

storetype.JPG

 

Once you are done with these quick settings, it is time to a develop a small WDA reusable component. This particular component shall then be placed in different sections of the main component. But before we start to develop WDA we need to small spade work of designing the table to store the required document data.

 

Design the table to store the following as shown below.

1. The section field is used to identify from which section the document got uploaded

2. The document ID is returned by the archive link after loading the document, it uniquely identifies a document.

3. The unique process id is used here because every form when submitted would give a unique process id, thus we can link the uploaded documents to unique form and sections in the form.

4. File type is the file extension, it needs to be capture as this wll be used while trying to open the document from WDA.

5. Store the file name also

table.JPG

6. Now create a web dynpro component with a very simple view consisting of a upload UI and table UI to display uploaded document details and also delete if not required.

Uploadview.JPG

On the load action of the file use the CALL FUNCTION 'CH_SPLIT_FILENAME' to split file name and mimetype so that it can be captured in the z-table.

Then store the read content into the content server by calling  ARCHIV_CREATE_TABLE


load_fm.JPG

Store the  ls_output-arc_doc_id in the ztable, this is an unique reference to the document store in the content server, this id will help us to retrieve the document back.


Now, on the other hand to open the uploaded file, you can create a handler action to fetch the file and open as a response. Use the FM CALL FUNCTION 'ARCHIVOBJECT_GET_TABLE' as shown below passing the unique document reference number that was generated and stored in the previous step.

down_fm.JPG

You might need to get the correct mime type to be passed to the browser using the  below FM and a little bit tweaking using a conversion class to correct the binary information. If you don't use the conversion class you might not be supporting xlsx type files and end up getting error while opening the file, though the file ultimately opens.

 

sdok.JPG

 

then a bit of coding to attach to response and the file shows up on the browser.

last_step.JPG

 

Apart from these, you might need to have some interface methods in the component controller to communicate with the parent component, the one of particular importance is the set data method(see below screen shot). This method gets information from the parent component, which helps it to uniquely identify the files that belongs to the process, the section and also store information of the files in the z-table. You can have other interface methods if you need further manipulation of the child component.

interfacmeth.JPG

 

methdetails.JPG

Below image you can see how the upload component in used in different sections of the same form.

demo.JPG

 

This is a normal scenario you would come across and I hope this blog will be quite useful at that time .

 

Thanks for reading and your comments are welcome.

 

Raghav.


Creating Simple WebDynpro ABAP using Contextual panel

$
0
0

Follow the below step to create an simple WebDynpro Application using Contextual Panel UI

 

Step 1: Goto T-code : SE80

Step 2: Create New WebDynpro Component "ZCONTEXT_PANEL"

wda-c.jpg

Step 3:  After creating component activate the entire Component and controllers. In view, insert Contextual panel UI element

wda-2.jpg

wda-3.jpg

Step 4: Insert view switch element inside contextual panel element

wda-4.jpg

wda-5.jpg

Step 5: Insert free contextual panel to insert other UI element

wda-6.jpg

wda-7.jpg

Step 6: Insert text view in free contextual area

wda-8.jpg

wda-9.jpg

Step 7: Create another contextual panel

wda-10.jpg

Step 8: Insert free contextual area in second contextual panel

wda-11.jpg

Step 9: Insert transparent container inside free contextual area

wda-12.jpg

Step 10: Insert two transparent containers inside main transparent container

wda-13.jpg

Step 11: Insert text view in both transparent containers

wda-14.jpg

Step 12: Create Two Nodes as below

Node1 ‘REP

                Attribute ‘REP’ type String

Node2 ‘VISIBILITY

                Attribute ‘FIRST’ type Boolean

                Attribute ‘SECOND’ type Boolean

wda-15.jpg

Step 13: Bind REP node in Item source properties of view switch element and Bind REP attribute in item text properties of view switch element

wda-16.jpg

Step 14: Create method ‘SHOW’for view switch element

wda-17.jpg

Step 15: Bind the attribute first from visibility node  to the visibile properties of tc_first element and Bind the attribute Second from visibility node  to the visibile properties of tc_second element

Step 16: Use below Code in WDDOINIT

 

METHOD wddoinit .
DATA : lo_nd_reports      TYPE REF TO   if_wd_context_node.
DATA : lo_nd_visibility   TYPE REF TO   if_wd_context_node.
DATA : ls_reports         TYPE          wd_this->element_rep.
DATA : lt_reports         TYPE          wd_this->elements_rep.

* Default Graph Show
lo_nd_visibility = wd_context->get_child_node( name = wd_this->wdctx_visibility ).


lo_nd_visibility->set_attribute( name =
'FIRST' value = abap_true ).
lo_nd_visibility->set_attribute( name =
'SECOND' value = abap_false ).

lo_nd_reports = wd_context->get_child_node( name = wd_this->wdctx_rep ).

* Setting the Drop Down & Other Values
ls_reports-rep =
'FIRST'.
APPEND ls_reports TO lt_reports.

ls_reports-rep =
'SECOND'.
APPEND ls_reports TO lt_reports.


lo_nd_reports->bind_table( lt_reports ).

ENDMETHOD.


Step 17: Use below code in Method SHOW

METHOD onactionshow .

DATA  lo_nd_reports     TYPE REF TO   if_wd_context_node.
DATA  lo_nd_visibility  TYPE REF TO   if_wd_context_node.
DATA  ls_visibility     TYPE          wd_this->element_visibility.

lo_nd_reports = wd_context->get_child_node( name = wd_this->wdctx_rep ).
lo_nd_reports->set_lead_selection_index(
index = index ).
lo_nd_visibility = wd_context->get_child_node( name =
'VISIBILITY' ).

IF index = 1.
ls_visibility-first   =  abap_true.
ls_visibility-second    = abap_false.

ELSEIF index = 2.
ls_visibility-first   =  abap_false.
ls_visibility-second   =  abap_true.

ENDIF.

lo_nd_visibility->set_static_attributes(
EXPORTING static_attributes = ls_visibility ).
ENDMETHOD.

 

Output

 

Second panel result will be display based on action taken in first contextual panel

wda-18.jpg

Get the selected record from Business Graphic

$
0
0

Below Steps will help to get the selected record from Business Graph

 

1. Create an WebDynpro Component, View, Window and application

1.JPG

2. Create context node and attribute as below in View. String type for all the attribute

9.JPG

3. Create Business graph, bind the series and create on Action as below

3.JPG

4. Create Category and bind the property as below

4.JPG

5. Create Series and bind property as below

5.JPG

6. Create Text view to display selected Employee Number

6.jpg

7. Populate the code as below in WDDOINIT

7.jpg

8. Create EVENT_ID parameter in EMP Event handler

8.jpg

9. Populate the below code in EMP Event handler

9.JPG

 

Output

Before selecting on Chart

o1.JPG

After Selecting on Chart, selected part will be marked and the employee number will display below

O2.png

 

Regards,

Manikandan S

How to read the data from a filtered table in SAP Web Dynpro ABAP

$
0
0

Hi welcome !!!

 

I would like to share the code/logic of method GET_TABLE_DATA of interface IF_WD_TABLE_METHOD_HNDL which helps to read the data from a filtered Table in Web Dynpro ABAP.

 

I have come across few SCN threads where in the requirement for reading filtered table data is left unanswered, as the method GET_TABLE_DATA( ) is not available in interface IF_WD_TABLE_METHOD_HNDL in their systems. I think the method GET_TABLE_DATA is available from SAP_ABA 731.

 

So, it might be useful if the logic to read the data from a filtered table is available for all.


Pre-requisite:

Basic knowledge of Webdynpro ABAP,& OO ABAP

 

 

Create below method.

 

 

GET_TABLE_DATA( )

Parameters:

IO_TBL Importing type ref to CL_WD_TABLE
RT_DATA Returning WDR_TABLE_ROW_DATA_TAB



METHOD get_table_data.

 

DATA elements         TYPE wdr_context_element_set.  DATA element          TYPE REF TO if_wd_context_element.  DATA row_data         TYPE wdr_table_row_data.  DATA last_row_index   TYPE i.  DATA first_row_index  TYPE i.  DATA wd_row_arrangement_type_id TYPE guid.  DATA wd_row_arrangement         TYPE REF TO cl_wd_view_element.  DATA first_actual_row TYPE i.  DATA fixed_row_count  TYPE i.  DATA data_source      TYPE REF TO if_wd_context_node.  DATA row_count        TYPE i.  DATA selected_elements TYPE wdr_context_element_set.  DATA first_row        TYPE i.  DATA last_row        TYPE i value -1.  CONSTANTS c_none TYPE guid VALUE ''.  CLEAR rt_data.  CLEAR selected_elements.  row_count = 0.  IF data_source IS NOT BOUND.    data_source = io_tbl->get_data_source( ).  ENDIF.  wd_row_arrangement ?= io_tbl->get_row_arrangement( ).  IF wd_row_arrangement IS NOT BOUND.    wd_row_arrangement = io_tbl->get_master_column( ).  ENDIF.  IF wd_row_arrangement IS BOUND.    wd_row_arrangement_type_id = wd_row_arrangement->_cid.  ENDIF.  fixed_row_count = io_tbl->get_row_count( ).  first_actual_row = io_tbl->get_first_actual_row( ).  CASE wd_row_arrangement_type_id.    WHEN c_none.      selected_elements = data_source->get_selected_elements( ).      IF fixed_row_count = -1.        row_count = data_source->get_element_count( ) +
first_actual_row.      ELSE.        row_count = fixed_row_count.      ENDIF.      first_row_index = first_row - first_actual_row.      IF last_row = -1 OR         last_row > row_count.        last_row_index = row_count - first_actual_row.      ELSE.        last_row_index = last_row - first_actual_row.      ENDIF.      IF last_row_index >= first_row_index.        elements = data_source->get_elements( from = first_row_index
to = last_row_index ).      ENDIF.      LOOP AT elements INTO element.        row_data-context_element = element.        row_data-level           = 0.        INSERT row_data INTO TABLE rt_data.      ENDLOOP.  ENDCASE.

ENDMETHOD.

 

Let us say, we have created the above method GET_TABLE_DATA in component controller of WD component.

 

Please refer to the below steps to read data from a filtered table

 

Steps:

  • Go to attributes tab of view and create an view attribute GO_TBL of type ref to CL_WD_TABLE
  • Go to method WDDOMODIFYVIEW( ) and write the below logic to get the reference of table ui element "MY_TABLE"
METHOD wddomodifyview .           IF first_time = abap_true.               "Note: my_table is the ui name of table in view layout               wd_this->go_tbl = view->get_element( 'MY_TABLE' )           ENDIF.
ENDMETHOD.
  • Now, to read data from filtered table, use the below code
   data lt_data type WDR_TABLE_ROW_DATA_TAB.                  wd_comp_controller->get_table_data(                    exporting                         io_tbl = wd_this->go_tbl                    receiving                         rt_data = lt_data ).

 

Thank you for your time and hope content of this blog was helpful.

 

Your comments / Feedback / suggestions are highly appreciable & always welcome

Dynamic Progress Bar Creation in Web Dynpro ABAP

$
0
0

This document will help you to understand the concept of Dynamic Progress Bar in Web Dynpro ABAP.


Create Web Dynpro Component and create a node with the cardinality of 1.1 and add an attribute with the type of ‘I’


Untitled.png

In the View Create two UI elements Timed trigger and Progress indicator and create an action for timed trigger and set the delay how much ever you want here I am setting as 1 and bind the same attribute(here BAR) in progress bar's Display and percent Value.

 

The event that we are declaring here will get called once the delay time is reached.

 

Untitled1.png

 

Code in the trigger event:


METHOD onactiontrigger .

 

  DATA lo_nd_progress TYPE REF TO if_wd_context_node.

  DATA lo_el_progress  TYPE REF TO if_wd_context_element.

  DATA ls_progress      TYPE        wd_this->element_progress.

  DATA lv_timer           TYPE        wd_this->element_progress-bar.

 

  lo_nd_progress = wd_context->get_child_node( name = wd_this->wdctx_progress ).

  lo_el_progress = lo_nd_progress->get_element( ).

 

lo_el_progress->get_attribute(

  EXPORTING

    name =  `BAR`

  IMPORTING

    value = lv_timer ).

 

  lv_timer = lv_timer + 3. "Incrementing the value after each delay set as 1.

 

  lo_nd_progress = wd_context->get_child_node( name = wd_this->wdctx_progress ).

 

  lo_el_progress = lo_nd_progress->get_element( ).

 

lo_el_progress->set_attribute(

  name =  `BAR`

  value = lv_timer ).

 

  IF lv_timer = 100.

 

       wd_this->fire_to_next_plg( ).

 

  ENDIF.

 

ENDMETHOD.


Create an application and activate the whole component.

Untitled2.png

- Gowtham

Short employee profile in MSS

$
0
0

Hi

 

I would like to overview about  configurations  required for  'Employee short profile ' in MSS. Employee short profile is basically used to display employee profile on one click with a separate window when manager wanted to see the employee profile  .

 

 

1 . Each short profile is associated with one category   .category can be  created in below view .

 

Create category -  view - V_T77TMCDRCAT

 

2. For each category map the required fields on short profile . use below view .

 

Create fields for category - V_T77TMCDRFLDS -

 

Ex: if short profile must have Employee Group , Employee Status , Hire Date , Org Unit , Personnel Area , Personnel  Subarea , Home Phone , Position.

 

All these must be assigned with category in the view . V_T77TMCDRFLDS


3. Create configuration ID - View : HRTMC_VC_CONF_GRP

 

 

 

   Create configuration ID using the view and Create fields to be associated .

How to dynamically bind a data node to a Web Dynpro ALV

$
0
0


Most WebDynpro ALV tutorials show you step by step how to import and setup an ALV component into your project. Add the ALV component to the list of used component in the COMPONENTCONTROLLER properties and add this usage to the display View.


 

 

 

Embed the TABLE View from the ALV component usage into your display View.



And then setup the data to be used by binding a node from the component context to the DATA node in the ALV component  INTERFACECONTROLLER.


 

Admittedly, this is probably the simplest, most direct way of introducing this process; statically defining the binding of the data node. And, not having conducted a poll myself, I would venture to say that for most implementations this is sufficient.

 

But there is always that one time, that one time where you need to be able to assign and/or reassign that binding at run time. That one time when it is not known at design time which node will be displayed. It may be dependent on user input or data selection or whatever. The point is that you need to dynamically bind a data node to the ALV.

 

Well, fear not, here’s how it’s done.

 

In a recent project I needed to display the same set of data at different granularity based on the user’s selection. There are two buttons for the user to choose: one displaying the data as a summary and the other combining it with more detailed line item type data for a more denormalized view. In any case, here’s how I approached it.

 

First, skip the last step above where the binding is done.


 

In the VIEW where the ALV is displayed I created a method called SET_DATA_MAPPING. This method takes in a parameter of type IF_WD_ACTION and gets called from the WDDOBEFOREACTION hook method which supplies the value for the ACTION that was triggered thru a reference to the view controller.


 

Based on the value of the action, I get the child node from the context that represents the data to be displayed. Then, get a reference to the ALV INTERFACECONTROLLER and using its SET_DATA method pass the value of the context node and the binding is done.

 


This should be enough to now go ahead and setup the properties and display your ALV. There are also methods that handle refreshing the view after, for example, adding or removing records, but we'll tackle does in a different post.

 

Good luck!

Multiple row selection in Web Dynpro table without pressing Shift/Ctrl

$
0
0

Hello colleagues!

 

Recently I've got an issue to provide users with ability to select several lines in web dynpro table without pressing Shift or Ctrl buttons.

 

Standard WD table doesn't provide this. So I had to do some additional customization and development.

 

At first I've set selection attributes of the table as follows:

blog0101.jpg

Then I've created an action for event onSelect:

blog0102.jpg

METHOD onactionselect.

 

   CHECK new_lead_selection IS BOUND.

 

   new_lead_selection->get_node( )->set_lead_selection_index( 0 ).

 

   new_lead_selection->set_selected( boolc( new_lead_selection->is_selected( ) IS INITIAL ) ).

 

ENDMETHOD.

 

In the second line I set the lead selection off, otherwise I've got a permanent selected row in the table.

In the third line i check if the row is already selected. If yes - I deselect it, otherwise I set on the row selection.

 

The solution is quite simple but I hope It will be useful.

 

Thanks for the attention!


FPM TABBED GUIBB FOR BEGINNERS

$
0
0

hi every one in this blog i am going to show you how tabbed guibb works.

 

SCENARIO :  here tabbed guibb contains four tabs,each tab embeds one interface view of the component.however on the first tab contains the check boxes.

each check box is related to the visibility of the remaining tabs i.e if we click on the first check box TAB2 is visible or if we click on the second check box TAB3 is visible.

 

PLEASE SEE THE BELOW SCREEN SHOTS:


I USED FPM_OIF_COMPONENT.


WHEN THE COMPONENT LOADED.


18.1.jpg

 

NOW I ENABLE FIRST CHECK BOX

 

18.2.jpg

 

NOW I ENABLES ALL CHECK BOXES ONE BY ONE

 

18.3.jpg

 

NOW I DISABLE FOURTH CHECK BOX.

 

 

 

18.4.jpg

 

SO THIS IS MY REQUIREMENT LET US START.

 

WEBDYNPRO COMPONENT:  Z_DEMO_OBJECT1


IMPLEMENTED INTERFACES: 


1)IF_FPM_UI_BUILDING_BLOCK: when we add this interface automatically FPM methods (  FLUSH  - to send the data to  Central Data Model,NEEDS_FOR_CONFIRMATION  - to provide the data loss popup if data not saved ,PROCESS_EVENT - to process the fpm events,PROCESS_BEFORE_OUTPUT - to read the data to be displayed ,AFTER_FAILED_EVENT - to handle the failed events  ) are loaded in to the

COMPONENT CONTROLLER.



2) IF_FPM_TABBED_CONF_EXIT :  when we add this interface only OVERRIDE_CONFIG_TABBED method is added which is triggered after every fpm event raised.

 

                                                           


1.jpg

 

 

1.1.jpg

 

COMPONENT CONTROLLER :

 

2.jpg

 

3.jpg

 

4.jpg

 

 

CODE IN ACTIVE_FIRST_TAB:


types:
BEGIN OF ty_s_tab,
variant
TYPE string,
id TYPE string,
name
TYPE string,
END OF ty_s_tab .
types:
ty_t_tab
TYPE STANDARD TABLE OF ty_s_tab .

DATA:LV_VARIANT_ID TYPE STRING,
LT_TAB
TYPE TY_T_TAB,
LS_TAB
LIKE LINE OF LT_TAB.

CALL METHOD WD_THIS->GO_TABBED->GET_CURRENT_VARIANT
RECEIVING
RV_VARIANT_ID
= LV_VARIANT_ID.

TRY.
CALL METHOD WD_THIS->GO_TABBED->GET_TABS
EXPORTING
IV_VARIANT_ID
= LV_VARIANT_ID
IMPORTING
ET_TAB       
= LT_TAB.
CATCH CX_FPM_FLOORPLAN .
ENDTRY.

LOOP AT LT_TAB INTO LS_TAB.
IF SY-TABIX GT 1.
CALL METHOD WD_THIS->GO_TABBED->SET_TAB_VISIBLE
EXPORTING
IV_TAB_ID 
= LS_TAB-ID
IV_VISIBLE
= ' '.
CLEAR LS_TAB.
ENDIF.
ENDLOOP.

 

CODE ININITIALIZE_BOX:

 

  DATA lo_nd_check TYPE REF TO if_wd_context_node.
DATA lo_el_check type ref to if_wd_context_element.
DATA lt_check TYPE wd_this->Elements_check.
DATA ls_check TYPE wd_this->Element_check.
*  navigate from <CONTEXT> to <CHECK> via lead selection
lo_nd_check
= wd_context->get_child_node( name = wd_this->wdctx_check ).


*  @TODO handle non existant child
IF NOT lo_nd_check IS INITIAL.

do 3 times.
lo_el_check
= lo_nd_check->create_element( ).
lo_nd_check
->bind_element( new_item = lo_el_check set_initial_elements = abap_false ).

enddo.

ENDIF.

 

CODE IN OVERRIDE_CONFIG_TABBED


  DATA lv_VISIBLE TYPE BOOLE_D.
DATA lv_id TYPE string.
DATA lv_name  TYPE string.
CASE io_tabbed->mo_event->mv_event_id.
WHEN 'FPM_START'.
WD_THIS
->GO_TABBED = IO_TABBED.
wd_this
->active_first_tab(
*    lo_tabbed =                        " ref to if_fpm_tabbed
).

WHEN 'ADD_TAB'.
io_tabbed
->mo_event->MO_EVENT_DATA->get_value( EXPORTING iv_key = 'ID' IMPORTING ev_value = lv_id ).
io_tabbed
->mo_event->MO_EVENT_DATA->get_value( EXPORTING iv_key = 'NAME' IMPORTING ev_value = lv_name ).

CALL METHOD IO_TABBED->SET_TAB_VISIBLE
EXPORTING
IV_TAB_ID 
= LV_ID
IV_VISIBLE
= 'X'.
WHEN 'DELETE_TAB'.
io_tabbed
->mo_event->MO_EVENT_DATA->get_value( EXPORTING iv_key = 'ID' IMPORTING ev_value = lv_id ).
io_tabbed
->mo_event->MO_EVENT_DATA->get_value( EXPORTING iv_key = 'NAME' IMPORTING ev_value = lv_name ).

CALL METHOD IO_TABBED->SET_TAB_VISIBLE
EXPORTING
IV_TAB_ID 
= LV_ID
IV_VISIBLE
= ' '.



endcase.

 

CODE IN WDDOINIT :


wd_this->initialize_box().

 

 

VIEW CONTROLLER:


1.1.jpg

 

 

5.1.jpg

 

 

5.2.jpg

 

 

 

5.4.jpg

 

6.jpg

 

7.jpg

 

CODE IN ONACTIONON_CHECK_BOX :

 

types:
BEGIN OF ty_s_tab,
variant
TYPE string,
id TYPE string,
name
TYPE string,
END OF ty_s_tab .
types:
ty_t_tab
TYPE STANDARD TABLE OF ty_s_tab .

DATA:LV_VARIANT_ID TYPE STRING,
LT_TAB
TYPE TY_T_TAB,
LS_TAB
LIKE LINE OF LT_TAB,
LV_INDEX
TYPE I.

CASE ID.
WHEN 'TABLE_CHECK_BOX_EDITOR'.
DATA: lo_fpm TYPE REF TO if_fpm,
lo_event
TYPE REF TO cl_fpm_event.


CALL METHOD CONTEXT_ELEMENT->GET_INDEX
RECEIVING
MY_INDEX
= LV_INDEX.

DATA lo_nd_check TYPE REF TO if_wd_context_node.

DATA lo_el_check TYPE REF TO if_wd_context_element.
DATA ls_check TYPE wd_this->Element_check.
DATA lv_check_box TYPE wd_this->Element_check-check_box.

* navigate from <CONTEXT> to <CHECK> via lead selection
lo_nd_check
= wd_context->get_child_node( name = wd_this->wdctx_check ).

* @TODO handle non existant child
* IF lo_nd_check IS INITIAL.
* ENDIF.

* get element via lead selection
lo_el_check
= lo_nd_check->get_element( index = LV_INDEX ).
* alternative access  via index
* lo_el_check = lo_nd_check->get_element( index = 1 ).
* @TODO handle not set lead selection
IF lo_el_check IS INITIAL.
ENDIF.

* get single attribute
lo_el_check
->get_attribute(
EXPORTING
name
`CHECK_BOX`
IMPORTING
value = lv_check_box ).



CALL METHOD WD_COMP_CONTROLLER->GO_TABBED->GET_CURRENT_VARIANT
RECEIVING
RV_VARIANT_ID
= LV_VARIANT_ID.

TRY.
CALL METHOD WD_COMP_CONTROLLER->GO_TABBED->GET_TABS
EXPORTING
IV_VARIANT_ID
= LV_VARIANT_ID
IMPORTING
ET_TAB       
= LT_TAB.
CATCH CX_FPM_FLOORPLAN .
ENDTRY.

READ TABLE LT_TAB INTO LS_TAB INDEX LV_INDEX + 1.
IF lv_check_box = 'X'.
lo_fpm
= cl_fpm=>get_instance( ).
lo_event
= cl_fpm_event=>create_by_id( 'ADD_TAB' ).
lo_event
->MO_EVENT_DATA->set_value( iv_key  = 'ID' IV_VALUE = LS_TAB-ID ).
lo_event
->MO_EVENT_DATA->set_value( iv_key  = 'NAME' iv_value = LS_TAB-NAME ).
lo_fpm
->raise_event( io_event = lo_event ).
ELSEIF lv_check_box = ' '.
lo_fpm
= cl_fpm=>get_instance( ).
lo_event
= cl_fpm_event=>create_by_id( 'DELETE_TAB' ).
lo_event
->MO_EVENT_DATA->set_value( iv_key  = 'ID' IV_VALUE = LS_TAB-ID ).
lo_event
->MO_EVENT_DATA->set_value( iv_key  = 'NAME' iv_value = LS_TAB-NAME ).
lo_fpm
->raise_event( io_event = lo_event ).
ENDIF.
ENDCASE.


8.jpg



9.jpg

 

 

10.jpg

 

11.jpg

 

VIEWS  TAB2_VIEW  -------> TAB2

              TAB3_VIEW --------->TAB3

              TAB4_VIEW --------->TAB4

 

FOR APPLICATION CONFIGURATION .

15.jpg


16.jpg17.1.jpg17.2.jpg17.3.jpg



Auto Logoff From Web Dynpro Application

$
0
0

Raindrops keep falling on my head, a beautiful song and a good metaphor to a programmers life. But if we have a sheer determination and an indomitable spirit to do something we make sure we find the wherewithal to achieve the formidable task.

 

Sitting on the edge of my seat at my workstation I managed to take a peek outside through the window, It was a wonderful view of the corniche and the vast blue expanse of the Arabian Gulf, the sun shining brightly in the clear sky striking its rays on the placid waters giving it a beautiful glitter, the ships making  delible marks on the shimmering blue canvas, while I was in a reverie I was jolted by a bolt from the blue, frankly never witnessed thundering clouds here anytime .  I heard some voices saying the users were not happy and comfortable with the NWBC HTML landing page screen on the kiosk, they wanted an ESS on Kiosk which looked like any other kiosk application and easy to navigate. I had concluded it to be a close and shut case and believed it would not raise its ugly head again, but the ball was back in my court. As always, they laid down the rules, they did not want to catch whatever we threw at them. The following were the expectations,

  • The application should have neat login screen with their logos and not the one what standard SAP throws up
  • The screen should have a pleasant look and they detested the Corbu look and feel for the kiosk application.
  • The screen should be touch screen friendly with enlarged buttons for easy navigation using back and to buttons.
  • They would like to have a logoff button to forcefully logoff from screen.
  • They also wanted an Auto logoff functionality which will automatically logoff the user after 20 seconds of inactivity and the auto logoff should prompt the user 10 seconds before logoff to make a decision to keep session or terminate session, and once logged off the logon screen should be shown.

 

I had to go back to the drawing boards and develop a simple and new application. The intention of the blog is to elaborate only on the last two points, but let me brief on the former three also. To paint a good login screen you just need to copy the class CL_ICF_NW07_LOGIN and manipulate the HTML and CSS code inside those methods and assign this class to your web dynpro ICF node. For the second point, you need to use the new theme designer /UI5/THEME_DESIGNER and copy the standard corbu, make alterations to the theme with an aesthetic touch, this can be bit tricky as you would not know SAP naming conventions, I basically tweaked around the colors and the button sizes. For the third point the only way I found to enlarge the buttons beyond a point is to embed images into the buttons, so I got a good graphic designer to design a few gif buttons representing each application and embedded those gifs.

 

To achieve the final two points I started off with an approach which had its loop holes, the basic idea was to put a triggered timer on each view of application screen where the various applications are itself either embedded as an iFrame or as an reusable component in the current application. I set the initial value of the logout time by reading the logout time set at the ICF node level, for every event in any of the application screens we reset the logout time to the initial time, and this time is set to the timed trigger, the timed trigger will check after the preset time if the time of last activity and the current time-10 seconds exceeds is the logout time limits, if yes, then it will trigger an exit plug to logoff the application and using the logoff server side java script we clear any SSO cookie.

 

But here I had hit the wall, it had a fundamental problem. Firstly, I thought, it is not a good idea to use round trips to reset time limits, but the major problem was when user started filling up the reason for leave application leisurely taking longer time than usual, and before he could submit the auto logoff triggered as it had exceeded the inactivity time when fundamentally he was not inactive but keying in the reason. I had to digest the fact that Web Dynpro ABAP will not detect any mouse clicks(other than on certain fields) and also does not detect typing, and this of course was not acceptable and entire approach collapsed like a pack of cards after days of effort.

 

It is fact that an open source developer and ABAPer cannot see eye to eye and I couldn't concur with him either, they have all the freedom to do what they want but we don't, but he did set me off thinking with his statement "Why are you using server round trips for resetting time, why don't you use java script instead?,  you can detect any kind of event using that", we abapers are averse to learning any new language we are comfortable in our coccons but javascript is a must learn as UI5 is based on it, so I decided to give this a shot like a blind shooter.

 

My initial stumbling block was to make js code to talk to web dynpro even if I managed to write some lines. Some amount of research and I felt I was hitting the right track, sometime back I had come across embedding HTML containers in WDA, and this was the beacon when treading in unknown territory. If we explore Html containers in WDA we find that there is a simple solution to this problem.

 

So this what I did, firstly create a new view in the application and create an HTML island as an element under the root container, add an HTML event and HTML script as sub elements as shown below.

HTMLBLOG.JPG

                                                      Figure 1.

 

The reset_time action method basically creates a count down timer of 10 seconds for user confirmation to logoff or to keep the session.

 

HTMLPIC2.JPG

                                                            Figure 2.

 

In the Logoff view we raise an event which will be listened by any of the current views at that point of time, so basically you will implement handler in all the views for the controller event, one of them shown below.

 

HMLb3.JPG

 

                                                                Figure 3.

 

 

The trig_logoff method just calls the exit plug of the current view to get out of the application if user confirms to logout or does not confirm anything within 10 seconds it will log him off.

Coming back to the HTML island, you would have noticed a sub-element  HTML script with source parameter zkiosk.js, this is the javascript file which detects all user events be it typing or mouse moving or clicking anywhere in the application. The script file can be loaded to application as a mime object.

 

if you notice in below table the script basically sets a timer and has a function addCallback which basically registers the events of a document to a timer function, the timer function calls a logout function when time limit expires, the Event is another name for the HTML event RESET_TIME. One more point to note is that you need to create an instance of HTML island and register the script call as shown in figure 5.

 

      

Header 3

html5.JPG

                     

script1.JPGscrip2.JPG

 

                                                                                                    Figure 4.

 

 

fig5.JPG

                                                                  Figure 5.

 

We are done with the most part of it, now we need to just embed this view in every application embedding view or else this will not function in every screen and can create issues. And a point to note, don't hide the view, if you hide the view the functionality stops working, so the only alternate way is put this view into a tray and collapse the tray and make it un-expandable, see figure 6.

figure6.JPG
                                                                Figure 6.


Now as a final piece of the puzzle we need an Java Script at the server side on the ICF node which kicks you out the Logon page again and clear all logon cookies again, this ensure that you enter userid and password again, see Figure 7.

 

figure7.JPG

                                                            Figure 7.

 

Application in action.

Logon screen.

fig8mod.jpg

 

landing screen.

fig9.JPG

 

Logout prompt after inactivity. Sorry for the typo in message

fig10.JPG

I hope this blog helps those who encounter a similar requirement, and as a last piece of information this whole thing works only in IE 10 and above, chrome also has some issues.

 

regards,

Raghavendra Prabhu

Web Dynpro ALV Configurator

$
0
0

Messy code replaced by Config Step

 

Anybody who has developed applications using SAP WD ALV component SALV_WD_TABLE, know’s how many lines of code is required to configure ALV to specific requirements. There’s getting instance of ALV model and then calling all sort of API methods to fine tune standard ALV like- sequence the columns, hide, rename the column header, set lead selection behaviors, set column width, editable ALV or not, set cell editors and many more. For complex scenarios - set cell variant, map column properties with other field value(from context).

 

 

Now think of a solution which provides an ALV configurator which can be used to do all the above configurations so that developer doesn’t have to write that boilerplate code. The whole functionality is delegated to an external application. Your ALV instance automatically adjusts itself to the values set in the configurator.

 

 

Let’s say during UAT phase of your project - user wants to re-sequence the columns and also update column headings - you just have to make changes in the configurator. This can be done by functional consultant on the project - no developer involved - no source code change.

 

 

The architecture of this solution supports abstracting the common ALV functions like - showing record count, custom excel export, etc so that they can be easily provisioned.

 

 

Here’s the overview diagram of the solution.

Arc Diagram.jpg

 

Maintenance Cycle

 

cycle diagram.jpg

 

  1. Add ALV Usage to the business application
  2. Add ZALV Usage for every ALV usage in the application
  3. Execute the application once to update Z tables with original config values
  4. Run the ZALV configurator app to override the original config values with wrapper values
  5. Transport business application components and wrapper records to UT/IT/PD

 

 

Supported Features
  • Almost all the ALV config properties mapped
  • Supports all ALV column properties
  • Supports screen resolution based adaptation ( details in next point )
  • Supports config variants that can be selected based on qualifiers - eg - role name, screen size etc. So columns shown to ROLE_A can be different from ROLE_B. Similarly, more columns can be shown for higher resolution display.
  • Supports overriding wrapper config value by run time value. Eg - retain the dynamic control of column visibility
  • Custom ALV functions (ALV Buttons) can be built in ZALV component and provisioned to consumer apps
  • ‘Record Count’, ‘Full Screen’  and 'Custom Export' functions are currently available


Design Consideration


  • Non-invasive: Original component and its ALV config code is untouched


  • Fallback: Just remove ZALV usage for easy fallback


  • Usability
    • Configurator lists the applications which uses ZALV with easy search mechanism.
    • Drop Down selectors used for the properties. Value descriptions used instead of internal values.
    • Property names are same as the one used in code for easy reference

 

  • Z Tables
    • Separate tables used for config, columns and functions.
    • CONFIG_SOURCE field is used to easily identify source of config record
    • CONFIG_SOURCE = 01 : Original Config
    • CONFIG_SOURCE = 02 : Wrapper Config

 

With all said - the implementation is of proto-type (beta) quality and not any where near to production quality. I am making this open source on GITHUB so as to involve WD ABAP community to contribute, provide feedback/suggestions and use freely.

 

Please raise github issues on the repository for better tracking.

 

You can find more details in the github repository.

techaware/wdalv_config · GitHub

Kiss of Death for Web Dynpro ABAP

$
0
0

Hi, folks!

 

Does anybody remember this great blog post Kiss of Death for Web Dynpro Java – The Follow-Up Questions? After going through the release notes of S/4 HANA 1511 I can' t help myself but thinking "History repeats itself".

 

It always starts with ESS/MSS as a playground for new UI technologies - and the beginning of the end for old ones. If the new technology doesn' t prove to be a complete failure, the old frontend passes away in a concerted action of SAP marketing, community evangelists, product management and development.


UI roadmaps are being updated, the community sphere is flooded with happiness and excitement about the new possibilities, new products are released only in the successor technology, old products are rewritten, UI roadmaps are updated again - and suddenly the grumpy old UI is extended maintenance mode.

 

So - of course no one at SAP will officially admit and there will be (not so?) violent opposition, but let' s face it: as this is exactly what happened many times before and now happens again, it' s time to say goodbye to the old days when everybody could get along with ABAP only and simply paint some web frontend in the Workbench.

 

Say hello to the new era - we' re all going to be web developers in 5 years from now.


Regards,

Thomas

SAP Screen Personas for Web Dynpro ABAP - Scripting Overview

$
0
0

Scripting in SAP Screen Personas for Web Dynpro ABAP is offered to allow primarily automation of re-occurring or complex steps. With the current release the basic functions are available to automate the current application.

 

Prerequisites

To work with the scripting features inside Web Dynpro ABAP based applications you need to have at least SAP Screen Personas 3.0 SP01 and SAP_UI 750 SP01 installed on your system – otherwise the SAP Screen Personas functions are not enabled for Web Dynpro ABAP based applications. See note 2181980 for more details on the system requirements.

 

Example

As example we use the product maintenance application from the Enterprise Procurement Model, which is part of each SAP NetWeaver installation. We enhance the application with a new button that will provide a dialog to ask the user for the new product name and will change this accordingly in the application.

 

The original application (S_EPM_FPM_PD) looks like the following:

Picture1.png

After the adjustment the screen should look like the following:

Picture2.png

I know there could be more improvements made with the layout capabilities of the Floorplanmanager as well as the SAP Screen Personas functions – but as the focus is on scripting let’s keep it as it is.

 

Start Scripting

Create a flavor and access a UI element

Each script is associated with a flavor – thus before we can create a script we need to create a flavor. After the flavor is created we leave the edit mode and switch to scripting mode. There the first action is to create a new script. The scripting engine is based on JavaScript, means nearly all JavaScript syntax can be used – however the access to some global objects may be limited.

 

The internal structure of the HTML page is controlled by the Web Dynpro ABAP and the Unified Rendering frameworks and by this the structure might change overtime to adopt changed browser behavior. To access the UI elements as seen from the framework a dedicated access is provided inside the scripting engine – do not use the standard objects inside the browser, e.g.

window

or

document

.

 

Using the global object

session

you have access to a bunch of functions built in to access the screen elements, access helping functions or use the logging. We’ll have all of them in use in the full example later on.

 

To access now a single element, e.g. the edit button you should start the inspector – this is an interactive tool which allows you to select any screen element that provides some interaction capabilities. While you hover over the element some basic information is displayed in the lower right section of the screen. Once you select the element via click the full available information for the element is shown.

Picture3.png

The inspector view shows you all available attributes and methods for the object. Attributes have an indication whether they can be changed or they’re read only. Methods are like functions and can be invoked. As we like to invoke the press function on the button we click on the icon in front of the press entry. This produces a single line of code in which the element is accessed and the method is invoked.

 

session.findById("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_FPM_EDIT_1").Press();

This line re-presents the pattern of using scripting quite well. Access the object with the

session.findById

function (the Id’s are stable) and then access either an attribute or invoke a method.

 

If you execute this script now, then the application changes into edit mode. However, if you execute the script for a second time you will see no visible change – except an error message on the Logging tab of the scripting area – this is due to the fact that the edit button is on the page but it’s inactive and as a result the press method cannot be called.

 

Initial Script – for straightforward case

Equipped with the knowledge on how to invoke actions on the UI we can complete our script to have the functionality working. The code would look like this:

 

session.findById("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_FPM_EDIT_1").Press();
var sName = session.findById("EPM_PD_OVP_HEADER_FORM_CFG.00.V_FORM.FGRP_8").value;
sName = session.utils.prompt("Enter new Product Name", sName );
session.findById("EPM_PD_OVP_HEADER_FORM_CFG.00.V_FORM.FGRP_8").value = sName;
session.findById("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_SAVE").Press();

 

The field with the ID

"EPM_PD_OVP_HEADER_FORM_CFG.00.V_FORM.FGRP_8"

is the input field for the product name – in the script we read the current value and exchange it with the input from the user – via the

session.prompt

method. This special method provides an input dialog for simple string values. For more complex inputs please use dedicated new screen elements which can be inserted via the editor.

 

Now we need to add this script to a new button on the screen to allow users to work with it. For this we quit the scripting mode and switch to edit mode. In there we add a new scripting button, place it in on the screen and assign our newly created script to it.

Picture4.png

This covers the first part of using the scripting inside SAP Screen Personas for Web Dynpro ABAP. For using such scripts in a productive environment it’s highly recommended to use logging functions and secure the script with additional checks. Please see the follow up blog for this.

SAP Screen Personas for Web Dynpro ABAP - Scripting Logging and Validation

$
0
0

Scripting in SAP Screen Personas for Web Dynpro ABAP is offered to allow primarily automation of re-occurring or complex steps. With the current release the basic functions are available to automate the current application.

 

PREREQUISITES

To work with the scripting features inside Web Dynpro ABAP based applications you need to have at least SAP Screen Personas 3.0 SP01 and SAP_UI 750 SP01 installed on your system – otherwise the SAP Screen Personas functions are not enabled for Web Dynpro ABAP based applications. See note 2181980 for more details on the system requirements.

 

Complementing a script

In the first part of the blog the initial script was created. This script is working as long as everything runs fine – if there is some obstacle the script may fail at any point, e.g. the user has no edit rights. This should be prevented to not impact the user experience in a bad way.

 

There are two parts which should be added:

  • Validation of the environment, e.g. is a button available and enabled
  • Logging of the steps

 

The first part will ensure your script can handle unforeseen situations and the second part will make the support later on easier as meaningful information is either being put into the logging section of the scripting view or into the browser console.

 

Validation can be added using the attributes of the UI elements, e.g. the enabled attribute or other states which are available. All of these Boolean attributes work as true Boolean values in the scripting – means they can directly be consumed in if clauses. Additionally, the session object has a method idExists– which works much like the findById but instead of giving back the UI element it returns a true/ false whether an element with the given id is currently available.

Logging can be added using the session.utils.log method. This method expects a string message and a severity.

 

Applying validation and logging to our script it will look probably like this:

 

// UpdateProductName script

// log some information about the environment
var sEnvironmentInfo = "User: " + session.info.user + " started UpdateProductName script on server: " + session.info.applicationServer + ", client: " + session.info.client + " in application: " + session.info.applicationConfigId;
session.utils.log( sEnvironmentInfo, session.utils.LogLevel.INFO);

// check for all needed elements
if (!session.idExists("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_FPM_EDIT_1") ||
   !session.idExists("EPM_PD_OVP_HEADER_FORM_CFG.00.V_FORM.FGRP_8") ||   !session.idExists("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_CANCEL") ||   !session.idExists("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_SAVE")) {    session.utils.log("Not all needed UI elements are on the page - exit processing");    return;
}

// buffer elements for later usage
var oEditButton = session.findById("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_FPM_EDIT_1");
var oInputField = session.findById("EPM_PD_OVP_HEADER_FORM_CFG.00.V_FORM.FGRP_8");
var oCancelButton = session.findById("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_CANCEL");
var oSaveButton = session.findById("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_SAVE");

// try to switch to edit mode
if (!oEditButton.enabled) {
      session.utils.log("Edit button not enabled");      return;
}

oEditButton.Press();

if (oEditButton.enabled) {
      session.utils.log("Switch to edit mode failed");      return;
}
// check if input field is available
if (!oInputField.enabled || oInputField.readOnly) {      session.utils.log("Input field for product name not open for changes");      return;
}

var sOldName = oInputField.value;
session.utils.log("Old Poduct Name: " + sOldName, session.utils.LogLevel.INFO);

var sNewName = session.utils.prompt("Enter a new product name", sOldName);
// check for user cancel action or not changed values
if (sNewName === null || sNewName === "" || sNewName === sOldName) {
      session.utils.log("Input canceled by user or name not changed", session.utils.LogLevel.INFO);      if (oCancelButton.enabled) {            oCancelButton.Press();      } else {            session.utils.log("Cancel button not enabled")      }      return;
}

// update product name
session.utils.log("New Product Name: " + sNewName, session.utils.LogLevel.INFO);
oInputField.value = sNewName;
if (oSaveButton.enabled) {
      oSaveButton.Press();
} else {     session.utils.log("Save button not enabled");     return;
}

// after save validation
if (!oSaveButton.enabled) {
      session.utils.log("Data saved", session.utils.LogLevel.INFO);
} else {      session.utils.log("Changed data could not be saved");
}

The log output after a run from the scripting view.

Picture5.png

In case the script is not running from the scripting view the messages could be found in the browser console instead.

 

Conclusion

Scripting inside SAP Screen Personas for Web Dynpro ABAP offers quite some capabilities for automation – however for more complex scenarios the development of scripts is very similar to application development.

 


SAP Screen Personas for Web Dynpro ABAP - Text Changes

$
0
0

Prerequisites

To work with the SAP Screen Personas features inside Web Dynpro ABAP based applications you need to have at least SAP Screen Personas 3.0 SP01 and SAP_UI 750 SP01 installed on your system – otherwise the SAP Screen Personas functions are not enabled for Web Dynpro ABAP based applications. See note 2181980 for more details on the system requirements.

 

Example

As example we use the product maintenance application from the Enterprise Procurement Model, which is part of each SAP NetWeaver installation. We’ll change a couple of texts in the application in order to meet our understanding.

 

The original application (S_EPM_FPM_PD) looks like the following:

Picture1.png

After the adjustment the screen should look like the following:

Picture2.png

I know that such changes as well can be made using the SAP Floorplan Manager based tools – however I’d like to show the capabilities of SAP Screen Personas for Web Dynpro ABAP in this example.

 

Adjusting Texts

All changes in SAP Screen Personas are associated with a flavor – this we start with the creation of a flavor using the flavor bar on top of the screen. To start the flavor bar click on the blue P on top of the screen - if this is not visible for you, you need to have additional authorisations to use SAP Screen Personas.

Picture3.png

At this point in time the application is set into a design mode where all objects can be accessed but the normal application functions, e.g. input of values are deactivated – additionally the SAP Screen Personas editor is shown on the top of the screen.

 

The editor hosts all functions which are available inside SAP Screen Personas with one note able exception – the change of the text. To change the text of an element the element has to be double clicked.

Picture4.png

If the element allows the change of the text a popup window appears in which the text can be changed – the change will be recorded in the current language only. After the change the flavor needs to be saved to see the changed texts later in the running application.

 

To enable the changed texts in other languages too – SAP Screen Personas offers a translation tool for changes made with SAP Screen Personas inside the administration tools. These tools can be reached in the SAP Screen Personas backend system with transaction code /PERSONAS/ADMIN.


Dynamic SALV table with a mix of DDIC and manual columns

$
0
0

I've been working recenlty on a business requirement that involved creation of a mix of some predefined columns and a number of period columns determined by selection criteria - so they could easily be modified (From/To).

 

And it would seem you have a number of options to create a SALV_WD_TABLE structure for a dynamic table, yet every had some drawbacks.

 

You could either use a DDIC structure reference for the static fields described here: https://scn.sap.com/thread/3245460

This is done by passing the structure name:

wd_context->get_node_info( )->add_new_child_node(
name  = 'NODE_NAME'

static_element_type = 'DDIC_NAME'

...)

The pros of this is you get all the DDIC bonuses in your column/cells like F4 help, edit masks and such. The drawback is that if you later loop over the node to dynamically add more columns, they don't seem to be linked to values in the SALV data model, so the cells are always empty.

 

A workaround for that problem would be to rather pass an RTTI structure description of the dynamic table (already with the extra columns for periods), but then you loose a lot of the DDIC information like edit mask, because the attribute structure is a bit short.

lr_nd_info         = wd_context->get_node_info( )->add_new_child_node(

name                   = 'DATA'

static_element_rtti    = lr_structdescr               "RTTI structure

...)

 

I did search a lot, but couldn't find a good solution, so eventually I tried the hard way by checking the code and different parameters, and what I ended up is using the attributes parameter like so:

ls_attrib-name = 'WBS_ELEMENT'.

ls_attrib-value_help_available = abap_true.

CONCATENATE if_wd_value_help_handler=>co_prefix_searchhelp ':' 'PRP' INTO ls_attrib-value_help_id.

ls_attrib-value_help_mode = if_wd_value_help_handler=>co_prefix_searchhelp.

ls_attrib-value_help_type = if_wd_value_help_handler=>co_vh_type_backend.

ls_attrib-rtti ?= cl_abap_datadescr=>describe_by_name( p_name = 'PS_POSID' ).

INSERT ls_attrib INTO TABLE lt_attribs.


lr_nd_info         = wd_context->get_node_info( )->add_new_child_node(
name                   = 'DATA'  
static_element_rtti    = lr_structdescr               "RTTI structure   attributes = lt_attribs ).

 

Only this way I managed to get those static columns with a sensible amount of DDIC support (value help, edit mask, column headers) and dynamic columns to properly work with the data model.

** Team WDA ** - New Features in Value Help and Value Suggest

$
0
0

Recently we implemented some new features for the DDIC value help and value suggest which we summarize here.

These comprise layout changes for our new guideline option FIORI and some long sought after customer requests.

 

If you are not familiar with FIORI, you can find an overview here:

http://scn.sap.com/community/web-dynpro-abap/floorplan-manager/blog/2015/12/08/floorplan-manager-web-dynpro-abap-a-change-of-image

 

The SAP_UI SPs mentioned in the text show the initial availability of the feature.

 

Value Help

New layout with guideline FIORI (SAP_UI 750 SP2)

 

The DDIC value help shows the filter bar layout for the selection criteria.

Advantage:

  • All search attributes are shown on open
  • Fast tabbing through the attributes
  • Single values and patterns can be entered directly
  • Complex conditions via the value help on the search attribute

 

blog_ddic_help_fiori.png

 

blog_ddic_fiori_conditions.png

 

Free text search (SAP_UI 750 SP2)

 

Prerequisites:

  • ‘Full Text Fuzzy Search’ is enabled in the DDIC value help definition
  • Database is fuzzy enabled

 

To improve the hit quality it might be beneficial to define a full text index on the search columns.
This indices can be created as customer extensions in transaction SE11.

 

Check additionally note 1861491 for DDIC information on fuzzy search:

http://service.sap.com/sap/support/notes/1861491

 

The free text search field is shown as first search attribute.

 

With guideline FIORI:

 

blog_fuzzy_fiori.png

 

With guideline GL20:

 

blog_fuzzy_gl20.png

 

Adjust number of search attributes for guideline GL20

 

For complex searches the proposed four attributes are sometimes not enough. To show more the customer can implement a BAdI to increase the number of search attributes on open.

 

blog_badi_gl20.png

 

Details can be found in SAP note:

SAP note 2271780: ValueHelp: BAdI for changing default number of selection criteria in guideline
http://service.sap.com/sap/support/notes/2271780

 

 

 

Value Suggest

New layout (SAP_UI 740 SP12)

The former layout has been replaced:

 

blog_value_Suggest_old.png

 

The new layout shows the description in several columns:

 

blog_value_Suggest_new.png

 

Fuzzy Value Suggest (SAP_UI 750 SP1)

 

Value suggest allows now fuzzy search on all search attributes without implementing a search help exit. Specific settings in the DDIC search help aren’t necessary. As before the response time of the search help must be sufficient to allow a smooth value suggest behavior.

Prerequisites:

  • Database is fuzzy enabled

 

blog_value_Suggest_fuzzy.png

 

If you are on a low SAP_BASIS SP check SAP note for required SAP_BASIS notes:

SAP note 2280929: ValueSuggest: Required notes for central TypeAhead feature
http://service.sap.com/sap/support/notes/2280929

 

 

History entries

 

On many input fields the history and the value suggest are both enabled. This might lead to confusing results since the history values are no longer shown within the value suggest table.

So far the user had to disable the history via the context menu to see all values with the description fields.

As new behavior, we now show the history entries within the value suggest table as well.

 

blog_history.png

 

This behavior is available via SAP note:

SAP note2280895: ValueSuggest: Keep History Values in ValueSuggest
http://service.sap.com/sap/support/notes/2280895

How my tables in WDA kept losing Lead Selection

$
0
0

More than once I got myself on the same scenario when developing an Web Dynpro ABAP application.

 

I would create a standard WD Table element and proceed to bind it to a context node and create a onLeadSelection method.

 

Except that when I selected a table row, instantly the screen would try to call my onLeadSelection method and fail, returning to select the first row instead.

Twice, on different applications, I had the same behavior. And it took me the same amount of time to discover what it was causing this.

 

 

The issue was very simple: I was re-binding the context node of the table!

 

On the onLeadSelection method, I was trying to update the table data, but the result of this is that the table resets the Lead Selection.

 

So, next time you cannot change the Lead Selection of a WDA table, try checking if your onLeadSelection method is not modifying the context node of the table in any way. Such as methods:

 

     lo_node->bind_table( new_items = itab ).

or

     lo_node->invalidate( ).

or

     other methods of if_wd_context_node (bind_element, bind_structure, clear_selection,... )

 

Regards,

Felipe

How to Display WDA UI Elements in Different Number of Columns

$
0
0

Usually, we have a Layout configuration that displays UI elements in a continuous row setting. On our first image below, you can see each pair of InputField and Label occupy one whole row of the Layout.

 

2016-06-07_09-32-40.png

 

In order to modify a Web Dynpro ABAP application so the UI elements are displayed in two or more columns, you should do the following:

 

1) On the relevant Web Dynpro view, you should set the parent UI element (this could be the ROOTUIELEMENT or other) of the elements you wish to display in a different number of columns to 'GridLayout' with a 'ColCount' property of the number of total columns you wish. On this example, since each InputField has a matching Label, we will set it to 4:

 

2016-06-07_09-28-08.png

 

2) Then, make sure each UI element to a 'ColSpan' property of 1. Thus, in this example the layout of the parent element will render everything with 4 columns, with each element occupying one column (each InputField and Label combination occupying two columns).

 

2016-06-07_09-30-32.png

 

Please note that if there are more elements in the same parent node, these will affect their behavior also. To reduce this modifications only to a specific set of UI elements, consider inserting them in a TransparentContainer and setting its properties as mentioned before, considering the TransparentContainer is now their parent UI element.

 

Observation: There are other ways of achieving the same results, but in my experience this seems to be the most straightforward alternative. In the future I might update this blog with different methods.

 

Regards,

Felipe

How my tables in WDA kept losing Lead Selection

$
0
0

More than once I got myself on the same scenario when developing an Web Dynpro ABAP application.

 

I would create a standard WD Table element and proceed to bind it to a context node and create a onLeadSelection method.

 

Except that when I selected a table row, instantly the screen would try to call my onLeadSelection method and fail, returning to select the first row instead.

Twice, on different applications, I had the same behavior. And it took me the same amount of time to discover what it was causing this.

 

 

The issue was very simple: I was re-binding the context node of the table!

 

On the onLeadSelection method, I was trying to update the table data, but the result of this is that the table resets the Lead Selection.

 

So, next time you cannot change the Lead Selection of a WDA table, try checking if your onLeadSelection method is not modifying the context node of the table in any way. Such as methods:

 

     lo_node->bind_table( new_items = itab ).

or

     lo_node->invalidate( ).

or

     other methods of if_wd_context_node (bind_element, bind_structure, clear_selection,... )

 

Regards,

Felipe

Viewing all 141 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>