WebDynpro ALV: Editable ALV using Property Binding
ALV UI elements are extensively used in WebDynpro
applications and a typical requirement would be to make certain cells in ALV
editable depending on a business condition.
We use to create a dedicated wdy_boolean attribute which
will be mapped to the actual field. So depending on our business condition we
enable('X') or disable the Boolean attribute and it will effectively open or
close our mapped alv cell.
In a scenario where we have huge number of alv cells(column
perspective) which needs to be open or close depending on different business
conditions, we will have to create that many number of wdy_boolean attributes.
This consequently results in a humungous context node which is mapped to the
alv (DATA) node. for eg: if we have 50 alv fields which opens or close
depending on respective fields condition, we would need to create 50
wdy_boolean attributes in addition to the actual alv fields.
SAP has understood this problem and has introduced the
concept of context property binding for ALV. So in this solution, Instead of
creating an additional attribute to determine whether the field is close or
open, We use the property of the fields attribute itself to determine whether
the cell is open of close.
Property Binding concept explained
by SAP:
https://help.sap.com/saphelp_nw04s/helpdata/en/31/3bc041a1236724e10000000a1550b0/frameset.htm
We need to create a WebDynpro ALV application which is used
to display SFLIGHT table.
Since our intention is to explain the concept of property
binding, we will use a simple scenario to open or close the PRICE cell in our
ALV depending on field SEATSMAX value.
Condition: If SEATSMAX > 300, then
Open the Price Cell
Else
Close the Price Cell
endif
1) Execute tcode>SE80 to open ABAP Development Workbench
2) Create a new webdynpro component (zwd_sflight_prop_binding)
3) click Yes ,Enter the description and execute
save it as a local object or package depending on your
requirement.
4) Now the component should be created as below.
5) Double click on the component and declare the usage of
alv component .
6) Now create the node which will be the structure for our
ALV (SFLIGHT in our example)
Create it in component controller context as below
Click on "Add Attributes from Structure"(this will
create the context node of same structure as SFLIGHT table.
Select All the fields and execute(Fields are selected on the
basis of your alv structure requirement).
Your context node "FLIGHT_NODE" should look as
below.
We will not be creating any wdy_boolean attribute to open or
close alv cells.
7) In the View Controller, Declare the usage of ALV
component and select the alv interface controller as below.
😎 go to the view context and copy the component controller
node "FLIGHT_NODE" by drag and drop.
The context node "FLIGHT_NODE" will be now
available in the view controller's context.
9) Now create the view layout.
Since our demo application has only an
alv(sufficient for the scenario), we need to just declare a view container
which will accommodate the alv view from alv component.
10) Attach ALV component interface view TABLE into our
component.
Click on the window which contains our view, drill down till
the view container and embed view TABLE from
ALV component as below.
11) Map our component node "FLIGHT_NODE" with the
DATA node of alv interface controller context.
Click on the component usage in the object hierarchy and
drill down till the interface controller, Double click on the interface
controller , Declare the usage of our component inside the interface controller
and map our node with the DATA node of ALV.
Map the nodes.
12) Now get the data from SFLIGHT table and populate the
data into the ALV on launch of the application.
the method create inputfld contains the code to create the
input field for field PRICE inside ALV.
The commented code lr_input_field->SET_READ_ONLY_FIELDNAME(
|{ 'PRICE' }:{ 'READ_ONLY' }| ) decides which field will determine
whether the cell is open or close. So in our case we have declared the
READ_ONLY property of the context attribute PRICE as the one which decides
whether the price cell is open or close.
13) Create the WebDynpro application(this completes how ALVs
are implemented)
Right Click on the component> Create Application
Our ALV output:
The column PRICE(Airfare) is open for all the records as of
now.
14) Now i am going to create a button and onaction event
handler method which will hold the code required for property binding(My
intention is to simplify the concept by modularization).
If SEATSMAX > 300, then
Open the PRICE Cell
Else
Close the PRICE Cell
endif.
15) So now in event handler method ONACTIONBINDING ,
write the logic to set the context property of PRICE attribute depending on the
SEATSMAX condition.
Now uncomment the code lr_input_field->SET_READ_ONLY_FIELDNAME(
|{ 'PRICE' }:{ 'READ_ONLY' }| ) in method CREATE_INPUTFLD.
16) Activate and Launch the application.
Before Binding:
The PRICE(airfare) field is currently open for all the rows.
Now click on button "Apply Property Binding" to apply the business
condition .
After Binding:
The Cells which has SEATSMAX field value greater than 300,
those are the only ones open for editing.
Source code for method CREATE_INPUTFLD
method
CREATE_INPUTFLD .
DATA: lo_INTERFACECONTROLLER TYPE REF TO IWCI_SALV_WD_TABLE,
lr_column TYPE REF TO cl_salv_wd_column,
lr_input_field TYPE REF TO cl_salv_wd_uie_input_field.
DATA lo_value TYPE ref to
cl_salv_wd_config_table.
data lo_cmp_usage type ref to
if_wd_component_usage.
lo_cmp_usage = wd_this->wd_cpuse_alv( ).
if lo_cmp_usage->has_active_component( )
is initial.
lo_cmp_usage->create_component( ).
endif.
lo_INTERFACECONTROLLER = wd_this->wd_cpifc_alv( ).
lo_value =
lo_interfacecontroller->get_model( ).
lr_column =
lo_value->if_salv_wd_column_settings~get_column('PRICE').
CREATE OBJECT lr_input_field
EXPORTING
value_fieldname = 'PRICE'.
lr_input_field->SET_READ_ONLY_FIELDNAME(
|{ 'PRICE' }:{ 'READ_ONLY' }| ).
lr_column->set_cell_editor( lr_input_field
).
lo_value->if_salv_wd_table_settings~set_read_only( value = abap_false
).
endmethod.
Source code for method ONACTIONBINDING
method
ONACTIONBINDING .
DATA lo_nd_flight_node TYPE REF TO
if_wd_context_node.
DATA lt_flight_node TYPE
wd_this->Elements_flight_node.
DATA lo_el_flight_node TYPE REF TO
if_wd_context_element.
DATA ls_flight_node TYPE
wd_this->Element_flight_node.
DATA lv_price TYPE
wd_this->Element_flight_node-price.
DATA lv_flight TYPE sflight.
DATA: lo_property type
if_wd_context_element=>t_property.
* navigate from
<CONTEXT> to <FLIGHT_NODE> via lead selection
lo_nd_flight_node =
wd_context->get_child_node( name = wd_this->wdctx_flight_node ).
*Get all the
records in the context node
lo_nd_flight_node->get_static_attributes_table(
importing table = lt_flight_node ).
lo_property =
if_wd_context_element=>e_property-read_only.
LOOP AT lt_flight_node
INTO lv_flight.
* alternative
access via index
lo_el_flight_node =
lo_nd_flight_node->get_element( sy-tabix ).
IF
lv_flight-seatsmax GT 300.
* set single
attribute property
lo_el_flight_node->set_attribute_property(
attribute_name = `PRICE`
property = lo_property
value = abap_false ).
ELSE.
* set single
attribute property
lo_el_flight_node->set_attribute_property(
attribute_name = `PRICE`
property = lo_property
value = abap_true ).
ENDIF.
ENDLOOP.
endmethod.
Bottom Line: You can use this property binding concept for variable of business scenario and avoid the creation of dedicated context attribute which can have serious implications on the performance of the application.
This approach will help a developer to keep the context nodesize to minimum and thus a better performing application.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
12 | |
11 | |
7 | |
5 | |
5 | |
4 | |
4 | |
3 | |
3 | |
3 |