Quantcast
Channel: SCN : Blog List - Web Dynpro ABAP
Viewing all 107 articles
Browse latest View live

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

 

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

Ready for our One Digital Experience (1DX)?

$
0
0

You have probably already heard the hype about the new community we are all moving to. SAP has overhauled and improved the things that concern you - while adding important components to our ONE Digital Experience (1DX) vision. The new community will include:

 

  • A more robust blogging solution
  • A friendlier approach to questions and answers
  • More extensive moderation with advanced features
  • Gamification that rewards quality over quantity


And that's just a taste of what's to come!

If you haven’t already done so, go and check out the beta version. You can familiarize yourself with the new look and give your honest opinion.


http://go.sap.com/community/beta.html


The 1DX goal is to give SAP's audiences - the customers, partners, and developers who comprise our community - what they need and when they need it. That means our move to a new best-of-breed community platform will always put your needs first. You will be able to use any mobile device to collaborate, engage, network, and access relevant SAP community content.

 

Hope to see you all in the new environment!

SAP Screen Personas for Web Dynpro ABAP - Cross Session Scripting

$
0
0

Introduction

 

With SAP Screen Personas there is now the option to add client-side scripting to existing Webdynpro for ABAP applications. For a first introduction to scripting please have a look at the Overview Blog of Matthias Heitmann.

With scripting it’s now possible to automate re-occurring or complex tasks. However there is a technical restriction: The script is always tied to the (technical) application. There is no possibility to define a script, which runs across different applications or even different browser windows. This heavily limits the applicability of scripting for automation.

Even worse is the fact, that there exists a lot of applications which are running in 2 windows – technically these are 2 instances of the same application. Such applications can’t be automated. Examples are basically all FPM applications based on the OVP Floorplan, which are using the Initial screen feature. A typical example is the demo application S_EPM_FPM_PD:

s_epm_fpm_pd.png

This application consists of an initial page, allowing you to search for products and a main page where single products are displayed and edited. By clicking a product name in the search result list, the application will launch the main page for this product in a separate window.

Now let’s assume we want to add a “discount” feature to this application – the user shall have the option to reduce the price of the selected products by a certain percentage. With the standard functionality this is a bit cumbersome: For each product to be discounter the user has to

  1. Click the product name
  2. Wait for the new window to be opened
  3. Press the ‘Edit’ button in the new window
  4. Change the Price
  5. Press ‘Save’

Much easier for the user would be a solution where there is a ‘Discount’ button on the initial screen. After clicking this button an input dialog would appear where the user can enter the percentage value and on closing this dialog everything else will be done automatically.

With a single script automation isn’t possible. Nevertheless since SAP_UI 7.50 SP03 there is a mechanism in place allowing to solve such tasks.

 

Concept

 

The idea is simple: Instead of enabling scripts to run in 2 windows, Personas now offers the possibility to

  • start a script in the first session,
  • and specify a follow-up and a completion script when navigating to the 2nd window.
  • When the 2nd window is launched the follow-up script will be executed and
  • On completion of the script in the 2nd window the completion script will be executed in the first window

 

Example

 

I will now show and explain the scripts needed to add such a discount functionality to demo application S_EPM_FPM_PD.

We will need 3 scripts:

  1. A start script which will prompt for the discount rate and then trigger the discounting for all selected products
  2. The follow-up script which will be executed once for each product on the application’s main page. This script will calculate, change and save the new product price
  3. The complete script which will restart the search, to show the updated values

 

 

Start Script

 

//Determine number of visible rows (this script will only work on visible values)
var visibleRowCount = session.findById("EPM_PD_OVP_SEARCH_LIST_CFG.00.LIST_VIEW.DYNAMIC_TABLE").visibleRowCount;
var rowCount = session.findById("EPM_PD_OVP_SEARCH_LIST_CFG.00.LIST_VIEW.DYNAMIC_TABLE").rowCount;
var firstVisibleRow = session.findById("EPM_PD_OVP_SEARCH_LIST_CFG.00.LIST_VIEW.DYNAMIC_TABLE").firstVisibleRow;
var visibleRows = Math.min(visibleRowCount,rowCount-firstVisibleRow);
//If there are no visible rows return
if (visibleRows == 0) {         session.utils.alert("No products selected!");          return;  
}
//Create a followup object, which will be passed to the next browser session
var followup = {scriptId:"wnd[0]/scrptPersonas_1"};
//Prompt for the discount rate and store it in the followup object

followup.parameters = session.utils.prompt("Enter discount rate: ","5");
//Check if user entered a valid value
if(followup.parameters==null || isNaN(followup.parameters)==true) {
         session.utils.alert("Discount value is not a valid Number!");          return;
}
//Loop for all visible rows and click the product name link
for(var i=firstVisibleRow;i<firstVisibleRow+visibleRows;i++) 
{         if (i==firstVisibleRow+visibleRows-1) {                   //When the last selected line is processed, specify the complete script                   followup.onCompleteScriptId = "wnd[0]/scrptPersonas_2";         }         //Click the product name and pass the followup object         session.findById("EPM_PD_OVP_SEARCH_LIST_CFG.00.LIST_VIEW.PRODUCT_NAME_FPM_CE[" + i +"]").Activate( false, false, followup);
};

In line 14 the followup object is created which is used to pass the name of the followup and the complete script, as well as the input parameters of the followup script to the next session.  In line 34 the navigation is triggered and the followup object is passed

 

Follow-up Script

 

var discountRate = 5;
//Check if discount rate has been passed, if not prompt the user. This makes it possible to 
//run and test the script standalone
if(typeof followUpParameter === 'undefined' || followUpParameter === null)          discountRate = session.utils.prompt("Enter discount rate: ","5");
else     discountRate = session.utils.parseFormattedNumber(followUpParameter); 
debugger;
//Switch to Edit Mode
if (session.findById("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_FPM_EDIT_1").enabled)                   session.findById("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_FPM_EDIT_1").Press();
//Get the current price
var priceString = session.findById("EPM_PD_OVP_HEADER_FORM_CFG.00.V_FORM.FGRP_12").value;
//Calculate new price...
var priceNumber = session.utils.parseFormattedNumber(priceString);
priceNumber = (100 - discountRate) * priceNumber / 100;
//round price to 2 decimals
priceNumber = Math.round(100*priceNumber)/100;
var newPriceString = session.utils.getFormattedNumber(priceNumber);
//...and write it back to the price input field

session.findById("EPM_PD_OVP_HEADER_FORM_CFG.00.V_FORM.FGRP_12").value = newPriceString;
// save
session.findById("S_EPM_UX_PD_OVP.00.PAGE_HEADER.FPM_CA_TOOLBAR_SAVE").Press();



Complete Script

 

//After all prices have been updated re-execute the search to see the discounted 
//prices in the result list

session.findById("FA35119EB8954786093E7A3C90C71FB8.07.V_SELECT_OPTIONS.BTN_SEARCH").Press();

 

After creating the 3 scripts there is only one thing missing: We have to add a Script Button to start the first script

css.png

Summary

By passing follow-up script names when navigating to another application, it's possible now to automate processes across different applications with Personas Scripting. This is especially helpful for all those applications starting with a search result list, where the object is edited in a seperate browser window or tab.

Code Snippet Series: Determining the Application Name

$
0
0

This post is part of a series on code snippets. The complete list of posts in the series is available in the document Code Snippets: A Blog Series.

 

Knowing the name of a Web Dynpro ABAP application can be useful if you want to branch logic or show or hide content depending on the variant of an application. An example is including on-screen hints and help content when the application is a normal end-user variant of the application but omitting such content when the application is an "expert" variant.

 

DATA lo_controller TYPE REF TO if_wd_controller.
DATA lo_component TYPE REF TO if_wd_component.
DATA lo_application TYPE REF TO if_wd_application.
DATA lo_application_info TYPE REF TO if_wd_rr_application.
DATA lv_name TYPE string.
lo_controller = wd_this->wd_get_api( ).
lo_component = lo_controller->get_component( ).
lo_application = lo_component->get_application( ).
lo_application_info = lo_application->get_application_info( ).
lv_name = lo_application_info->get_name( ).
CASE to_lower( lv_name ).    WHEN 'expert'.           WHEN OTHERS.                
ENDCASE.


If you are on a version of NetWeaver that supports chaining method calls (NW 7.0 EhP 2 or higher), you may skip declaration of some or all of the object references.


DATA lo_application TYPE REF TO if_wd_application.
DATA lv_name TYPE string.
lo_application = wd_this->wd_get_api( )->get_component( )->get_application( ).
lv_name = lo_application->get_application_info( )->get_name( ).
CASE to_lower( lv_name ).    WHEN 'expert'.    WHEN OTHERS.        
ENDCASE. 


CASE to_lower( wd_this->wd_get_api( )->get_component( )->get_application( )->get_application_info( )->get_name( ) ).    WHEN 'expert'.           WHEN OTHERS.
ENDCASE. 


Viewing all 107 articles
Browse latest View live


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