SAP SIEMENS ABAP Documents
ABAP BASICS
ABAP Book - Reports
ABAP Book - BDCs
ABAP Book - Scripts
ABAP TRANSACTIONS
We
present the place and role of the Web Dynpro within the SAP NetWeaver
platform. So, we start with the layers of the SAP NetWeaver platform, we
continue with the importance of the Application Platform layer, and we
conclude with the place and role of Web Dynpro (ABAP and Java) within
the Application Server ABAP and, respective, Application Server Java.
As
we can see, four layers are distinguished in this context: Application
Platform, Process Integration, Information Integration and People
Integration.
The
Application Platform represents the technical basis of almost all the
other SAP products. This is the reason why the Application Platform
plays a central role in the SAP NetWeaver.
The
Application Platform essentially offers two programming interfaces:
ABAP and Java (J2EE). ABAP is the programming interface for Application
Server (AS) ABAP and Java is the programming interface for AS Java.
To
create ABAP and Java applications, we have two independent development
environments: ABAP Workbench for ABAP and SAP NetWeaver Developer Studio
for Java.
Both
development environments offer the possibility to create web based
applications built by using declarative programming techniques based on
the Model View Controller (MVC) paradigm.
SAP
NetWeaver Developer Studio is the SAP’s own development environment
used to develop Java-based multilayer business applications. This
development environment is based on Eclipse and offers a Web Dynpro
Perspective to create Web Dynpro Java applications.
All the tools we need to create Web Dynpro Java applications are found within the SAP NetWeaver Developer Studio.
SAP NetWeaver components (SAP)
SAP NetWeaver Developer Studio–Web Dynpro perspective
ABAP Workbench is the SAP’s own development environment used to develop ABAP-based multilayer business applications. This development environment offers Web Dynpro Explorer to create Web Dynpro ABAP components
ABAP Workbench–Web Dynpro Explorer
The Application Server ABAP has the structure presented.
AS ABAP (SAP)
AS ABAP (SAP)
As we can see, most of the AS ABAP components can be divided into three layers:
- Presentation layer
- Business layer
- Persistence layer
Web
Dynpro ABAP is part of the presentation layer and it’s the SAP standard
UI technology used for developing web business applications without
knowing HTML or JavaScript.
Web Dynpro ABAP offers many advantages, as follows:
- Strict separation between the layout and business data
- Re-use and better maintainability through reusability.
- Automatic input checks.
- Automatic data transport, using data binding.
- WYSIWYG (What You See Is What You Get) view editor.
Web
Dynpro ABAP and Web Dynpro Java mostly offer the same functionalities.
But, of course, there are some differences between them, for example:
- Web Dynpro Java, unlike the Web Dynpro ABAP, disposes of a ViewSet that allows us to integrate in a Screen more Views, by using certain pre-defined layouts. In this respect, their common part is the View Container UI Element.
- Web Dynpro Java offers graphical tools that ease the programming work, as:Navigation Manager and Diagram View, unlike the Web Dynpro ABAP where we dispose only of a tool used to visualize and to define the window structure.
The
Web Dynpro ABAP is what the current book is about. More information
about Web Dynpro Java can be found in the Book Inside Web Dynpro for
Java by Chris Whealy.
Abstract
This chapter presents the SAP Easy Access, highlighting some aspects
found in our everyday work. So, we show how to change the standard
settings, how to add in the Favorites list the frequently used
transactions, and how to create a Shortcut on the Desktop.
SAP
easy access starts automatically after logging-in into the SAP system.
In the left side, we can see the user menu. Here are the functions the
user needs to perform his tasks.
Changing the SAP Easy Access
U.Gellert and A.D.Cristea,Web Dynpro ABAP for Practitioners,
DOI 10.1007/978-3-642-11385-7_2, # Springer-Verlag Berlin Heidelberg 2010
We can change the SAP easy access settings through the menu Extras -> Settings,
by specifying settings as follows:
- The place of the Favorites
- The presents of the menu
- The easy access picture in the right side of the screen – to be present or not
- Displays or not the technical names
Settings
Favorites List
The
user menu is mostly defined by the administrator, but we can define our
own Favorites list. Here, we can create our own list of favorites
containing items as transaction, files, web addresses or other objects.
To add new transactions in the Favorite list, we can choose from the menu Favorites ->Insert Transactions
Inserting transaction onto the Favorites list
As a result, the new item appears in our Favorites list
Favorites list
We
can find the list of the SAP transaction codes in the transparent table
TSTC. Besides the transactions predefined in the system, we can create
our own transactions (e.g. with transaction SE93) which are going to be
inserted in this table.
Every
time we use a transaction, the system verifies in this table whether
the transaction exists and if we have the proper authorization to use
it.
As support for our daily tasks, we add here some of the transactions we use in this book
Transactions used
To add other objects, we can choose them from the menu Favorites ! Add Other Objects
Adding new objects in Favorites list
We add the web address to open the SDN page
Inserting a web address
We
can use Favorites -> Download to PC to save on our computer a list
with all the objects we have in the Favorites folder. To upload in a
Favorites folder objects from a list saved on our computer, we can use
Favorites -> Upload from PC.
Setting a Transaction as Start Transaction
We
have the possibility to set a transaction as start transaction:Extras
-> Set start transaction .In this way, the desired transaction is
automatically started after logging-in into the system (in our case the
SE80 transaction), and we don’t see the SAP easy access anymore. saved
on our computer, we can use Favorites -> Upload from PC.
Setting the start transaction dialog box
Creating a Shortcut
After
installing the SAP GUI, a SAP logon icon appears on our desktop. By
using this logon, we can login into the system. Additionally, we can
create a SAP logon shortcut to be used to perform the same logon, but we
don’t need to fill all the entries in the logon form. A SAP shortcut
allows us not only to perform a logon into the system, but to execute
other commands, too. So, we can start a SAP transaction, run a report or
perform a system command.
To
create a SAP Shortcut on our desktop to start the transaction SE80, we
can use the Wizard available in the layout menu, by clicking on the
respective icon located in the system function bar.
Creating a SAP Shortcut on our Desktop
Another
possibility to create a SAP shortcut on our desktop is to select a
transaction or another object from the Favorites list, and to use the
menu Edit -> Create Shortcut on the Desktop.
Designing a Web Dynpro Component
Abstract
The present chapter is dedicated to the constitutive elements of a Web
Dynpro ABAP component. Moreover, we show how to use the ABAP Debugger to
execute, by line or by section, a Web Dynpro application, and how to
use the new tool offered by ABAP Debugger to reach the context
attributes values.
In
order to develop a Web Dynpro ABAP component, we have to open the ABAP
Workbench of the Application Server ABAP.To work with ABAP Workbench, we
need an authorization as a developer or developer key, and for the SAP
NetWeaver ABAP trial version we can use BCUSER, automatically registered
as a developer.Web Dynpro is available with release SAP NetWeaver 2004s
and later. After logging into AS ABAP, we can use the transaction SE80
to call the object navigator.
Object navigator
All
the repository objects we develop with the ABAP Workbench tool we build
by using the Object Navigator. Here, we develop not only Web Dynpro
applications,but also other development objects (e.g.reports,database
tables, data elements,classes, function modules, etc).
The
development objects we create as customer have the first letter “y” or
“z”. Therefore, we created a Web Dynpro component with the name
y_wd_component.
We
have to assign all the development objects created with ABAP Workbench
to a package. We can use the default package “$TMP” to create test
programs without transporting, or we can create our own packages. We
choose to create our own package, named Y_WEBDYNPRO.
Creating the package Y_WEBDYNPRO
We have chosen the package type “Not a Main Package”, because this package holds development object and not other packages.
After creating the package, we create a Web Dynpro component, as follows:
right-click on the package name and, from the context menu, we select Create -> Web Dynpro -> Web Dynpro component. We have to enter the component name, a short description, the type we want to create, the view name and the window name
right-click on the package name and, from the context menu, we select Create -> Web Dynpro -> Web Dynpro component. We have to enter the component name, a short description, the type we want to create, the view name and the window name
Creating a Web Dynpro component
After saving our component, we have to assign it to our package
Assigning the component to a package
As a result, in Object Navigator we can see the Package Y_WEBDYNPRO and our first created Web Dynpro Component.
The content of our package
The
name of the development objects marked in blue are not active. After
creating the Web Dynpro component, we have to activate it.
WD component activation
Each
Web Dynpro application has at least one view. Each View has a view
Layout, where we can add different UI (User Interface) elements that can
be nested one in the other one, to create the screen. The positioning
of the UI elements in a view is realized by using the layout and data
layout.
Each
View has a view controller that is automatically created for this view
and each View has several tabs (Properties, Layout, Outbound Plug,
Inbound Plug, Attributes, Context, Actions and Methods). This indicates
that a View consist of many parts.
View Layout.
The screen content of a view is designed in the Layout tab. The View Layout is divided in three areas:
- UI element library
- View designer
- Context menus, UI elements properties and UI element hierarchy.
View Layout
the UI Elements are grouped in a library to be accessed via the View Layout. We have several ways to add an UI element into the view layout. For example:
- By right-clicking on the ROOTUIELEMENTCONTAINER
- By dragging & dropping
Adding UI elements into the view
All
the UI Elements we enter into a screen are children of the node
ROOTUIELEMENTCONTAINER and are represented as a hierarchy where
ROOTUIELEMENTCONTAINER is the top of this hierarchy. With “Swap Root
Element” we have the possibility to transform ROOTUIELEMENETCONTAINER
from a Transparent Container into another UI element (Table,
FlashIsland, Group, etc.).
In
this way, we can use, for example, the FlashIsland UI element to
integrate Adobe Flex into our web Dynpro component. This transformation
is possible only if the ROOTUIELEMENTCONTAINER doesn’t have any child UI
elements.
Adding UI elements into the view
In
our ROOTUIELEMENTCONTAINER, we insert one Group UI element, one
InputField UI element, one Label UI element, one TextView UI element and
one Button UI element
View Layout
If
we select individual UI elements in the layout of a view, their
properties are displayed in the Properties area. In this way, we can
change the properties of each element. For example, we have changed the
property design of the button UI element and the property state of the
InputField UI element.
As
a result of changing the property state of the InputField UI element
from the Normal item to the required one, the label associated to this
UI element becomes a red star and the end user knows that this value is
mandatory.
For
a property, we can create fixed character strings, we can choose from a
list, or we can bind properties to context nodes or attributes by using
the Binding button. For the text property of an UI element Button, we
have created a fixed character string “Save”. For the design property,
we have chosen from the list one of the supported designs.
UI element properties
We
need to bind the value property of the InputField UI element and the
text property of the TextView UI element. To be able to do this, we will
create two context attributes
By
using “Context Menus” we have the possibility to create, for an
application, our own context menus displayed in the Browser when the
user presses right click on an UI element. In standard mode, the web
Dynpro Framework offers the default context menus with certain
functionalities, e.g. hiding an UI element displayed into the Browser.
After running the application, we can test this standard mode by
rightclicking on the inputField UI element.
Context View
The
data are stored in the context and the UI Elements are the only objects
the user interacts with. Every View has a Context View where we can
create context nodes and attributes. Via data binding, the context of a
view controller provides a view with all the required data. For our
application, we create two context attributes named NAME and GREETING,
of STRING type.
To put the data on the screen and to read data from user, we connect the proper UI Elements properties with attributes or nodes.
In
our case, we connect the property value of the InputField UI element
with the NAME attribute. To create a greeting for the user and to show
it after the user presses the Save button, we connect the property text
of the TextView UI element with the GREETING attribute. These
connections are known as data binding.
Creating an attribute in context view
Data binding
The
effect of the binding is that, at runtime, any data changes are
transported in both directions and these changes affect all the
properties bound to this element.
Actions
Some
of the UI Elements have special events that are linked with the user
actions. The UI element Button is one of these UI elements and that’s
why we have to create an action that reacts to the user interaction. To
do this, we use the Action tab.
Creating an action
As
we can see, each action has a corresponding event handler method,
automatically generated by the Framework. An event handler method is a
special method of a view controller that has the ONACTION prefix
followed by the action name. For the SAVE action, the Framework
generates the ONACTION event handler. After creating an action, we can
assign it to an UI element that has attached an event.
Assigning an action to an UI element
After generation, this method is empty, but we can fill it with source code by using the Methods tab.
Methods
In
the Methods tab of a View, we can find some types of methods (e.g.
event handler methods, Hook methods, user-defined instance methods).
In
our case, in the Methods tab we can find the Hook methods,
automatically generated by the Framework, and our event handler method
ONACTIONSAVE
Methods tab
With double-click on the method name, we open the ABAP editor.In this way, we can insert the source code.
ABAP editor
The
user enters his name that we use to show a greeting message with the
help of textView UI element. To create a greeting for the end user, we
concatenate his name with the string “WELCOME” and we pass this string
value in the GREETING attribute. After this, we reset the inputField UI
element. To do this, we pass an empty string into the NAME attribute
bound to the corresponding UI element
On action save event handler method
METHOD onactionsave . DATA: lv_name TYPE string, lv_greeting TYPE string. wd_context->get_attribute( EXPORTING name = `NAME` IMPORTING value = lv_name). CONCATENATE ‘Welcome’ lv_name INTO lv_greeting SEPARATED BY space. wd_context->set_attribute(name = 'GREETING' value = lv_greeting). CLEAR lv_name. wd_context->set_attribute(name = 'NAME' value = lv_name). ENDMETHOD.
Properties
In
the Properties tab, we can create a description text for our view, we
have information about the view and about the person who created and
changed this view. In this tab, we can set the view lifetime:
- Framework controlled – controlled by Framework
- When visible – lifetime limited to its visibility. A view controller is always deleted as soon as the corresponding view is no longer displayed on the user interface. It is used when a view is displayed only once and not repeatedly.
Additionally, Property tab offers the possibility to define the usages .
Properties view
We
can define a usage to be able to access the methods of another internal
controller or of an interface controller, if the usage has been defined
for an external component. To create a new usage in the Used
Controller/Components table, we have to choose the Button Create
Controller Usage. The table Used Controller/ Components includes a list
with all the global controllers of our own component and, in case we
define usages, this list includes the external component and its
interface controller.
In
our case, we don’t use any external components. In the list we have
only the global controller COMPONENTCONTROLLER. We have to specify that,
for each view controller, the usage of the corresponding component
controller is automatically created.
Attributes
Each View controller contains some attributes automatically generated by the Framework
Attributes tab
The
attribute WD_COMP_CONTROLLER is a reference variable of IG_
COMPONENTCONTROLLER type that we can use to access all the publicly
accessible methods of the component global generated interface of the
corresponding component controller.
The
attribute WD_THIS is a self-reference to local controller interface.
This self-reference works similarly with the self-reference me found in
the ABAP Objects. We can use it, for example, to call a user-defined
method.
The
attribute WD_CONTEXT is a reference to the controller context. The
IF_WD_CONTEXT_NODE interface provides several methods that enable us to
obtain read and write access to a context node.
Additionally,
we can create our own attributes. These attributes are used to store
application data that are not relevant for the UI elements and we don’t
store in the context. To access these attributes, we use the
self-reference: wd_this -> attribute_name
By
default, every Web Dynpro component has a component controller that
acts as the central controller instance within the entire component
Component controller
Data
required across different views can be stored in his context. Besides
the Context tab, each COMPONENTCONTROLLER disposes of tabs: Properties,
Attributes, Events and Methods. Hereunder, in our examples, we will see
how we can cross-component access the methods and the attributes defined
here.
A
Window is an entity into which we embed all the views that will be used
to construct the screen for the end user. When the user interacts with a
view, theirinteraction will cause a request to the server. In response,
one or more views that build the current screen will require to be
replaced with other views. This is possiblethrough navigation links
among the various views in the window.
Each Web Dynpro component can have several Windows. We have created only one Window, named W_default.
A
view or several Views are generally embedded in a Window. The first
view created at the WD component creation is directly embedded into the
Window. To embed other views in a Window, we can use dragging &
dropping or right-clicking on the window name to choose between
embedding an empty view or the View we have created. The Empty View is a
special type of View, presented in the View- ContainerUIElement
example.
In
every window, at least one view is marked as default. A default view is
the first view displayed when the window is called. The first embedded
view is marked as default, but we can change it. To mark as default,
after right-clicking on the view we choose Set as default from the
contextual menu.
Embed View
By
using Inbound plugs and Outbound plugs, we define the navigation
between views or windows. For a Window, these plugs can be of Standard,
Startup or Resume type. As we can see, the Framework generates for each
window an inbound plug of Startup type and an event handler method .By
using this event handler method, we can read, for example, the URL
parameters from a Web Dynpro application.
Default inbound plug for a window
For a View, we don’t have the possibility to define a specific plug type.
After
developing a Web Dynpro component, we need to provide the users with
access to its functionality. To do this, we have to create a Web Dynpro
Application.
Creating an application
For each application, the Framework generates an URL. We find this URL in the Properties tab.
Application URL
In the same time, we can specify here how the Messages are handled:
- l Show Message Component on demand – the Message Component is displayed only when we have a message.
- Always Display Message Component – the Message Component is always displayed on the screen, even when we don’t have any messages.
By
using the Parameters tab, we can define our own parameters for the
application or we can choose from the parameters offered by the Web
Dynpro Framework.
Application parameters list
To run the application, we can use the Execute button or we can copy and past the URL into the browser.
Running the application
When
the user interacts with the screen, specific adapter techniques are
used to convert data and events, as part of the request response cycle,
into the browser format as HTML, JavaScript or XML. In Fig., we can see
the generated source code for our WD component.
Generated source file
If
any errors occur in our Web Dynpro components, we can use the ABAP
Debugger to execute our WD component, by line or by section.
To work with the debugger, we can create Breakpoints at the point where the program should pause
Setting a Breakpoint
We run the application and, in the moment when the program flow reached the defined breakpoint, the ABAP Debugger is open
ABAP Debugger
As
we can see in the Process Information, the main component of the ABAP
Debugger, we debug an HTTP application. The “Exclusive” represents the
fact that the application we debug occupies a work process of the
application server.
By
using the Buttons from the Control Area, we can control the program
flow. For Example,We can choose to execute the program line by
line-single step or to execute the program up to the next
Breakpoint.Continue.
We can use the ABAP Debugger tools to have information about the variable
Tool Component of the ABAP Debugger
By
using the New Tool Button,We can open a selection window that offers
the possibility to access additional functionalities. In the Special
Tools section, we can find the created tool, to be used for a better
debugging of the Web Dynpro components.
ABAP Debugger – New tool selection window
As
we can see in, we are offered the possibility to have access to all the
individual elements of the Web Dynpro component; we can see the view
attributes, the view layout, the UI elements and data binding, the
context structure and its attributes, etc.
The ABAP debugger – web Dynpro ABAP tool
We
are able to see not only the context structure, but also to display the
runtime object, by choosing from the contextual menu Display Runtime
Object.
Displaying the runtime object
These
are only some of the ABAP Debugger capabilities that can be used along
with other performance tools (for example, the transactions
WD_TRACE_TOOLS, S_MEMORY_INSPECTOR), to help us to develop Web Dynpro
applications.
As
we have seen, a logon page appears when running our application, where
we have to provide some values, as follows: Logon Language, Client, User
Password, etc.
Example of a webDynpro application log on page
We
can change the modality this logon page looks like and the modality we
realize the user authentication, by using the SICF transaction (HTTP
Service Hierarchy Maintenance). In the webdynpro ! sap hierarchy, each
Web Dynpro application disposes of one corresponding entry.
By using this transaction, we search for all the entries that begin with Y_WD_* and are created by our test user Gellert.
Searching for a service with the SICF transaction
We find the entry that corresponds to our created Web Dynpro component.
Entry corresponding to our Web Dynpro component
With
double-click, we are allowed to view or/and to change this service. In
the lower part of the Error Page tab, we can find the Configuration
button for the system logon. Here, we can define our own settings by
choosing from the lists, or we can use the global settings.
System logon configuration
As
a result of our changes, in the logon page we have to provide only the
User and the Password, through a popup window, and we are able to change
our logon password.
Logon page
Abstract
The following section details and describes the ABAP Dictionary.The
main purpose of this chapter is to show how to realize all the
development objects to be used in the future Web Dynpro
applications.Therefore,we present not only the modality to create the
various development objects in the ABAP Dictionary, but also the
modality to use them in realizing Web Dynpro applications.
We
can create development objects in ABAP Dictionary,by using the
transaction SE11(ABAP Dictionary Maintenance) or the Object Navigator.
Development object with transaction SE11
ABAP
programming language has a number of ten elementary data types that we
can use in our programs. When we want to create global data types by
using the ABAP Dictionary, we have to use dictionary built-in types.
These predefined types are different from the elementary data types. We
need them for reasons of compatibility with the external data types.
In
this we presented some of the ABAP Dictionary Built-In types and a few
corresponding examples of Dictionary built-in data types and
ABAPelementary types.
Some of ABAP Dictionary Built-In types and corresponding ABAP elementary types
A data element defines an elementary data type and has certain properties. We create a data element YDATEOFBIRTH
Definition of a data element
In
the “Data Type” tab we can choose between the elementary type and
reference type. The elementary type can be a domain and a build-in type.
In this case, we have chosen the build-in type DATS that has a
predefined format (YYYYMMDD) and a predefined length 8.
In
the tab “Field Label”, we can set a field label that is automatically
shown in the label, or caption of an UI Element that is bound to an
attribute of this type.
For a data element, we can create documentation F1 Help with Goto -> Documentation -> Change.
This documentation is not seen on screen if the Web Dynpro application
attribute WDHIDEMOREFIELDHELPASDEFAULT was set as ABAP_TRUE. We create a
text that describes the content of our data element.
Creating a F1 help for a data element
A
domain defines a value range.To be able to use it in a Web Dynpro
application,in other repository object, as parameter in GUI
programming,etc.we have to assign it to a data element
Data elements and domains
We
create a domain named Y_COUNTRY_DOMAIN that holds all the names of EU
member states, with the proper abbreviation. In “Definition” tab we have
to specify properties as data type, number of characters or length of
output
Definition of a domain – tab “Definition”
In “Value Range” we have three possibilities:
- Single values
- Intervals
- Value table
We
begin with the first possibility, “Single values”. We define the domain
fixed values – all the abbreviations of the EU countries, and a short
text – the corresponding country names.
Definition of a domain – tab “Value Range”
As
we have specified, to be able to use a domain we have to assign it to a
data element. To do this, we create a new data element and we choose
the elementary type – domain.
Assigning a domain to a data element
When
we use this data element in our Web Dynpro application, for example to
define a parameter or a context attribute, the user is allowed to choose
only the values that range among values we have defined in Domain.
To
explain the next possibility (“Intervals”), we take an example where we
need to store, in a table column, the ages between 18 and 45. In this
case, we can use an interval to limit the values that the user may
enter.
Definition of a domain – interval
We use this interval in the database table YPERSON, defined hereinafter. For this, we assign it to a data element Y_DEINTERVAL.
To explain the last possibility (“Value Table”), we use a domain that is defined in the system: WAERS.
Domain WAERS – value table
It
is recommendable to use the value table when we have many fixed values.
In our case, we have used the system table TCURC. This table holds all
the system currency.
We
use this value table in the database table YEU_COUNTRIES, defined
hereunder. For this, we assign it to a data element Y_CURRENCY.
Structures
consist of any combination of other data types of the ABAP
Dictionary.In fig. we present a structure with three components:
FIRSTNAME, LASTNAME and DATEOFBIRTH.
Definition of a structure
For each component it is defined a component type, as follows: a data element,other structure, table type, etc.
As
a component type for a structure, we can choose a type that is already
defined in the ABAP Dictionary, or we can create a new type. For
example, the component DATEOFBIRTH has YDATEOFBIRTH data type. This data
type has been already defined.
If
we want to create a new type for a component, we have to enter its name
(for example, YFIRSTNAME) and then, with double-click, we can choose
the new type.
Creating a new component type
After
we create a structure, we have to maintain the enhancement category:
Extras ! Enhancement Category, from the menu. In case we don’t want to
further extend the component structure, we choose “Cannot be Enhanced”.
Maintaining enhancement category
We can use the structures defined in ABAP Dictionary to create the context node structure for a Web Dynpro application.
We create two transparent tables, YPERSON and YEU_COUNTRIES. We will use this table later, for our Web Dynpro example.
In
the YPERSON table, we want to store the competition candidates. All the
candidates should be 18–45 years old and live in an EU country. After
creating the table, we have to enter a short description along with the
delivery and maintenance
Table maintenance
We
set “Data Browser/Table View Main” ! Display/Maintenance Allowed, to be
able to populate our table with values, using “Create Entries”, from
the menu.
Then,
we will define our table structure. To do this, we select the tab
“Fields” and enter the table columns For the fields MANDT and ID_PERSON,
we have marked the option “Key”, meaning they are the table keys. The
field MANDT is the SAP client field, a three-character client ID. The
field “ID_PERSON” represents the candidate’s ID, required to uniquely
identify each competition candidate.
Table structure
As
can be seen, we have used the data elements created hereinbefore:
YFIRSTNAME, YLASTNAME, Y_DEINTERVAL, Y_DEFORDOMAIN. When we want to
create a new data element, we write its name and, with double-click, we
activate the forward navigation. If this data element doesn’t exist, we
are asked if we want to create the new data element.
Creating a data element
Before being able to activate this table, we have to maintain the technical settings
How to maintain the technical settings for the table YPERSON
We choose a size category 0, because we don’t require many data records. We have to maintain the enhancement category: Extras -> Enhancement Category,
from the Menu. We choose the same “Cannot be Enhanced”, because we
shouldn’t further extend the table structure. After this, we can
activate our table and create the second table YEU_COUNTRIES.
We
hold here all the EU Member states information, as follows: country
name, year of EU entry, political system, capital city, currency and the
flag image name. The structure of this table is presented.
Table structure
After
this, we have to define a foreign key for the field CHECK_CUR. For this
purpose, we use the button “Foreign Keys”. We are asked if we want to
use the value table TCURC as check table.
How to create foreign key
We need TCUC as a check table, because we want to use its table contents, respectively the Currency Codes.
Currency codes
After we maintain the Technical settings and enhancement category, we can activate the same as for the table YPERSON.
The candidates can live only in an EU country. Therefore, we create a 1 to CN relationship between the tables.
From the table YPERSON field ID_COUNTRY, we create a foreign key.
How to create a foreign key
The
system can generate the graphical representation of the relationships
we have defined between tables. To show this graph,we use the Button
“Graph”.
Foreign key relation ship
We can see our tables YEU_COUNTRIES, YPERSON and the 1:CN relationship.
The
table TCUC is the check table for the table YEU_COUNTRIES. To see this
relationship also, we have to select the name of YEU_COUNTRIES table and
to press the Button “Check Table”.
Foreign key relation ship
We can create contents withUtilities --> Table content --> Create Entries from Menu
Insert – table YEU_COUNTRIES
To display the content: Utilities --> Table content --> Display from Menu.
Select – table YEU_COUNTRIES
We
can use the transparent tables defined in the ABAP Dictionary to create
the context node structure for a Web Dynpro application.
ABAP
Dictionary offers the possibility to create simple search help and
collective search help. To create a search help, we can use the context
menu of our package.
Creating a development object in the ABAP Dictionary by using the Object Navigator
We create a simple search help YSH_ID_PERSON for the column ID_PERSON of the table YPERSON
Creating a simple search help
As
can be seen at Data collection ! Selection method, we have used the
table name YPERSON. This means that all the data required come from our
table YPERSON. A search help can have the following parameters: “import
parameters”, “export parameters” or “no import” and “no export”. We have
used ID_PERSON as export parameter, because we want its value to be
returned to the input template. LPos represents the parameter position
in the hit list: FIRSTNAME has the position 1 and it is firstly
displayed in the hit list, and LASTNAME has the position 2, being
displayed after the FIRSTNAME.
Testing a search help
Afterwards,
we want to use this search help in a Web Dynpro application. We create a
search option for a competitor. The user has to enter the competitor’s
ID into a search mask. The list of IDs is limited to the number of
competitors. When the user doesn’t know the competitor’s ID, he uses the
search help and can choose the competitor’s name. The content of the
ID_PERSON parameter is returned to the search mask as soon as the user
has selected a line of the hit list in the input help. In this way, we
facilitate the input.
We
can use this search help if we link it with the ID_PERSON column of the
YPERSON table. To do this, we select the column ID_PERSON and press the
button “Srch Help”.
Search Help for the field ID_PERSON
After we enter the search help name, we have to create the search help attachment, and to save and activate the table
How to create search help attachment to the column ID_PERSON
In
this way, we have created a simple search help for the column ID_PERSON
of the table YPERSON. When we use this column in Web Dynpro, the
Framework creates a special icon to be used at the runtime to call the
input help. Moreover, we can use the keyboard key F4 to call an input
help.
To
be able to access a search help from a WD component, the proper Input
Help Mode context attribute property has to be set (“Automatic” or
“Dictionary Search Help”).
By
using a view, we can combine the data distributed in several tables.
For a better understanding, we create a view on the tables YPERSON and
YEU_COUNTRIES. When we create a view, we can choose one of the four view
types.
View types
We
choose to create a database view named YVIEW_CMPETITION. At the
beginning of the “view definition”, we have to select the view base
table (in ourcase, the table YPERSON.After the base table definition, we
link this table by defining the joining conditions. To create this
link, we use the button “Relationships”.
Creating a view
Joining conditions
In
the next step, we have to select the fields we need in our view. We can
enter each field manually or we can use the Button “Table fields”.
View fields
After activation, we can see our view content using the “Contents Button”.
View content
In this way, we have created a database view on the tables YPERSON and YEU_COMPETITION.
View definition on the database
By
using this view, we can create the context node structure for our Web
Dynpro application and so we simultaneously select the logically
connected data, from two tables.
We create a table type named YTABLE_TYPE, the line type being our YPERSON table
Creating a table type
For
the line type, we can use an existing type (table, structure, view, . .
.) or we can enter the data type, length and number of decimals. The
typical use of table type is the declaration of an internal table.
Another
example of using table type is to populate with values a context node
via a supply function. To be able to do this, we create a table type
named YTABLE_ TYPE_STRUCTURE with the line type – the structure
YSTR_PERSON.
Table type – line type structure
In the next chapter, we show how we can use this table type to populate a context node.
We create a Lock Object for the database table YPERSON. The lock object name has to begin with the prefix E (from “Enqueue”).
Lock object
Our
case consists of exactly one table, and the lock argument is the
primary key of this table. The lock mode is set to write, but can be
overwritten.
After the lock object activation, the ABAP Dictionary generates two Function Modules, named ENQUEUE_ and DEQUEUE_.
The Function Modules with enqueue prefix help us to set a lock, and the
Function Modules with dequeue prefix help us to release the locks.
With
the SE37 transaction we can see the two generated Function Modules:
ENQUEUE_EYPERSON and DEQUEUE_EYPERSON. Figure shows the structure of the
Function Module required to set a lock.
Function Module for lock setting
SAP
offers a lock mechanism required to provide two transactions by
simultaneously changing the same data in the database. The lock table
represents a table in the memory of the enqueue server and is used to
manage all the locks in the system. This lock table is checked every
time when the enqueue server receives a lock request. A program sends,
to the lock table, the key of the table entries it wants to lock; if no
lock is set, the request is accepted and the new lock is written in the
lock table. If a lock is set, the request collides with an existing lock
and the request is rejected.
Context Nodes and Attributes at Design Time
This
chapter mainly focuses on the context nodes and attributes statically
realized at design time. In this respect, we will explain not only the
role and modality to create context nodes and attributes, but also the
modality to access the values stored in the attributes of the nodes.
An
attribute is a context entity that has certain properties and can be
directly created in the root node CONTEXT, or as a child for another
node. Usually, a node is used to group more attributes that belong
together. In Fig. we present a context example created in a view
context.
A
context node can have attributes or can hold other nodes, but a context
attribute cannot have other attributes or nodes. We create a
hierarchical arrangement that has, as the start point, the root node
CONTEXT. This is automatically created when the controller is
initialized and all the nodes and attributes we created are children of
this root node.
Example of the structure of a View Context
The
data hold in the context nodes and attributes are transient, they exist
only for the lifetime of the controller. After this, all the data are
lost if we don’t store them in storage media (e.g. database table).
Attributes
To
create an attribute, we have to select the node where the attribute
should be inserted (in this case, the root context node) and, with
right-click, to open its context menu.
Creating an attribute
We have to enter the attribute properties – name and type are required, but the other settings are optional.
Defining the attribute properties
As
data type for an attribute, we can use a data type as string, xstring,
d,i or we can use the data type defined in the ABAP Dictionary. In our
example,the attribute type YDATEOFBIRTH is a data element defined in the
ABAP Dictionary. In the system, we find a list with all the data types
we can use for an attribute. The coding presented in Listing shows how
we can access, in a method, the value of the attribute created in the
context node.
Searching for an attribute data type
Access of an attribute from context node
DATA lv_dateofbirth type ydateofbirth. wd_context->get_attribute(EXPORTING name ='DATEOFBIRTH' IMPORTING value = lv_dateofbirth).
We
have defined a local variable named lv_dateofbirth of YDATEOFBIRTH
type, the same type as the attribute. We pass the value of the attribute
DATEOFBIRTH in our local variable, by using the method get_attribute of
the interface if_wd_context_node. The interface if_wd_context_node has
many methods we can use to work with context nodes. We can see all the
available methods of this interface by double-clicking on the
get_attribute method. To set the value of an attribute, we can use the
method set_attribute of the same interface.
As
can be seen in Fig, the property Input Help Mode of the attribute is
set AUTOMATIC. This means that it is used the search help assigned to
the data type of the context attribute in the ABAP Dictionary. In
principle, we have a data element of D type. This is the reason why we
will have a CALENDAR as input help
Calendar input help
The
read-only property set “no” means that the attribute is not write-
protected. To put data on the screen and to read data from user, we
connect the proper UI Elements properties with the attributes or nodes.
The data are stored in the attributes, the UI Elements being the only
object the user interacts with. For our example, we have an UI Element
InputField where the user enters his date of birth. Web Dynpro Framework
transports these data from the UI element to the attribute DATEOFBIRTH
when the user presses the SAVE Button, after he enters the value. The
attribute keeps the value for further processing. To be able to access
the value of this attribute in our methods, we have to pass this value
in a local variable (lv_dateofbirth). We can use this value, change it
or pass the new value back in the context (Fig) This value is kept in
the context for the lifetime of the controller. Then, these data are
lost if we don’t store them.
Connection among attribute, ABAP Dictionary, method and UI Element
We can directly create a node in the context root node or as child for other node. In Fig. we show how we can create a node.
Creating a node
For
each node we create, we have to set some properties, as: cardinality,
selection, etc. We can individually create the attributes for a node, or
we can use some repository objects from the ABAP Dictionary. For
example, when we work with tables, structures or views defined in the
ABAP Dictionary, we can use them to define our node, and the attributes
will be automatically generated.
Creating a Node that Uses an ABAP Dictionary Repository Object
We create a context node that uses the ABAP Dictionary structure YSTR_PERSON.
Node properties
The Button “Add Attribute from Structure” allows us to add all the structure components or only a part of them.
Selecting components of Structure
Because
we need a proper attribute for all these structure components, we
select all of them. As result, we have created a node, the attributes
being automatically generated according to the structure components we
have selected.
Context node STUDENT at design time
The
properties of the node we have chosen are: cardinality 0. . .n,
singleton – yes and Init. Lead Selection – yes. Web Dynpro Code
Wizard,reading a context node or attribute.
The
cardinality properties are very important, because they tell us how
many elements a context node may have at runtime. We have four possible
values:
- 1. . .1 Exactly one context element is instantiated
- 0. . .1 Maximum one context element is instantiated
- 0. . .n Zero or more context elements are instantiated
- 1. . .n One or more context elements are instantiated
The
singleton property can be set YES or NO. When a node is singleton at
the runtime, we have only one instance of this node. As usage example,
for a nonsingleton node we can specify the context structure required
for a Tree UI Element – sequential implementation.The Lead Selection
Initialization property determines if the lead selection should be
automatically set or manually programmed. In our case, this property is
set “YES”, meaning that the lead selection is AUTOMATIC and the first
element of this node it automatically selected. More details about lead
selection – Table UI element.
For
our node, we have defined the supply function named supply_student.
Each node may have a supply function defined for it and automatically
called by the Web Dynpro Framework. The scope of using a supply function
is to populate a context node. In certain cases, we can use the Hook
Method wdDoInit instead of a supply function. For more details, see the
Hook Methods chapter.
The
coding presented in Listing shows how we can use the supply function
method to populate the context node STUDENT with three values. We have
defined two variables: ls_student and lt_student. Ls_student is of type
if_view_name=>element_student, where “view_name” represents the view
name and “student” represents the node name. ”if_view_name” represents
the programming interface for our view controller. By double-clicking on
his name or clicking on the icon Display Controller Interface we can
see the coding of this interface. Listing shows a coding part for the
context node STUDENT.
Example of supply function Method
METHOD supply_student . DATA ls_student TYPE if_view_name=>element_student. DATA lt_student LIKE TABLE OF ls_student. ls_student-firstname = 'Ionescu'. ls_student-lastname = 'Ana Maria'. ls_student-dateofbirth = '19700309'. APPEND ls_student TO lt_student. ls_student-firstname = 'Marinescu'. ls_student-lastname = 'Loredana'. ls_student-dateofbirth = '19800523'. APPEND ls_student TO lt_student. ls_student-firstname = 'Marton'. ls_student-lastname = 'Luminita'. ls_student-dateofbirth = '19831108'. APPEND ls_student TO lt_student. node->bind_table( new_items = lt_student). ENDMETHOD.
Example of view controller programming interface.
constants: wdctx_Student type string value `STUDENT`. types: Element_Student type YSTR_PERSON, Elements_Student type standard table of Element_Student with default key. …..
As
can be seen, Element_Student is of YSTR_PERSON type (our ABAP
Dictionary structure).But, when we manually create context nodes without
dictionary structure,in the view controller programming interface,a new
structured type is created (Listing).
Example of view controller programming interface
….. types: begin of Element_Faculty, FACULTY_NAME type String, SPECIALIZATION type String, end of Element_Faculty, ……
This is why we use the following form to append values: ls_student-firstname = ‘Ionescu’.
The way we append values in an ABAP structure is: structure_name-component_name = value
With
the declaration “DATA lt_student LIKE TABLE OF ls_student”,we declare
an internal table.We use APPEND statement to add each new line at the
end of the last line of the internal table.
At the end,we use the bind_structure method to populate the node with values.Instead of the declaration:
DATA ls_student TYPE if_view_name=>element_student.
we can use:
DATA ls_student TYPE wd_this->element_student.
DATA ls_student TYPE wd_this->element_student.
In this way, we don’t need the view name anymore,because we use the wd_this self-reference.
The runtime structure
The
node STUDENT was set Singleton, it has only an instance at runtime and
the cardinality was set 0. . .n, meaning that, at runtime, we can have
from zero to n elements. Because the lead selection was set “YES”, it
was selected the first element of the node. To read, set or append a
context node or attribute, we can use the Web Dynpro Code Wizard.
The
option “As table operation” can be used in combination with the Read,
Set or Append options for a node that allows the usage of this
combination. We can read, for example, the entire context node STUDENT
in an internal table.
DATA lt_student TYPE wd_this->elements_student. lr_node->get_static_attributes_table( IMPORTING table = lt_student).
Web Dynpro Code Wizard, reading a context node or attribute
In
this case, the wizard has generated a variable lt_student of type
wd_this -> elements_student. In Listing we saw that, in Interface
Controller, besides the definition of a variable, the Element_structure
Framework has also defined a variable Elements_Student, with the form:
Elements_Student type standard table of Element_Student with default key.
This is the reason why the Wizard offers the possibility to read all the values from the STUDENT node in lt_student.
As
we have mentioned in the last chapter, we can use a table type to
populate with data a context node via a supply function. Our node
STUDENT has its attributes from the YSTR_PERSON structure. The table
type YTABLE_TYPE_STRUCTURE defined in the ABAP Dictionary has the same
YSTR_PERSON structure, as line type. Listing shows how we can use a
table type to populate with data a context node.
Example of supply function Method
METHOD supply . DATA: lt_student TYPE ytable_type_structure . DATA: ls_student TYPE ystr_person. ls_student-firstname = 'Ionescu'. ls_student-lastname = 'Ana Maria'. ls_student-dateofbirth = '19700309'. APPEND ls_student TO lt_student. ls_student-firstname = 'Marinescu'. ls_student-lastname = 'Loredana'. ls_student-dateofbirth = '19800523'. APPEND ls_student TO lt_student. node->bind_table(new_items = lt_student). ENDMETHOD.
Working with Child Nodes
We create the context structure presented.
Example of child node
It
has a context node FACULTY, cardinality 1. . .1, Singleton with child
node ADDRESS, cardinality 1. . .1, Singleton and two attributes
FACULTY_NAME type STRING and SPECIALIZATION type STRING.
We
read data from the attributes of the node ADDRESS as a child node for
FACULTY. Listing shows a possible method to read these attributes.
Reading the attributes values of the child node “ADDRESS”
DATA: lr_node TYPE REF TO if_wd_context_node, lr_subnode TYPE REF TO if_wd_context_node. DATA: lv_street TYPE string, lv_number TYPE y_char, lv_city TYPE string. lr_node = wd_context->get_child_node('FACULTY'). lr_subnode = lr_node->get_child_node('ADDRESS'). lr_subnode->get_attribute EXPORTING name ='STREET' IMPORTING value = lv_street). lr_subnode->get_attribute(EXPORTING name ='NUMBER' IMPORTING value = lv_number). lr_subnode->get_attribute (EXPORTING name ='CITY' IMPORTING value = lv_city ).
With
the first data definition, we create two variable lr_node and
lr_subnode of if_wd_context_node type. With the second data definition,
we create three variables with the same data type as the attributes we
want to read. Data type Y_CHAR represents a data element defined in the
ABAP Dictionary of CHAR type, length 6. Instead of the declaration:
lr_node = wd_context->get_child_node( ’FACULTY’).
we can use the form:
lr_node = wd_context->get_child_node( name = wd_this->wdctx_faculty).
In
the first case we have to write with capital letters the node name, and
in the second case we use the constant wdctx_faculty of string type,
defined by the Framework in Interface Controller, with the form:
constants:
wdctx_faculty type string value ‘FACULTY’.
By
using the get_child_node method of if_wd_context_node interface, we
successively access the node FACULTY and the node ADDRESS, and by using
the method get_attribute, we pass the values of the attributes in our
local variable.Another possibility to read the values of the ADDRESS
child node attributes is presented in Listing.
Reading the attributes values of the child node “ADDRESS”
DATA: lr_node TYPE REF TO if_wd_context_node, lr_subnode TYPE REF TO if_wd_context_node, ls_subnode type wd_this->element_address. DATA: lv_street LIKE ls_subnode-street, lv_number LIKE ls_subnode-number, lv_city LIKE ls_subnode-city. lr_node = wd_context->get_child_node('FACULTY'). lr_subnode = lr_node->get_child_node('ADDRESS'). lr_subnode->get_static_attributes(IMPORTING static_attributes = ls_subnode). lv_street = ls_subnode-street. lv_number = ls_subnode-number. lv_city = ls_subnode-city.
In
this case, we have used the get_static_attributes method that supplies a
copy of all the static attributes for the ADDRESS child node. After
this, we are able to access the attributes values through the local
structure “ls_subnode”.Listing shows how we can populate with values the
elements of the ADDRESS child node
Populating the attributes of the ADDRESS node
DATA:lr_node TYPE REF TO if_wd_context_node, lr_subnode TYPE REF TO if_wd_context_node, ls_subnode TYPE if_view_name=>element_address. lr_node = wd_context->get_child_node('FACULTY'). lr_subnode = lr_node->get_child_node('ADDRESS'). ls_subnode-street = 'Pforzheimer'. ls_subnode-number = '106A'. ls_subnode-city = 'Pforzheim'. lr_subnode->set_static_attributes(ls_subnode).
Data Binding, Context Mapping and Interface Methods
This
starts with the presentation of the mechanism used to manipulate data
between the context attributes and UI elements, mechanism called,in Web
Dynpro,“data binding”. We continue with the mechanism of sharing data
among the various controllers, which is realized by using different
variants of context mapping. Finally, we highlight the importance of the
interface methods required to access them “cross-component”.
In
the last chapter, we have created context nodes and attributes in the
context view.A node or attribute can be created in each context. When we
create an attribute in the context view, this value is visible only in
this context view. The mechanism for sharing data among different
controllers is known as “context mapping”. A context mapping can be
internal, when the nodes we map are within the same component, and
external, when the mapping is cross-components.
Data Binding
Each
UI element has certain properties. With data binding, we define which
node or attribute from the context will act as a data source for an UI
element property. To exemplify the data binding mechanism, we create a
component named Y_DATABINDING with a view named V_BIND and a window
W_DEFAULT.
Structure of Y_DATABINDING component
In context view, we create a context node STUDENT with the same dictionary structure YSTR_PERSON.
Structure of STUDENT node
We
create a WD component that reads the user inputs in the attributes
FIRSTNAME,LASTNAME and DATEOFBIRTH. When the user presses the “SHOW”
button, these data are shown by means of TextView UI Elements.
Example of data binding
We have many possibilities to make a data binding. For example, we can:
(a) Create a “Container Form” for a context node
(b) Use the Web Dynpro Wizard
(c) Create data binding for each attribute
(b) Use the Web Dynpro Wizard
(c) Create data binding for each attribute
(a)
To create a “Container Form”, we add a Group UI element and then, by
rightclicking,we choose from the contextual menu “Create Container
Form”.
Creating container form
After
this, we can choose which context node we use for data binding and
which type of UI Element is associated to each attribute
As a result, the Framework generates for each context attribute an UI element InputField and a proper label, and makes the data binding between each UI element property (value) and the context attribute.
As a result, the Framework generates for each context attribute an UI element InputField and a proper label, and makes the data binding between each UI element property (value) and the context attribute.
Data mapping among InputField UI Elements and the context attributes.
To create a “Container Form”, we can use each UI Element of container type.
(b)
To create a data binding, we can use the Web Dynpro Wizard button(Fig)
In case we use the Form option, the Framework generates a
transparentContainer UI element that contains the UI elements that we
have to choose inthe same way as we have shown at point (a).
Using wizard to create a form and the proper data binding
(c)
To manually define a data binding for each attribute, we have to insert
the proper UI Element and create data binding between an UI element
property and a context attribute. We insert 3 TextView UI Elements and 3
Labels UI Elements.
Layout structure
We have to create the data binding between each text property of the TextView UI Element and the proper context attribute.
Data binding
We
repeat this step until we make data binding among the text property of
all the three UI Elements and the proper context attributes. Then,we
insert a Button UI Element in the Group GRP_STUDENT_WRITE and add an
action.
Inserting a button and adding an action
In
this case, we don’t need to enter coding in the generated event handler
method onactionshow. After creating an application for our component,
we are ready to run it. The result is presented. At runtime, the context
attributes are empty. After the user enters values and pushes the SHOW
button, the context attributes are populated with these values.At design
time, we realised a data binding among the TextView UI Elements and the
same context attributes (Firstname, Lastname and Dateofbirth). This is
the reason why these UI Elements show the values entered by the user in
the Input-Fields UI elements.
Running the application
So
far, we have used only context attributes that were defined in the view
context.When we want to share data among different controllers, we have
to define a context mapping.
A
context mapping can be an internal context mapping or an external
context mapping. An internal mapping relationship can be defined between
any pair of controllers within the same WD component, whereas the
external mapping defines a mapping across the borders of a WD component.
Internal Context Mapping
As
mentioned before, the mechanism for sharing data among different
controllers within the same WD component is known as internal context
mapping.For a better understanding of this mechanism, we create the same
example from data binding, but in this case we create the two groups
GRP_STUDENT_READ and GRP_STUDENT_WRITE, in different views. At runtime,
we display the view V_VIEW1.When the user presses the “SHOW” button, we
display the second view V_VIEW2. The WD component structure is
presented.
WD component structure
We
cannot create the context node in the view context, because we need the
values of this attributes not only in the view V_VIEW1, but in the view
V_VIEW2 as well.In this case,we create the node STUDENT in the context
of component controller.In this way,through context mapping, we can
access the context of the component controller via a view
controller. Context mapping doesn’t cause the duplication of data.The
nodes in the view controllers only hold a reference to the mapping
context node from the component controller.
Internal context mapping
We
firstly create the context node of the component controller. After
this, we make a context mapping between the context of the view V_VIEW1
and the context node of component controller. As a result, the entire
context node STUDENT is mapped. In the same way, we proceed to make a
context mapping between the context of the view V_VIEW2 and the context
of component controller.Consequently,we have to create the view layout
for the views V_VIEW1,V_VIEW2 and the data binding.Data stored in the
context of the component.
Context mapping
The mapping result
controller can be used within a view if we have firstly made a context mapping.The schematic representation is presented.
Intern context mapping, data binding
The
lines between controllers symbolize the context mapping, and the lines
between view controllers and the views layout symbolize the data
binding. In the view V_VIEW1, we create the group GRP_STUDENT_WRITE and
then we can use the view context to create a “Container Form”.Because we
want to show both views in the same window,after the user presses the
“SHOW” Button we use a ViewContainerUIElement.
View layout for V_VIEW1
We have to embed the view V_VIEW2 in the ViewContainerUIElement.
Embed view V_VIEW2
We have to embed the view V_VIEW2 in the ViewContainerUIElement (Fig.).
Embed view V_VIEW2
After
creating an application,we can see the result. At runtime, the User
Interface is the same as for the data binding (example – Fig.)The
difference is the context mapping. In this case, the context is not
defined in the view context, but in the context of the component
controller, and can be accessed through context mapping. The data reside
in the context node of the component controller context, and the
context node of the views controller simply holds a reference to this.
External Context Mapping
External
mapping is a cross-component mapping and can be directly mapping or
reversely mapping. We can create an external context mapping if we have
firstly declared a usage for the component that holds the respective
context and the respective context node has been marked as interface.
Direct Mapping
As
a briefly description of this kind of mapping, we can say that the
external mapping of direct mapping type is a cross-component mapping in
which the main component directly access the data (represented through
the context structure) of the used component.
For
a better understanding of this type of mapping, we create the same
example for the internal mapping, but in this case we create two WD
components. The component Y_EM_LAYOUT has two Views used to create the
user interface.To hold the data entered by the user, we use the context
node STUDENT.To be able to access this context node, we have to define a
component usage. In WD, the component Y_EM_LAYOUT defines a usage of
the component Y_EM_CONTEXT.
WD component structure
In
real cases, a faceless component is useful if several components access
the same set of data. This type of component can be used to create a
model for a multicomponent application. We firstly create the context
node in component controller of the component Y_EM_CONTEXT. We keep the
same context node STUDENT, but in this case we create an interface node.
If this node has not defined the interface type, we cannot access it
from another component.
Context node structure
The
component Y_EM_LAYOUT has two Views used to create the user interface.
To hold the data entered by the user, we use the context node STUDENT.
To be able to access this context node, we have to define a component
usage. In WD, the component Y_EM_LAYOUT defines a usage of the component
Y_EM_CONTEXT
Defining a Usage in a component
After
the usage is defined, we have to create a controller usage in the
component controller. We need to use the component Y_EM_CONTEXT, the
component use (named CONTEXT) and, hence, we need the
INTERFACECONTROLLER
Controller usage definition
The
next step is to define a mapping. In this case, it is an external
mapping, because the node we use to define the mapping is outside the
component
Defining an external mapping
As a result, the entire context node is mapped.
The mapping result
In
the Methods tab, we have to verify in the wddoinit( ) Hook Method if it
is an instance of the used component. The coding from Listing shows how
we can verify this and how can be created in case it doesn’t exist.
Checking an instance of the used component
METHOD wddoinit . DATA:lr_cmp_usage TYPE REF TO if_wd_component_usage. lr_cmp_usage = wd_this->wd_cpuse_context( ). IF lr_cmp_usage->has_active_component( ) IS INITIAL. lr_cmp_usage->create_component( component_name = 'Y_EM_CONTEXT'). ENDIF. ENDMETHOD.
By
using the method HAS_ACTIVE_COMPONENT of the IF_WD_COMPONENT_USAGE, we
verify if the usage has an active component.If the component has already
been initialized, the logic moves on otherwise, we create an instance
of the component by using the CREATE_COMPONENT method of the same
interface. We must ensure that the external component has been
instantiated before the interface controller is accessed.
It
is recommendable to create a usage for a component only in the moment
we need it.In our little example, we have to create the usage in the
wdDoInit Hook method, but,in case we use navigations plugs to navigate
to a used component,it is recommendable to create the usage in the
method used to fire the respective plug.
Further,
we can proceed as in the previous example: we create an internal
mapping between the context node of the component controller and the
context view of the views V_VIEW1 and V_VIEW2. After this, we can create
the data binding.All these are schematically presented. The line
between WD components symbolizes the external direct context mapping,
the lines between component controller and views controllers symbolize
internal mapping, and the lines between view controllers and views
layout symbolize the data binding.
Reverse Mapping
As
a briefly description of this king of mapping, we can say that the
external mapping of the reverse mapping type is a cross-component
mapping in which the data (represented through the context structure)
are put at our disposal by the main component.
To
realise the screen based on them, we use the interface view of the used
component.For a better understanding of this type of mapping, we create
the same example from direct mapping,where we change only the
implementation part. We create two WD components, named Y_EM_CONTEXT_RM
and Y_EM_LAYOUT_RM. The WD components structure is presented. We define,
in the component Y_EM_CONTEXT_RM, the context node STUDENT.This
component has no view, because we embedded here the interface view
Schematic representation of an external direct mapping
WD components structure
of
the component Y_EM_LAYOUT_RM.The component Y_EM_LAYOUT_RM implements
the user interface, making usage of the component Y_EM_CONTEXT_RM
required to have access to the STUDENT node. Schematically, all these
are presented. We firstly create the context node in the component
controller of the component Y_EM_CONTEXT_RM, by using the same context
node STUDENT and interface node.
Schematic representation of an external reverse mapping
Interface node
The
component Y_EM_LAYOUT_RM implements the user interface. In component
controller, we create a node named STUDENT, with the same structure as
the node STUDENT from the component controller of the component
Y_EM_CONTEXT_RM.
After
creating the node, we make an internal mapping, we create the user
interface and make the data binding. Another solution is to copy the
component Y_EM_LAYOUT and to make the proper changes. We can copy this
component by right-clicking on the component name, and choose “Copy”
from the contextual menu. We have to specify a name for the new
component and a package where we want to save this component. We define a
usage of the component Y_EM_CONTEXT_RM and create an external mapping,
reverse mapping.
Interface node, Input element
Context structure after usage and mapping
After
entering the coding required to verify if it is an instance of the used
component, we can save and activate. For the next step, we go back to
the component Y_EM_CONTEXT_RM, where we have to define a usage for the
component Y_EM_LAYOUT_RM, required to be able to embed its interface
view.
After
this, we can embed the interface view of the component for which we
have defined only the usage. The Framework generates a corresponding
interface view when we create a window. This interface can be embedded
by other component,after the usage was defined. To embed the interface
view or windows of the Y_EM_LAYOUT_RM component, we proceed in the same
way as for embedding the views.
Defining the usage
Y_EM_LAYOUT_RM component, we proceed in the same way as for embedding the views.
Embed operation
After
entering the coding required to verify if an instance of the used
component exists, we can save, activate and run the application.
A
method of a component controller can be marked as interface. In this
way, it is possible to access it cross-component. This option is
possible only for the methods applied to the component controllers. The
methods that take place in Views orWindows can’t be marked as interface.
For
a better understanding of this kind of methods, we expand the previous
example. In this example, after the user enters values and presses the
“SHOW” button, the context attributes of the node STUDENT of the
component Y_EM_CONTEXT_RM are populated with these values. When we want
to verify if the user have entered his first name, we have to define an
interface method in the component controller of this component, a method
that verifies if this attribute has a value or it is empty. For this
purpose, we create the interface method named check_firstname().
Marking a component controller method as interface
We
create this method in the component Y_EM_CONTEXT_RM, because there is
the context node where the values are transferred after the user presses
the “SHOW” button.
Method check_firstname implementation
METHOD check_firstname . DATA lr_node TYPE REF TO if_wd_context_node. DATA ls_node TYPE if_componentcontroller=>element_student. DATA lv_firstname TYPE string. DATA lr_api_controller TYPE REF TO if_wd_controller. DATA lr_message_manager TYPE REF TO if_wd_message_manager. lr_node = wd_context->get_child_node('STUDENT'). lr_node->get_attribute(EXPORTING name = 'FIRSTNAME' IMPORTING value = lv_firstname). IF lv_firstname IS INITIAL. lr_api_controller ?= wd_this->wd_get_api( ). lr_message_manager = lr_api_controller->get_message_manager( ). lr_message_manager->report_error_message( message_text = 'The Field First Name is empty!'). ENDIF. ENDMETHOD.
We
read the value of the FIRSTNAME attribute into the local variable
lv_firstname.After this, we verify if this attribute has a value or it
is empty. In case this attribute is empty, we want to show a message
with the string ‘The Field First name is empty!’.In this case, we have
used the method REPORT_ERROR_MESSAGE of interface IF_WD_MESSAGE_MANAGER.
To generate a message, we can use the Web Dynpro Code Wizard.
Usage of Web Dynpro Code Wizard
Is
not recommended this art of programming, where the language-specific
text elements are entered in the source text. In this case, we have used
the easy way and not the best one. In the Chap.10, we explain how we
can create messages easy to use and translate, without more programming
effort.
After
this method is implemented, we have to go back to the component
Y_EM_LAYOUT_RM. When the user presses the SHOW button, we have to call
the method check_firstname from the component use. If a method is marked
as interface, we can cross-component access it. This means that we can
call it from our onactionshow event handler method after we define a
usage at the view level.
Usage definition
The coding from Listing shows the implementation of onactionshow event handler method.
Method call in used controller
METHOD onactionshow . DATA: lr_interfacecontroller TYPE REF TO yiwci__em_context_rm . lr_interfacecontroller = wd_this->wd_cpifc_context( ). lr_interfacecontroller->check_firstname( ). ENDMETHOD.
We can use Web Dynpro Code Wizard to generate this code.
Web Dynpro Code Wizard
Runtime
View Controller Methods
Abstract
As we have seen in the previous chapters, in the Methods tab of a View
we find various types of methods generated by the Framework, and we can
also create our own methods. The purpose of this chapter is to present
the role and the modality to use the various methods generated by the
Framework and the modality to realize our own methods.
Each view has exactly one view controller. The view controller can contain
methods for data retrieval or for processing user inputs.
methods for data retrieval or for processing user inputs.
As
we have seen, each view has a Methods tab where we can create our own
user-defined methods or we can find the methods generated by the
Framework. In each Method tab of a View, we can find or create three
types of methods:
- Event Handler: This kind of methods respond to actions or to events. An example of such a method is generated by the Framework when we define an inbound plug into a View. Another example is a method generated from the Framework when we create an action.
- Method: We can use this kind of methods to create User-defined instance methods. Another example is the Hook Methods generated by the Framework.
- Supply Function: When we create a node and define a supply function for it, the Framework generates a corresponding supply function method used to populate with data a context node.
These
methods cannot be deleted and represent the interface between the
Framework and our application. The Hook Methods are called in a specific
sequence according to a phase model. After generation, these methods
are empty, but can be filled with source codes in case we want to
interfere in a certain step of this phase model.
shows the Hook methods to be found in different controllers.
As
we can see, the Hook methods wdDoInit and wdDoExit are common to all
the controllers. shows which Hook methods can be found in a view.
Hook methods in a view
wdDoInit
This
method can be considered the controller constructor. It is
automatically called when the controller is initialized for the first
time. We have many examples where we can use this method, for
example:setting the initial values of a controller context, dynamically
creation of a context node and attributes,filling context nodes.We can
use this method instead of the supply function method (to populate with
values a context node),only if we know that the context is filled only
once and it’s not invalidated afterwards.
We
create a WD component that uses the wdDoInit Hook method to populate
with values a context node. The component structure and the view layout
are presented.
WD component structure, view layout
In
the context view, we create a context node named STUDENT, with the same
structure as the data binding example –dictionary structure
YSTR_PERSON,cardinality 1...1,singleton, without supply function.
Context structure
Using
the wdDoInit Hook method,we populate with values this node (Listing).
When calling the application for the first time, the wdDoInit Hook
method fills the node STUDENT with all the elements set here.
The wdDoInit Hook method
METHOD wddoinit . DATA lr_node TYPE REF TO if_wd_context_node. DATA ls_data TYPE if_v_view=>element_student. lr_node = wd_context->get_child_node('STUDENT'). ls_data-firstname = 'Antonia Maria'. ls_data-lastname = 'Keller'. ls_data-dateofbirth = '19800306'. lr_node->set_static_attributes(ls_data). ENDMETHOD.
We can use the wdDoInit Hook Method to dynamically create the context nodeSTUDENT and to populate it with values.
Runtime
The wdDoInit Hook method
METHOD wddoinit . DATA: lr_node TYPE REF TO if_wd_context_node, lr_node_info TYPE REF TO if_wd_context_node_info, lr_child_node_info TYPE REF TO if_wd_context_node_info. lr_node_info = wd_context->get_node_info( ). lr_child_node_info = lr_node_info->add_new_child_node( name = 'STUDENT' is_singleton = abap_true is_multiple = abap_false is_mandatory = abap_true static_element_type = 'YSTR_PERSON' ). lr_node = wd_context->get_child_node('STUDENT'). DATA ls_data TYPE ystr_person. ls_data-firstname = 'Antonia Maria'. ls_data-lastname = 'Keller'. ls_data-dateofbirth = '19800306'. lr_node->bind_structure(EXPORTING new_item = ls_data). ENDMETHOD.
To
dynamically create the context node “STUDENT”, we have used the
method ADD_NEW_CHILD_NODE of the IF_WD_CONTEXT_NODE_INFO interface that
creates an Info Object and adds it as a Lower-Level Node for the CONTEXT
root node. The method CREATE_NODEINFO_FROM_STRUCT of the
CL_ WD_DYNAMIC_TOOL class is obsolete and that’s why it is recommendable
to use the if_wd_context_node_info->add_new_child_node.
ADD_NEW_CHILD_NODE have many import parameters of which,for the scope of our example, we have used:
- NAME of STRING type – the name of the generated context node
- IS_SINGLETON of ABAP_BOOL type,default value ABAP_FALSE – sets the property node SYNGLETON.In our example,the node STUDENT has to be singleton,and that’s why we have set this value ABAP_TRUE
- IS_MULTIPLE of ABAP_BOOL type, default value ABAP_TRUE – sets the property node CARDINALITY.In our example,the node STUDENT has the cardinality 1...1,and that’s why we have set this value ABAP_FALSE
- IS_MANDATORYf ABAP_BOOL type,default value ABAP_FALSE - sets the same property node CARDINALITY.We need the ABAP_TRUE value because the context node must have exactly one context element at runtime
- STATIC_ELEMENT_TYPE of STRING type – we can use it to define the DICTIONARY_STRUCTURE property for our context node. Same as the case when this node is created at the design time, we can use the name of the development objects created in the ABAP Dictionary as Structure or Views
wdDoExit
This
method can be considered the controller destructor. It is automatically
called when exiting the controller, and can be used for executing
closing statements.
In
the ABAP Dictionary, we have defined a lock for the database table
YPERSON. We can use wdDoExit Hook method to release a lock that has been
set for this table to synchronize the access of several WD applications
to the same data. To do this, we have to use the generated
DEQUEUE_EYPERSON Function Module (Listing).
The wdDoExit Hook method
METHOD wddoexit . DATA lv_id_candidate TYPE yperson-id_person. DATA lr_node TYPE REF TO if_wd_context_node. DATA ls_data TYPE wd_this->element_candidate. lr_node = wd_context->get_child_node('CANDIDATE'). lr_node->get_attribute( EXPORTING name = 'ID_PERSON' IMPORTING value = lv_id_candidate). CALL FUNCTION 'DEQUEUE_EYPERSON' EXPORTING id_person = lv_id_candidate. ENDMETHOD.
Here
we have called the Function Module directly from our WD method, but we
can create a method in a class used as model for theWDcomponent. If we
don’t call the corresponding DEQUEUE_EYPERSON Function Module to release
the database record that was locked with the EQUEUE_EYPERSON Function
Module, this lock is generally removed at the end of the transaction.
wd Do Modify View
This
method is mostly used in the dynamic programming, it is a method used
for modifying the view before rendering. For the dynamically programming
of the UI elements, we have many classes and methods that help us as
application developer to dynamically modify a view. To show this, we
create an example, aWDcomponent, where we use this Hook method to
dynamically create an InputField, a Label, a TextView and a LinkToAction
UIelement. The WD component structure and the context node are
presented.
WD component structure and context node
For
the scope of this example, we import in the MIMEs (Multipurpose
Internet Mail Extensions) folder an image: next.JPG that we use for the
linkToAction UI element. To import a file in this folder, we right-click
on the WD component name and, from the contextual menu, we chooseCreate -> Mime Object -> Import.
The
context node PERSON has the Cardinality 1. . .1, Singleton. Its
attributes are NAME and GREETING, of string type. We can almost use the
same example as for our first exercise. In this case, we create at
design time only the UI element Group, the other UI elements being
dynamically created by using the wdDoModify- View Hook method.The view
layout is presented.
View layout
Listing
shows the content of the wdDoModifyView Hook method By using the
FIRST_TIME parameter of WDY_BOOLEAN type, we check if wdDoModifyView is
called for the first time. In case this parameter is ABAP_TRUE (first
time), we create a label UI Element:
lr_label = cl_wd_label=>new_label( id = ‘NAME_LBL’ label_for = ‘NAME’ text = ‘NAME’).
To do this, we use the method new_label of the cl_wd_label class interface
The WdDoModifyView Hook method
METHOD wddomodifyview . DATA lv_bind_name TYPE string. DATA lv_bind_greeting TYPE string. DATA lr_link_to_action TYPE REF TO cl_wd_link_to_action. DATA lr_container TYPE REF TO cl_wd_group. DATA lr_flow_data TYPE REF TO cl_wd_flow_data. DATA lr_input_field TYPE REF TO cl_wd_input_field. DATA lr_text_view TYPE REF TO cl_wd_text_view. DATA lr_label TYPE REF TO cl_wd_label. IF first_time EQ abap_true. lr_label = cl_wd_label=>new_label( id = 'NAME_LBL' label_for = 'NAME' text = 'NAME'). lr_flow_data = cl_wd_flow_data=>new_flow_data(element = lr_label). lr_container ?= view->get_element('GRP'). lr_container->add_child(lr_label). lv_bind_name = 'PERSON.NAME'. lr_input_field = cl_wd_input_field=>new_input_field( id = 'NAME' bind_value = lv_bind_name). lr_flow_data = cl_wd_flow_data=>new_flow_data( element = lr_input_field). lr_container->add_child( lr_input_field). lr_link_to_action = cl_wd_link_to_action=>new_link_to_action( id = 'LTA_LINKTOACTION' on_action = 'NEXT' image_source = 'NEXT.JPG'). lr_flow_data = cl_wd_flow_data=>new_flow_data( element = lr_link_to_action). lr_container->add_child(lr_link_to_actio ). lv_bind_greeting = 'PERSON.GREETING'. lr_text_view = cl_wd_text_view=>new_text_view( id = 'TXV_NAME' bind_text = lv_bind_greeting). lr_flow_data = cl_wd_flow_data=>new_flow_data(element = lr_text_view). lr_container->add_child(lr_text_view). ENDIF. ENDMETHOD.
The
new_label method has many mandatory and optional parameters. We have
used label_for, text and ID to set the main properties of the Label UI
element. The text parameter helps us to set the label text. The
Label_for parameter specifies the UI element for which this label is.
To
embedding the UI elements into the layout, we need to specify the
arrangement of these elements. For this, we have used the FlowLayout
layout:
lr_flow_data = cl_wd_flow_data=>new_flow_data( element = lr_label).
Class interface CL_WD_LABEL
Parameters for the new_label method
After
creating the UI element and setting the layout, we have to attach them
to the ROOTCONTAINERUIELEMENT or to another container.In our case, we
have attached our new created label to the UI element Group with the GRP
ID.
lr_container ?= view->get_element(‘GRP’).
lr_container->add_child(lr_label).
lr_container->add_child(lr_label).
We have used the method add_child( ) that enabled us to do this.After this,we create an InputField UI element:
lr_input_field = cl_wd_input_field=>new_input_field( id = ’NAME’ bind_value = lv_bind_name).
We
use the new_input_field method from the cl_wd_input_field class
interface.The bind_value parameter represents the value property for the
UI element property.In this case, we dynamically create a data binding
for this property to the context node PERSON, attribute NAME. Until now,
we have seen how we can create a data binding at the design time. In
this case, we can’t create a data binding at design time, because this
UI element doesn’t exist at the design time; it is dynamically created
at runtime.
To
dynamically create a data binding of the property bind_value with the
NAME attribute, we have to specify the absolute path of this
attribute. lv_bind_name = ‘PERSON.NAME’.
In the next step, we dynamically create a LinkToAction UI element:
lr_link_to_action = cl_wd_link_to_action=>new_link_to_action( id = ‘LTA_LINKTOACTION’ on_action = ‘NEXT’ image_source = ‘NEXT.JPG’ ).
We
use the method new_link_to_action of the cl_wd_link_to_action class
interface. This UI element has an event associated. We have used the
parameter on_action to define the action that the Framework triggers
when the user interacts with this UI element.
For
a linkToAction UI element, we can define a hypertext link or we can use
an image instead a text.In our case, we have used the parameter
image_source to specify the name of the image we want to use. Then, we
specify the layout and we attach it to our UI element Group with the
same GRP ID.
At the end, we dynamically create a TextView UI element by using the new_text_view method of the cl_wd_text_view class interface
lr_text_view = cl_wd_text_view=>new_text_view(id = ’TXV_NAME’bind_text = lv_bind_greeting).
The
data binding to the context attribute GREETING is dynamically
created.After creating the UI element, we specify the layout and we
attach it to our UI element Group with the same GRP ID.
When the user presses the linkToAction UI element, the Framework triggers the event handler method onactionnext(Listing ).
Action Next
The onactionnext event handler method
METHOD onactionnext . DATA: lv_name TYPE string, lv_greeting TYPE string. DATA lr_node TYPE REF TO if_wd_context_node. DATA ls_data TYPE wd_this->element_person. lr_node = wd_context->get_child_node( 'PERSON'). lr_node->get_attribute(EXPORTING name = 'NAME' IMPORTING value = lv_name). CONCATENATE 'Welcome' lv_name INTO lv_greeting SEPARATED BY space. ls_data-greeting = lv_greeting. lr_node->set_static_attributes(ls_data). ENDMETHOD.
Runtime
In case we want to set “required” the state property of the Input UI element, we need only an extra line code:
lr_input_field = cl_wd_input_field=>new_input_field( id = ‘NAME’ state = cl_wd_input_field=>e_state-required bind_value = lv_bind_name).
We
use the state parameter to dynamically set the property with the same
name of the InputField UI element.If we don’t use this optional
parameter, the default value is set:
CL_WD_INPUT_FIELD=>E_STATE-NORMAL.
wd Do Before Action
We
can use this method to perform our own validation before an action is
triggered.To exemplify this,we create a Web Dynpro component named
Y_WDDOBEFOREACTION with a view named V_VIEW and a window W_DEFAULT.
In
the context view, we create the well-known context node named
STUDENT,with the same dictionary structure YSTR_PERSON, cardinality
1...1, singleton,without supply function. Our scope is to check if the
user enters values in all the in put Fields UI elements bound to the
attributes of the context node STUDENT. TheView layout is presented.
The View layout
In
the wd Do Before Action Hook method, we use the static method
CHECK_MANDATORY_ATTR_ON_VIEW of the CL_WD_DYNAMIC_TOOL class to check if
the user had entered values in all the mandatory fields (the state
property of the inputField UI elements is set required).
The wdDoBeforeAction Hook method
METHOD wddobeforeaction . DATA lr_api_controller TYPE REF TO if_wd_view_controller. DATA lr_action TYPE REF TO if_wd_action. lr_api_controller = wd_this->wd_get_api( ). lr_action = lr_api_controller->get_current_action( ). IF lr_action IS BOUND. CASE lr_action->name. WHEN ‘SAVE’. cl_wd_dynamic_tool=>check_mandatory_attr_on_view( view_controller = lr_api_controller). ENDCASE. ENDIF. ENDMETHOD.
When
the user presses the Save button, the Web Dynpro Framework firstly
checks,by using the wdDoBeforeAction Hook method, if all the required
fields are filled.In case the user doesn’t enter values in all these
fields, all the operations that had to take place after pressing the
Save button are finished and the user is informed about this,through
error messages and by highlighting the UI elements that generated these
messages. In this way, we don’t have to manually check each mandatory
field.
Runtime
wd Do On Context Menu
We
can use this method to provide hierarchical context menus in web Dynpro
Views.In our first example, we have already seen the default context
menu displayed by the Web Dynpro Framework when the user presses
right-click on an UI element.
We
can create a context menu at design time,by using the CONTEXT_MENUS
root,or dynamically, by coding the wd Do On Context Menu Hook method.To
exemplify how we can use this method to dynamically create context
menus, we use the example from the wdDoBeforeAction Hook method. In this
case,we offer to the user the possibility to personalize the field he
wants to be mandatory. He will be able to choose between his first name
as mandatory field and his last name as mandatory field.
When
he chooses the first name as mandatory,we will mark the corresponding
field with a red star, and when he chooses the last name, we will mark
the corresponding field with a red star. In the default mode, the first
name is set as mandatory.
To
create this example, we have to perform some modifications into the
last application.In this case,we have to set dynamic the state
properties of the two inputField UI elements,corresponding to first name
and last name. To be able to do this, we have to create, in the context
view,two extra context attributes of WDUI_STATE type,to bind these
attributes with the corresponding properties. In this way, at design
time, the two inputField UI elements are not marked as mandatory,anyway.
To set in the default mode the first name as mandatory,we use the
wdDoInit Hook method we have just learnt about.
Context structure and data binding
Setting the initial values for our node DYNAMIC
METHOD wddoinit . DATA lr_node TYPE REF TO if_wd_context_node. DATA ls_data TYPE wd_this->element_dynamic. lr_node = wd_context->get_child_node('DYNAMIC'). ls_data-first_name = cl_wd_input_field=>e_state-required. ls_data-last_name = cl_wd_input_field=>e_state-normal. lr_node->set_static_attributes(ls_data). ENDMETHOD.
To
offer to the end user the capability to dynamically choose what value
he wants to be mandatory from the two optional values, we have to code
the wd Do On-ContextMenu Hook method.
With
the first data statement, we create a local reference to the CL_WD_MENU
class and two local references to the CL_WD_MENU_ACTION_ITEM, required
to dynamically create our menu,and two menu options of menuActionItem
type. We need the two menu options to offer to the user the possibility
to choose between options:set first name as mandatory or set last name
as mandatory.
With
the second data statement, we create two local variables required to
read from the context attributes the status properties corresponding to
the two input-Fields UI elements(firstname, lastname)and a local
reference required to access our context node. Firstly,we create a
context menu by using the static method new_menu of the cl_wd_menu
class.
By
using the static method new_menu_action_item of the
cl_wd_menu_action_item class, we create the two menu options we
need.Fromthe parameters of this class,we have used:
- id: To set the ID of the view element
- on_action: To associate the action that will be triggered when the user presses the respective option
- text: The text that will be displayed for the respective menu option
The wd Do On Context Menu example
METHOD wddooncontextmenu . DATA: lr_menu TYPE REF TO cl_wd_menu, lr_menu_item1 TYPE REF TO cl_wd_menu_action_item, lr_menu_item2 TYPE REF TO cl_wd_menu_action_item. DATA: lr_node TYPE REF TO if_wd_context_node, lv_first_name TYPE wdui_state, lv_last_name TYPE wdui_state. lr_node = wd_context->get_child_node('DYNAMIC'). lr_node->get_attribute(EXPORTING name = 'FIRST_NAME' IMPORTING value = lv_first_name). lr_node->get_attribute(EXPORTING name = 'LAST_NAME' IMPORTING value = lv_last_name). lr_menu = cl_wd_menu=>new_menu(id = 'CONTEXT_MENU'). IF lv_first_name = 01 AND lv_last_name = 00. lr_menu_item1 = cl_wd_menu_action_item=>new_menu_action_item id = 'LAST_NAME' on_action = 'LN_MANDATORY' text = 'Set last name as mandatory'). lr_menu_item2 = cl_wd_menu_action_item=>new_menu_action_item id = 'FIRST_NAME' on_action = 'FN_MANDATORY' text = 'set first name as mandatory' enabled = abap_false). ELSEIF lv_first_name = 00 AND lv_last_name = 01. lr_menu_item2 = cl_wd_menu_action_item=>new_menu_action_item id = 'FIRST_NAME' on_action = 'FN_MANDATORY' text = 'set first name as mandatory'). lr_menu_item1 = cl_wd_menu_action_item=>new_menu_action_item id = 'LAST_NAME' on_action = 'LN_MANDATORY' text = 'Set last name as mandatory' enabled = abap_false). ENDIF. lr_menu->add_item(the_item = lr_menu_item1). lr_menu->add_item(the_item = lr_menu_item2). menu = lr_menu. ENDMETHOD.
- enabled: To set if this option is active or inactive. In the default mode,this parameter is set ABAP_TRUE,respective enabled
The
local variables used to pass the values of the two attributes
(firstname and lastname) are of the same type as the attributes:
WDUI_STATE.By doubleclicking on the TYPE,the forward navigation is open
and we can see a data element with a Domain as an elementary type.This
domain has two fixed values:00 for Normal item and 01 for required.
Before
we effectively create the two menu options, we have to check which one
of the two state proprieties is set required and which one is set
normal.In case the firstname is required and lastname is normal,we
create the two menu options with “Set last name as mandatory” active and
“Set first name as mandatory” inactive.In case the firstname is normal
and the lastname is required,we create the two menu options with “Set
last name as mandatory” inactive and “Set first name as
mandatory”active.
Then,
we add the two created menu options of menuActionItem type to our
context menu and display the respective menu by using the
wdDoOnContextMenu Hook method, returning the parameter named menu. we
have already seen that, for our InputFields UI elements, we have set the
properties:
- context Menu Behaviour: Provides, not inherits from the container
- context Menu Id: Set with the IDs of our context menu options
Runtime
All
we have to do now is to create the respective actions: FN_MANDATORY and
LN_MANDATORY,actions that the Framework triggers when the user presses
our menu action items. The onactionln_mandatory event handler method is
presented.
Event handler method triggered for the menu option with LAST_NAME ID
method ONACTIONLN_MANDATORY . DATA lr_node TYPE REF TO if_wd_context_node. DATA ls_data TYPE wd_this->element_dynamic. lr_node = wd_context->get_child_node('DYNAMIC'). ls_data-first_name = cl_wd_input_field=>e_state-normal. ls_data-last_name = cl_wd_input_field=>e_state-required. lr_node->set_static_attributes(ls_data). endmethod.
In
case the user chooses the last name as mandatory, we have to set
required the property state of the corresponding UI element and normal
the property state of the UI element corresponding to the first name.
The
onactionfn_mandatory event handler method is presented in Listing In
case the user chooses the first name as mandatory, we have to set
required the property state of the corresponding UI element and to set
normal the property state of the UI element corresponding to the last
name.
Event handler method triggered for the menu option with FIRST_NAME ID
method ONACTIONFN_MANDATORY . DATA lr_node TYPE REF TO if_wd_context_node. DATA ls_data TYPE wd_this->element_dynamic. lr_node = wd_context->get_child_node('DYNAMIC'). ls_data-first_name = cl_wd_input_field=>e_state-required. ls_data-last_name = cl_wd_input_field=>e_state-normal. lr_node->set_static_attributes(ls_data). endmethod.
Runtime
We
have used this type of methods every time we have assigned a supply
function to a context node, every time we have populated the context
attributes of the context nodes with initial values via supply function.
When a controller is called, these methods are called first. We have
seen that a supply function can be assigned to each context node of a
Controller.
Context node and supply function
The
Framework generates a corresponding supply function method.An
alternative for the supply function methods can be the wdDoInit Hook
method, if we know that the context is filled only once at
initialization and it is not invalidated afterwards.
Supply function
In
the Methods tab, we can create our own user-defined methods with or
without parameters. After creating a user-defined method, we can call it
in the same controller, by using the wd_this self reference.
In this case, we copy our example from the wdDoModifyView Hook method and we create two extra user-defined methods:
- A method named GREETING that has two import parameters
- A method named PERFORM_VALLIDATION that has one import parameter
In
the ONACTIONNEXT event handler method, we check whether the attribute
NAME is initial, respective if the user didn’t enter his first name. In
case of initial attribute, we call our own defined PERFORM_VALIDATION
method. By using this method, we show an error message. In case this
attribute is not empty, we call our own defined GREETING method to
create a greeting for the end user.
The
user-defined GREETING method. As we can see, this method has defined an
importing parameter named P_NAME of STRING type and an importing
parameter named P_NODE of ref to if_wd_context_node type. The P_NAME
parameter holds the value of the NAME attribute.
The user-defined
PERFORM_VALIDATION method. As we can see, this method has an importing
parameter named P_ELEMENT, referable to the interface
IF_WD_CONTEXT_ELEMENT.
In
this case, we have used the method REPORT_ATTRIBUTE_ERROR_MESSAGE of
the interface IF_WD_MESSAGE_MANAGER to report a Web Dynpro error message
to a context attribute.
The
ONACTIONNEXT event handler method. As we can see, the local variable
lv_name holds the value of the NAME attribute. If this attribute is
empty, we have to show an error message. To do this, we use our own
defined PERFORM_VALIDATION method.
User-defined GREETING method
User-defined PERFORM_VALIDATION method
wd_this->perform_validation(EXPORTING
p_element = lr_element). If this attribute is not initial, we use its
value as exporting parameter for our own defined method GREETING.
The onactionnext event handler method
METHOD onactionnext . DATA lr_node TYPE REF TO if_wd_context_node. DATA ls_data TYPE wd_this->element_person. DATA lv_name TYPE string. DATA lr_element TYPE REF TO if_wd_context_element. lr_node = wd_context->get_child_node('PERSON'). lr_element = lr_node->get_element( ). lr_node->get_attribute(EXPORTING name = 'NAME' IMPORTING value = lv_name). IF lv_name IS INITIAL. wd_this->perform_validation(EXPORTING p_element = lr_element). ELSE. wd_this->greeting(EXPORTING p_name = lv_name p_node = lr_node). ENDIF. ENDMETHOD.
Runtime
A
Fire method is a special kind of method generated by the Framework when
we define an outbound plug.We need inbound plugs and outbound plugs to
define the navigation between two views.These plugs are the entry and
the exit point for each view. We create an example,a WD component that
has two Views. The WD component structure is presented.
WD component structure
In
this case, we want to navigate from the view V_VIEW1 to the view
V_VIEW2, when the Framework triggers an event handler method, respective
when the user presses a button. In the COMPONENTCONTROLLER,we create a
context node PERSON, Cardinality 1...1,Singleton and one attribute NAME
of string type.
Context structure
The
data stored in the context of the component controller are used within
the two views V_VIEW1 and V_VIEW2, through context mapping.
View V_VIEW1 layout
View V_VIEW2 layout
When
the user presses the Next button,we want to navigate from the view
V_VIEW1 to the view V_VIEW2.The view V_VIEW1 will be replaced with the
view V_VIEW2. This navigation is possible through a navigation link
between the views, in the window.
Plugs and navigation
To set up navigation between our views, we must create an inbound plug for the view V_VIEW2 and an outbound plug for the V_VIEW1. In the Outbound Plug tab of the view V_VIEW1, we create an outbound plug named OP_TO_V_VIEW2.
Out bound plug
In the Inbound plug tab of the view V_VIEW2,we create an inbound plug named IP_V_VIEW2.
In bound plug
When
the user presses the Next button,the Framework triggers the event
handler method onactionnext.Every time we create an outbound plug for a
view,a special method is added to its interface. This method has the
statement FIRE_<NAME_OUTBOUND_PLUG>_PLG. To fire this method, we
can use the Web Dynpro CodeWizard or select an outbound plug when
creating an Action.
The event handler method has the following statement:
METHOD onactionnext . wd_this->fire_op_to_v_view2_plg( ). ENDMETHOD.
Creating an action
We
use the self-reference WD_THIS of the view controller to fire the
method FIRE_OP_TO_V_VIEW2_PLG that was added to this interface when we
have created the outbound plug.
All
the views within a window can be connected to each other by using
navigation links.To be able to create the navigation,we embed the views
in the window and then we drag & drop the outbound plug to the
inbound plug. We can also create navigation by right-clicking on the
output plug name.
Creating navigation link
At
runtime, when the user interacts with the view V_VIEW1, his interaction
will cause a request to the server.In response, the view V_VIEW1 will
be replaced with the view V_VIEW2. This is possible through the
navigation link defined between these views.
An event handler method responds to actions or to events. We have used this type of methods every time we have assigned an action to
an UI element.This kind of methods are special methods of a view
controller that has the prefix ONACTION followed by the action name. As
we have seen,the action is defined in the Action tab and the
corresponding event handler method is generated by the Framework.
Action and event handler method
We
can assign an action to an UI element that has an event, indifferent if
this UI element is created dynamically or at the design time.
Action and UI element
Let’s create an example where we use an event handler method implemented to respond to events of inbound plugs!
We
have seen that the outbound plugs are the starting point of navigation,
called in any method of the view controller by using the statement:
wd_this->FIRE_<NAME_OUTBOUND>_PLG( ).
This method allows also parameter transfer
wd_this->FIRE_<NAME_OUTBOUND>_PLG(PARAMETER = ‘value’).
In
this case, the PARAMETER has to be entered in the parameter table of
the view controller. For a better understanding,we create the same
example as for the fire methods, but in this case we show an error
message when the user doesn’t enter a value in the inputField UI
element.We will pass a reference to Message Manager from a view to
another view, via an outbound parameter. In the View_1 we add in the
parameter table,on the Outbound plug,a parameter named P_MM.
Defining the parameter for an Outbound Plug
When the user presses the Next button, the Framework triggers the event handler method onactionnext.
Event handler method
METHOD onactionnext . DATA: lr_api_controller TYPE REF TO if_wd_controller, lr_api_manager TYPE REF TO if_wd_message_manager. lr_api_controller ?= wd_this->wd_get_api( ). lr_message_manager = lr_api_controller->get_message_manager( ). wd_this->fire_op_to_v_view2_plg( p_mm = lr_message_manager). ENDMETHOD.
Inbound plug
We
don’t have the possibility to create a parameter for an Inbound Plug.In
this case, we use the event handler method HANDLEIP_V_VIEW2 to read the
value of the P_MM parameter.
When
an inbound plug is called, the handler method that is uniquely assigned
to this inbound plug is called. This method is automatically generated
in the view controller when the inbound plug is created.We find this
method in the Methods tab of the view V_VIEW2.
Event handler method
The
value of the parameter P_MM is passed by the outbound plug
OP_TO_V_VIEW2. To be able to read the value of this parameter, we have
to add the parameter P_MM to the signature of the event handler method
assigned to the inbound plug,i.e.the HANDLEIP_V_VIEW2 event handler
method.
Event handler method. Implementation
In
this way, the value of the P_MM parameter is known by the event handler
method and can be used to send a message in case the user doesn’t enter
a value in the InputField UI element.
Layout UI Elements
The
following section details and describes the Layout of the UI elements.
Here, we are going to present the various types of existent Layouts and
the modality to use them, either in static or in dynamic variant. The
layout helps us to manage the arrangement of the UI elements within
their parent container.
All
the UI elements within a view are hierarchy arranged. The node
ROOTUIELEMENTCONTAINER is the root of this hierarchy and all the UI
elements. within a view are children of this root container. It is of
TransparentContainer type and has initially assigned to it the
FlowLayout layout. In our first example, we have seen that we have the
possibility to change it from ransparentContainer into another UI
element, in case this one doesn’t have any children. Table shows the
layout UI elements that are available for arranging the UI elements in a
view, and the corresponding LayoutData. The layout is the abstract base
class of all the layout UI elements within Web Dynpro and has the
runtime class CL_WD_LAYOUT.
Layout and LayoutData UI element
The
layout data of an UI element are used to specify the position within a
container and have the runtime class CL_WD_LAYOUT_DATA.
Flow Layout
If
we use the FlowLayout layout, all the UI elements are displayed in a
line. Byusing the property WRAPPING of the container into which the UI
elements are going to be integrated, we can manipulate the modality of
putting these UI elements on screen. In case this property is ABAP_TRUE,
the UI elements that don’t enter in the first line are arranged bellow,
in another line, to automatically adapt to the client window. In case
of ABAP_FALSE, the UI elements are not automatically adapted to the
client window.
For
a better understanding, we create a Registration Form with three
fields: first name, last name and date of birth. The WD component
structure and the view layout are presented.
WD component structure and view layout
In View context, we create the same well-known STUDENT contextnode with the dictionary structure YSTR_PERSON.
ROOTUIELEMENTCONTAINER
and Group UI element are both UI elements of container type, which have
the FlowLayout layout in the default mode. Each UI element reference to
a LayoutData object and every UI element inserted within a container
must have the data layout that matches the respective container.
Layout and layout data
Runtime: wrapping ABAP_TRUE
As
we can see, the UI elements are arranged in a line. Because the
attributes of STUDENT context node are empty, the InputField’s UI
elements bound to these attributes are not shown. After the user presses
the Save Button, we show all the data that the user has entered in the
InputField UI elements. In this case, all the UI elements don’t enter in
a line anymore, because the client window is too small for that. The
elements that don’t enter in the first line are arranged below in
another line, to automatically adapt to the client window.
We
can see that, for the layout data, we can set two properties:
cellDesign that specifies the distance between rows and vGutter that
specifies the additional distance to the left edge. The default of these
values is cellDesign – padless (there is no distance between the row
and the edges) and vGutter – none (no additional distance). In case the
wrapping property is ABAP_FALSE, the UI elements that don’t enter in the
first line are not arranged below in another line, they are not visible
anymore.
Runtime: wrapping ABAP_FALSE
For
a dynamic manipulation, we can use the runtime class CL_WD_FLOW_DATA to
embedding the UI elements into the container that has a FlowLayout
layout.An example of using this class we have seen in the wdDoModifyView
example.
f
we use the GridLayout layout, all the UI elements are arranged in
container in a tabular grid with a fixed number of columns. We can
specify the number of columns in the grid by usingthe property colCount.
The number of rows depends on the number of the UI elements added to
the container.We create the same example, but in this case we use
GridLayout layout for the Group container.
Group container: GridLayout
We
arrange all the UI elements from the GRP Group UI element in two
columns.In this case, at runtime we have: As we can see,the number of
columns is two and the number of rows is five.We want the Save button to
remain alone in its row. To do this, we have to use an
InvisibleElement.
Runtime
This UI element is an invisible element on the screen and can be used to fill an empty cell in the GridLayout.
InvisibleElement and GridLayout
For
a dynamic manipulation, we can use the runtime class CL_WD_GRID_ DATA
to embedding the UI elements into the GRP container that has a
GridLayout layout.
UI elements into the GRP container that has a GridLayout layout
METHOD wddomodifyview. DATA lv_bind_attribute TYPE string. DATA lr_input_field TYPE REF TO cl_wd_input_field. DATA lr_container TYPE REF TO cl_wd_group. DATA lr_label TYPE REF TO cl_wd_label. DATA lr_grid_data TYPE REF TO cl_wd_grid_data. IF first_time EQ abap_true. lr_label = cl_wd_label=>new_label(id ='FIRSTNAME_LABEL' label_for ='FIRSTNAME' ). lr_grid_data = cl_wd_grid_data=>new_grid_data(element = lr_label). lr_container ?= view->get_element('GRP'). lr_container->add_child(index = 1 the_child = lr_label). lv_bind_attribute = 'STUDENT.FIRSTNAME'. lr_input_field = cl_wd_input_field=>new_input_field( id ='FIRSTNAME' bind_value = lv_bind_attribute). lr_grid_data = cl_wd_grid_data=>new_grid_data(element = lr_input_field). lr_container ?= view->get_element('GRP'). lr_container->add_child(index = 2 the_child = lr_input_field ). ENDIF. ENDMETHOD.
In
this example,we dynamically created the first two UI elements:
InputField for the user first name and the corresponding label. To embed
these UI elements into the GRP container (GridLayout),we use the proper
GridData layout.
If
we use the MatrixLayout, all the UI elements from a container are
arranged in columns. With MatrixLayout, we can produce a grid with a
variable number of columns per row. Each UI element inserted in a
container that has the MatrixLayout layout will contain either a
MatrixData object or a MatrixHeadData object.
Layout and layout data
An
UI element that has MatrixHeadData data layout starts a new row and the
UI elements that have MatrixData data layout are shown in the same row,
until an UI element is set MatrixHeadData and a new row is created.
UI elements arranged in a container by using a MatrixLayout layout
For
a dynamic manipulation, we can use the runtime class CL_WD_MATRIX_
HEAD_DATA and CL_WD_MATRIX_DATA to embed the UI elements into the GRP
container that has a MatrixLayout layout .
GRP container that has a MatrixLayout layout
METHOD wddomodifyview. DATA lv_bind_attribute TYPE string. DATA lr_input_field TYPE REF TO cl_wd_input_field. DATA lr_container TYPE REF TO cl_wd_group. DATA lr_label TYPE REF TO cl_wd_label. DATA lr_matrix_head_data TYPE REF TO cl_wd_matrix_head_data. DATA lr_matrix_data TYPE REF TO cl_wd_matrix_data. IF first_time EQ abap_true. lr_label = cl_wd_label=>new_label(id ='FIRSTNAME_LABEL' label_for ='FIRSTNAME'). lr_matrix_head_data = cl_wd_matrix_head_data=>new_matrix_head_data(element = lr_label). lr_container ?= view->get_element('GRP'). lr_container->add_child(index = 1 the_child = lr_label). lv_bind_attribute ='STUDENT.FIRSTNAME'. lr_input_field = cl_wd_input_field=>new_input_field(id ='FIRSTNAME' bind_value = lv_bind_attribute). lr_matrix_data = cl_wd_matrix_data=>new_matrix_data(element = lr_input_field). lr_container ?= view->get_element('GRP'). lr_container->add_child(index = 2 the_child = lr_input_field). ENDIF. ENDMETHOD.
If
we use RowLayout, all the UI elements from a container are arranged
into horizontal rows. Each UI element inserted in a container that has
the RowLayout layout will contain either a RowData object or a
RowHeadData object.
Layout and layout data
This
kind of layout is helpful when we want to arrange our UI elements into
horizontal rows,but where we don’t need a vertical alignment between the
resulting columns..
UI elements arranged in a container by using a RowLayout layout
For
a dynamic manipulation, we can use the runtime class CL_WD_ROW_
HEAD_DATA and CL_WD_ROW_DATA to embed the UI elements into the GRP
container that has a RowLayout layout..
GRP container that has a RowLayout layout
METHOD wddomodifyview. DATA lv_bind_attribute TYPE string. DATA lr_input_field TYPE REF TO cl_wd_input_field. DATA lr_container TYPE REF TO cl_wd_group. DATA lr_label TYPE REF TO cl_wd_label. DATA lr_row_head_data TYPE REF TO cl_wd_row_head_data. DATA lr_row_data TYPE REF TO cl_wd_row_data. IF first_time EQ abap_true. lr_label = cl_wd_label=>new_label(id ='FIRSTNAME_LABEL' label_for = 'FIRSTNAME'). lr_row_head_data = cl_wd_row_head_data = >new_row_head_data(element = lr_label). lr_container ?= view->get_element('GRP'). lr_container->add_child(index = 1 the_child = lr_label). lv_bind_attribute ='STUDENT.FIRSTNAME'. lr_input_field = cl_wd_input_field= new_input_field(id ='FIRSTNAME' bind_value = lv_bind_attribute). lr_row_data = cl_wd_row_data=>new_row_data(element =lr_input_field). lr_container ?= view->get_element('GRP'). lr_container->add_child(index = 2 the_child = lr_input_field). ENDIF. ENDMETHOD.
User Interface Elements (UI elements) Static and Dynamic Programming-part 1
The
UI elements we can use in the Web Dynpro ABAP are divided in various
categories.In this chapter, we are going to present some of the UI
elements, included in the categories:action, selection,layout, complex,
graphic and integration. Each UI element will be illustrated by an
example,showing the modality of using it either in static or in dynamic
variant.
A
UI element is a User Interface element we use to create a screen for
the end user. The UI Elements are grouped in categories we can access
via the View Layout,and each UI Element has some properties, as follows
- Common with other UI elements,inherited from superclasses
- Specific only for an UI element
- For example, the following properties are inherited:
- Tooltip: Shows a quick info text when the user passes the mouse pointer over the UI element
- Visible: Determined if an UI element is visible in the screen or not
- Enabled: Specified if the UI element is active or inactive
By
using the Class Builder transaction SE24, we can see different classes
along with their inheritances and attributes. For example, the class
CL_WD_UIELEMENT is the super class of all the UI elements we use in Web
Dynpro ABAP. Being super class, this class has
CL_WD_VIEW_ELEMENT. presents the tooltip,visible and enable properties
for an InputField UI element.
Most
of the UI elements properties can be bound to different context nodes
or attributes.In this way, we can manipulate the UI elements via the
data held in the context. Each bindable property of a UI element has a
certain type. For example,the enabled property can be bound to an
attribute of WDY_BOOLEAN type.
when
this attribute is set ABAP_TRUE, the respective UI element is
active.When this attribute is set ABAP_FALSE, the respective UI element
is inactive.
The
UI elements, along with the aggregations, determine the appearance and
behaviour of the UI elements on the screen. The Web Dynpro UI elements
are divided in categories. Hereunder, we present some of these
categories.
Graphic
This
category contains UI elements that help us to work with graphics
maps,etc. Hereunder,we present some of the UI Elements included in this
category.
Image
This
UI element enables us to integrate graphics in our WD application. Same
as other UI elements, it has some properties. Hereunder,we show a table
with some of the Image UI element properties that can be bound,and the
attribute type in case the property is bindable.
Some of the Image UI element properties
We
create a WD Component, where we can choose among three images and we
can manipulate the current image via the data held in the context.The WD
component structure is presented.
WD component structure
We
import three images in JPG format.As we have mentioned,to import an
image into a MIME folder,we have to choose Create Mime Object Import
from the contextual menu,shown by right-clicking on the WD component
name.
The
context node DYNAMIC is Singleton, cardinality 1...1. The attributes
WIDTH and HEIGH are STRING type and the attribute BORDER is I type. We
use these attributes to manipulate the properties of the Image UI
element. For the attributes WIDTH,BORDER and HEIGH, it is defined the
data binding to the properties (with the same names) of the UI element
Image.
Context structure and data binding
The
context node DROPDOWNBYINDEX has the dictionary structure
SHSVALSTR2,cardinality 0...n,Singleton.We have defined a data binding
between the attribute KEY and the property texts of the dropDownByIndex
UI element. The attribute VALUE is used to manipulate the property
source of the Image UI element.This property defines the name of the
image file shown on the screen.
View Layout structure
To
populate with values the context attributes of the context node
DROPDOWNBYINDEX, we use the supply function method shown in the Listing.
Supply function method
METHOD supply_dropdownbyindex. DATA: ls_image TYPE wd_this->element_drop down by index,lt_image LIKE TABLE OF ls_image. ls_image-key ='Germany'. ls_image-value ='deutschland.jpg'. APPEND ls_image TO lt_image. ls_image-key = 'France'. ls_image-value ='france.jpg'. APPEND ls_image TO lt_image. ls_image-key ='Italy'. ls_image-value ='italia.jpg'. APPEND ls_image TO lt_image. node->bind_table( new_items =lt_image set_initial_elements = abap_true). ENDMETHOD.
Runtime
Dynamic Programming
RUNTIME CLASS: CL_WD_IMAGE
Hereunder,we
present a table showing the correspondence between the view designer
name and the runtime name, with the proper types,in case of dynamic
programming of an Image UI element.
The implementation of a dynamic Image UI element contains the following statements:
Dynamic creation of an Image UI element
data lr_image type ref to cl_wd_image. data lr_image type ref to cl_wd_image. Ir_image = cl_wd_image=>new_image( id =‘IMG_IMAGE’ bind_width =‘DYNAMIC.WIDTH’ bind_height =‘DYNAMIC.HEIGHT’ bind_border =‘DYNAMIC.BORDER’ bind_source =‘DROPDOWNBYINDEX.VALUE’).
BusinessGraphics
This
UI element enables us to use several chart types in our WD
application.The Internet Graphics Service (IGS) helps us to work with
this UI element,being able to show graphics in a browser.
The
chart engine is a C++ library that supports chart types, from simple
charts (e.g. bars or pie) to complex charts(e.g. gantt).We create a WD
Component with the structure presented in Fig. By using the
BusinessGraphics UI element,we show the graphical illustration of the
data stored in our database table YPERSON.
WD component structure
Context structure
The
node person has the dictionary structure YPERSON, cardinality 1...n,
Singleton. From this structure,we choose only LASTNAME and AGE. We have
used a chart of columns type,to graphically display the data contained
by the columns of our database table.
View Layout
By
using the supply function, we populate the node PERSON with data from
the database table YPERSON. We select all the data from the two columns
LASTNAME and AGE.
Runtime
To
perform customizing settings for business graphics, we have to use the
SAP Chart Designer. We access this tool by double-clicking on the chart
picture, in the view layout. Now,the SAP Chart Designer is open and we
can customise our chart.
Chart designer
We
save the settings we made; the Framework generates a MIME file in XML
format and sets the property customizing of the BusinessGraphics UI
element.
Saving the customizing in a XML file
Runtime result
Dynamic Programming
RUNTIME CLASS: CL_WD_BUSINESS_GRAPHICS
Hereunder,we
present a table showing the correspondence between the view designer
name and the runtime name, with the proper types,in case of dynamic
programming of a BusinessGraphics UI element (Table). For a BusinessGra
. The Category object has the CL_WD_CATEGORY runtime class.The Series
can be Series,runtime
CL_WD_SERIES or SimpleSeries,runtime class CL_WD_SIMPLE_SERIES
CL_WD_SERIES or SimpleSeries,runtime class CL_WD_SIMPLE_SERIES
The
implementation of a dynamic BusinessGraphics UI element(with a
SimpleSeries and a Category)contains the following statements.
Dynamic creation of a BusinessGraphics UI element
METHOD wddomodifyview. DATA lr_flow_data TYPE REF TO cl_wd_flow_data. DATA lr_container TYPE REF TO cl_wd_uielement_container. DATA lr_businessgraphics TYPE REF TO cl_wd_business_graphics. DATA lr_category TYPE REF TO cl_wd_category. DATA lr_simpleseries TYPE REF TO cl_wd_simple_series. IF first_time EQ abap_true. lr_container ?= view->get_element('ROOTUIELEMENTCONTAINER'). lr_businessgraphics = cl_wd_business_graphics=>new_business_graphics(id = 'BGR' chart_type = cl_wd_business_graphics=> e_ chart_type-columns dimension = cl_wd_business_graphics=>e_dimension-two height = 300 width = 300 bind_series_source = 'PERSON' customizing = 'D57PJD6VB3MQAZR78XQHWTMIT.xml' ). lr_flow_data = cl_wd_flow_data=> new_flow_data(element = lr_businessgraphics). lr_container->add_child(lr_businessgraphics). lr_category ?= cl_wd_category=>new_category(id = 'CATEGORY' bind_description = 'PERSON.LASTNAME' tooltip ='Candidates last name' ). lr_simpleseries ?= cl_wd_simple_series=> new_simple_series(id ='SIMPLESERIES' label ='Candidate Age' bind_value ='PERSON.AGE' tooltip ='Candidate Age' ). lr_businessgraphics->set_category(the_category = lr_category). lr_businessgraphics->add_series(the_series = lr_simpleseries). ENDIF. ENDMETHOD.
The
UI elements that contain an action are included in this category.Some
of these UI elements we have already used (Button, LinkToAction).
Timed Trigger
This
UI element triggers automatically and periodically an event.To specify
the periodicity,we have to use its delay property. As we have mentioned
above, most of the UI element properties can be bound. Hereunder, we
show a table with some of the TimedTrigger properties that can be bound
and the attribute type in case the property is bindable
Some of TimedTrigger UI element properties
WD component
At
every 5 s, we trigger an event that uses a Function Module to generate a
random number under 1,000.In context view, we create a node named
COUNTER,cardinality 1...1,Singleton that has an attribute COUNTER_TT of i
type.
View layout
We have used an action named TRIGGER to specify the action to be triggered after the specified delay 5.
METHOD onactiontrigger. DATA lr_node TYPE REF TO if_wd_context_node. DATA ls_data TYPE wd_this->element_counter. DATA lv_step TYPE i. lr_node = wd_context->get_child_node('COUNTER'). CALL FUNCTION 'GENERAL_GET_RANDOM_INT' EXPORTING range = 1000 IMPORTING random = lv_step. ls_data-counter_tt = lv_step. lr_node->set_static_attributes(ls_data). ENDMETHOD.
The
Function Module GENERAL_GET_RANDOM_INT has an import parameter named
RANGE of i type and an exporting parameter named RANDOM of i type. This
function returns the random value with 0(RANDOM)(RANGE) At runtime.
runtime fig
Dynamic Programming
RUNTIME CLASS: CL_WD_TIMED_TRIGGER
As
we have seen,by using the wdDoModifyView( )Hook method we can
dynamically create an UI element. The same properties, events and
aggregations as in the View Designer are available. Hereunder,we present
a table showing the correspondence between the view designer name and
the runtime name, with the proper types,in case of dynamic programming
of a TimedTrigger UI element .
Dynamic programming
The implementation of a dynamic TimedTrigger UI element contains the following statements.
DATA lr_timed_trigger TYPE REF TO cl_wd_timed_trigger. lr_timed_trigger = cl_wd_timed_trigger=> new_timed_trigger(id ='TIMED_TRIGGER'delay = 5 on_action ='TRIGGER').
ButtonChoice
We
can use this UI element to choose among the various options offered by
the menu. Hereunder, we present a list with some of the ButtonChoice
properties that can be bound, and the attribute type in case the
property is bindable.
Some of the ButtonChoice UI element properties
We
create aWDapplication, where we use the ButtonChoice UI element to
offer to the end user a menu list with two options: power and divide. To
realise these calculations, we have used the methods of the class
CL_FOEV_BUILTINS.As we can see in Fig.this class has many calculation
methods,from the PLUS method (that performs a simple addition) to
functions,in order to obtain the Integer Part or Hyperbola Sinus.
Class CL_FOEV_BUILTINS
The structure of the POWER method
This
method has two importing parameters, named IM_ARG1 and IM_ARG2, and an
exporting parameter, named EX_RESULT, of float type. The method DIVIDE
has the same parameters.
For
this scope, we create our context node named CALCULATE, with the
context attributes ARG1 of f type, ARG2 of f type and RESULT of f type,
required to perform the calculations and to holdthe result.The WD
component structure and the view context structure are presented.
WD component structure and view context structure
The View layout
In
the ButtonChoice UI element, we insert two options: menuactionitem1 and
menuactionitem2.For the two created options, we set actions(divide and
power), and we use the hotkey property to offer to the end user the
capability to press the respective key combination to trigger the
associated event handler method.
When
the user interacts the first time with the ButtonChoice UI element,an
action can be selected,and the Framework triggers the proper event
handler method. The last selected action remains on the ButtonChoice UI
element after the action has been executed. This behaviour is possible
through the property repeat SelectedAction.
Some of the ButtonChoice UI element properties
The
Framework triggers the event handler method onactiondivide when the
user clicks the respective choice option button or he presses the CTRL_D
key combination. Listing shows the coding of this method.
METHOD onactiondivide. DATA lr_oref TYPE REF TO cx_foev_error_in_function. DATA ls_calculate TYPE wd_this->element_calculate. DATA lv_arg1 LIKE ls_calculate-arg1. DATA lv_arg2 LIKE ls_calculate-arg2. DATA lv_result LIKE ls_calculate-result. wd_this->attribute_get(IMPORTING p_arg1 = lv_arg1 p_arg2 = lv_arg2). TRY. cl_foev_builtins=>divide(EXPORTING im_arg1 = lv_arg1 im_arg2 = lv_arg2 IMPORTING ex_result = lv_result). CATCH cx_foev_error_in_function INTO lr_oref. ENDTRY. wd_this->attribute_set(EXPORTING p_result = lv_result). ENDMETHOD.
As
we can see, to read the context attributes ATR1 and ATR2, we use the
user defined method named ATTRIBUTE_GET that has two exporting
parameters.
To
pass the result of the division calculation into the context attribute
RESULT, we have used the user defined method ATTRIBUTE_SET that has an
importing parameter
User defined method required to read the context attributes
User defined method required to populate the RESULT attribute
Runtime for the Divide operation
To rise to power a number (number1 risen to number2), the Framework triggers the event handler method onactionpower (Listing).
METHOD onactionpower. ………….. TRY. cl_foev_builtins=power(EXPORTING im_arg1 = lv_arg1 im_arg2 = lv_arg2 IMPORTING ex_result = lv_result). CATCH cx_foev_error_in_function INTO lr_oref. ENDTRY. ENDMETHOD.
We
have used the static method POWER, of the calculation class
CL_FOEV_BUILTINS, to perform the number1 risen to number2 operation.To
read the context attributes ATR1 and ATR2, we call the same user defined
method ATTRIBUTE_ GET; to pass the calculation result, we call the
method ATTRIBUTE_SET. In this example, we have caught errors that can
occur, but we didn’t display their message to the user. The way we can
use try. . . endtry, the way we can raise, catch and display exceptions
will be detailed described.
Dynamic Programming
RUNTIME CLASS: CL_WD_BUTTON_CHOICE
Hereunder,we
present a table showing the correspondence between the view designer
name and the runtime name, with the proper types,in case of dynamic
programming of a ButtonChoice UI element.
Dynamic programming
The
implementation of a dynamic ButtonChoice UI element with one mean
action item, named DIVIDE, contains the following statements:
METHOD wddomodifyview. DATA lr_button_choice TYPE REF TO cl_wd_button_choice. DATA lr_flow_data TYPE REF TO cl_wd_flow_data. DATA lr_container TYPE REF TO cl_wd_uielement_container. DATA lr_menu_action TYPE REF TO cl_wd_menu_action_item. IF first_time EQ abap_true. lr_container ?= view->get_element('ROOTUIELEMENTCONTAINER'). lr_button_choice = cl_wd_button_choice=> new_button_choice( id = 'BTN_CHOICE' text = 'Choose' repeat_selected_action = abap_false ). lr_flow_data = cl_wd_flow_data=>new_flow_data(element = lr_button_choice). lr_container->add_child(lr_button_choice). lr_menu_action = cl_wd_menu_action_item=>new_menu_action_item (id ='MENUACTIONITEM1' text = 'Divide' on_action = 'DIVIDE' hotkey = cl_wd_menu_action_item=>e_hotkey-ctrl_p ). lr_button_choice->add_choice(the_choice = lr_menu_action). ENDIF. ENDMETHOD.
This
category contains UI elements that have selection options. Hereunder,we
present some of the UI Elements included in this category.
Drop Down By Key
This
UI element provides the end user with a dropdown list from where he can
choose only one entry. We create a WD Component named
Y_UI_DROPDOWNBYKEY with a view named V_VIEW and a window.
We
have many possibilities to populate with values the dropdown list.For
example,we can use a Domain defined in the ABAP Dictionary, we can use
the wdDoInit Hook method or a supply function method. For our example,
we use Y_COUNTRY_DOMAIN, domain that holds all the names of EU member
states.
The View layout is presented in fig
As
we have mentioned above, most of the UI element properties can be
bound. Hereunder, we present a table with some of the DropDownByKey
properties that can be bound, and the attribute type in case the
property is bindable.
Some of the DropDownByKey UI element properties
The
property selectedKey is mandatory; this means we have to realise data
binding at this attribute. The context structure is presented.
Context structure
We
have a context node with the cardinality 1. . .1 Singleton that has two
attributes. The KEY attribute is of Y_DEFORDOMAIN type,defined in the
ABAP Dictionary, and the RESULT attribute is of string type. We define a
data binding between the KEY attribute and the selectedKey property of
the DropDownByKey.
Data binding
If
the selectedKey property of the DropDownByKey UI Element is bound to
this attribute,the values stored in the attribute KEY are displayed in
the selection list.
We
use the attribute RESULT to show, in the textView UI Element,the
capital of the first two EU countries,from the dropdown list. After the
user chooses a value,the Framework triggers the event handler method
onactionselect_country.
the event handler method
METHOD onactionselect_country. DATA lr_node TYPE REF TO if_wd_context_node. DATA ls_data TYPE wd_this-element_dropdownbykey. DATA lv_value TYPE string. lr_node = wd_context-get_child_node('DROPDOWNBYKEY'). lr_node-get_attribute(EXPORTING name ='KEY'IMPORTING value = lv_value). CASE lv_value. WHEN 'AT'. ls_data-result ='Vienna'. WHEN 'BE'. ls_data-result ='Brussels'. WHEN OTHERS. ls_data-result ='Unknown'. ENDCASE. lr_node-set_static_attributes(ls_data). ENDMETHOD.
Runtime
Dynamic Programming
RUNTIME CLASS: CL_WD_DROPDOWN_BY_KEY
Hereunder,we
present a table showing the correspondence between the view designer
name and the runtime name, with the proper types,in case of dynamic
programming of a DropDownByKey UI element.
Dynamic programming
The implementation of a dynamic DropDownByKey UI element contains the following statements.
Dynamic creation of a Drop Down By Key UI element
DATA lr_dropdown_by_key TYPE REF TO cl_wd_dropdown_by_key. DATA lv_bind_attribute TYPE string. lv_bind_attribute = 'DROPDOWNBYKEY.KEY'. lr_dropdown_by_key =cl_wd_dropdown_by_key= new_dropdown_by_key(id ='DDK'bind_selected_key = lv_bind_attribute text_direction = cl_wd_dropdown_by_key=e_text_direction-ltr on_select = 'SELECT_COUNTRY').
Drop Down By Index
This
UI element provides the end user with a dropdown list from where he can
choose only one entry. This UI element doesn’t differ from the
DropDownByKey when displayed on the screen, the implementation being the
only difference. We create the same WD Component; in this case, we use a
dropDownByIndex UI element instead of the dropDownByKey.In Fig. we show
the context structure.In this case, we use a context node with the
dictionary structure SHSVALSTR2, cardinality 0...n, Singleton.
Context structure
View Layout
Here
under,we present a table with some of the DropDownByIndex properties
that can be bound,and the attribute type in case the property is
bindable.
Some of DropDownByIndex UI element properties
As
we can see,the texts property is mandatory. If this property of the
drop- DownByIndex UI Element is bound to the VALUE attribute, the values
stored in this attribute are displayed in the selection list. Listing
shows how we can populate the dropdown list with values via a supply
function method.
Supply function method
METHOD supply_dropdownbyindex. DATA: ls_country TYPE if_v_view=element_dropdownbyindex, lt_country LIKE TABLE OF ls_country. ls_country-value ='Austria'. ls_country-key ='Vienna'. APPEND ls_country TO lt_country. ls_country-value ='Belgium'. ls_country-key ='Brussels'. APPEND ls_country TO lt_country. node-bind_table(new_items = lt_country set_initial_elements = abap_true). ENDMETHOD.
Runtime
Dynamic Programming
RUNTIME CLASS: CL_WD_DROPDOWN_BY_IDX
Hereunder,we
present a table showing the correspondence between the view designer
name and the runtime name,with the proper types,in case of dynamic
programming of a DropDownByIndex UI element.
Dynamic programming
The implementation of a dynamic DropDownByIndex UI element
DATA lr_dropdown_by_index TYPE REF TO cl_wd_dropdown_by_idx. DATA lv_bind_attribute TYPE string. lv_bind_attribute ='DROPDOWNBYINDEX.VALUE'. lr_dropdown_by_index = cl_wd_dropdown_by_idx=new_dropdown_by_idx (id = 'DDI'bind_texts = lv_bind_attribute text_direction = cl_wd.
Radio Button Group By Index
This
UI Element includes some RadioButtons,allowing the user to select only
one value. Similar to the DropDown lists,we have here RadioButtons
grouped by key and by index. Indifferent of the type,they don’t differ
when they are displayed on the screen,but only in the implementation
part.
We
create the same WD Component as for the DropDownByIndex UI element;in
this case,we change the DropDownByIndex UI element withthe RadioButton-
GroupByIndex.The view context has the same structure. We create a
context node named RADIOBUTTONGROUP_I with the dictionary structure
SHSVALSTR2, cardinality 0. . .n, Singleton.
Hereunder,
we present a table with some of the RadioButtonGroupByIndex properties
that can be bound, and the attribute type in case the property is
bindable.
Some of the RadioButtonGroupByIndex UI element properties
View Layout
We
define the same data binding between the VALUE attribute and the texts
property of the RadioButtonGroupByIndex. If this property of the
RadioButton- GroupByIndex UI Element is bound to the VALUE attribute,
the values stored in this attribute are displayed in columns and rows.
To
specify the number of columns in which the RadioButtonGroup elements
are grouped, we can use the property colCount. In our case, we have set
“2”.This property can be personalised by an administrator.Listing shows
how we can populate the RadioButtons with values via a supply function
method (the same method as for the DropDownByIndex lists).
Supply function method
METHOD supply_radiobutton_i. DATA: ls_country TYPE wd_this-element_radiobuttongroup_i, lt_country LIKE TABLE OF ls_country. ls_country-value = 'Austria'. ls_country-key = 'Vienna'. APPEND ls_country TO lt_country. ls_country-value = 'Belgium'. ls_country-key = 'Brussels'. APPEND ls_country TO lt_country. node-bind_table( new_items = lt_country set_initial_elements = abap_true). ENDMETHOD.
Runtime
For the RadioButtonGroupByKey UI element, we have the same concept as described for the DropDownByKey.
Dynamic Programming
RUNTIME CLASS: CL_WD_RADIOBUTTON_GROUP_BY_IDX
Hereunder,
we present a table showing the correspondence between the view designer
name and the runtime name, with the proper types,in case of dynamic
programming of a RadioButtonGroupByIndex UI element.
Dynamic programming
The implementation of a dynamic RadioButtonGroupByIndex UI element contains the following statements:
Dynamic creation of a RadioButtonGroupByIndex UI element
DATA lr_radiobutton_group_by_index TYPE REF TO cl_wd_radiobutton_group_by_idx. DATA lv_bind_attribute TYPE string. lv_bind_attribute ='RADIOBUTTONGROUP_I.VALUE'. lr_radiobutton_group_by_index = cl_wd_radiobutton_group_by_idx=>new_radiobutton_group_by_idx( id = 'RDB_INDEX' bind_texts = lv_bind_attribute col_count = 2
on_select = 'SHOW’).
User Interface Elements (UI elements) Static and Dynamic Programming-part 2
User Interface Elements (UI elements) Static and Dynamic Programming-part 2
User Interface Elements (UI elements) Static and Dynamic Programming-part-3
Messages, Exceptions and Web Dynpro ABAP
Writing Multilanguage Applications
WebDynproModel
ALV and Select Options
Integrating a Web Dynpro Application into the SAP NetWeaver Portal
Web Dynpro and Authorization
Web Dynpro Mind Map
No comments:
Post a Comment