How to set breadcrumbs in UIU Applications
How to set breadcrumbs in UIU
Applications:
Please find
below the guidelines based on the implementation done in Service Order
Application (UI Component BT116H_SRVO) in order to fulfil the breadcrumb
requirements:
In the
following the term sync point is used, this means simply a place where we code
the “raise event history_trigger” for breadcrumb navigation.
Which sync points do we need (where is raise event history_trigger
written)?
According
to concept team guidelines we define sync point on search page and on overview
page (both header and item level). Currently we do not set this sync points if
we are in creation mode i.e. the root object is not yet persistent.
1) Sync Point for Search Page
We write
raise event history_trigger in method WD_DESTROY of the ViewSet of the search
page (see UI component BT116S_SRVO, View SearchViewSet, Method WD_DESTROY. Do
not forget to call also the method from the superclass.
Sample:
METHOD wd_destroy.
DATA: lr_tcc TYPE REF TO
cl_bt116s_s_bspwdcomponen_impl.
lr_tcc ?=
me->comp_controller.
IF
lr_tcc->gv_write_breadcrumb = abap_true.
RAISE EVENT history_trigger.
ENDIF.
CLEAR
lr_tcc->gv_write_breadcrumb.
CALL METHOD
super->wd_destroy.
ENDMETHOD.
What has to be done additionally?
You should
remove already existing places where event is raised, so that this does not
happen twice during roundtrip e.g. when navigation into overview page was done
or during event-call from advance search (create, copy, follow-up)
In our case
we faced the problem that the search view is also loaded and removed during
creation case or if you start the advance search in value-help mode. In that
cases we do not want to raise event history_trigger. To overcome this we added
a flag gv_write_breadcrumb in our component controller. This flag is set in
corresponding inbound plug of the window (IP_ADVSEARCH) and in the DO_VIEW_INIT_ON_RESTORE
method of the window controller.
2) Sync Point for Overview
Page
We write
raise event history_trigger in method WD_DESTROY of the ViewSet of the overview
page both for header and for item.:
Header: See UI componet BT116H_SRVO, View OVViewSet, Method
WD_DESTROY. Note, that we are using a generic superclass in our Header overview
pages. Do not forget to call also the method from the superclass! Note that we
do not raise the event if the root-object is not persistent.
Sample:
METHOD wd_destroy.
DATA: lr_cn TYPE REF TO cl_bsp_wd_context_node.
DATA: lr_ent TYPE REF TO
if_bol_bo_property_access.
FIELD-SYMBOLS: <lr_cn>
TYPE ANY.
* get root object from context
assign
me->context->('BTOrder') to <lr_cn>.
IF <lr_cn> IS ASSIGNED.
lr_cn ?= <lr_cn>.
lr_ent ?=
lr_cn->collection_wrapper->get_current( ).
ENDIF.
IF
cl_crm_uiu_bt_tools=>is_order_persistent( lr_ent ) = abap_true.
RAISE EVENT history_trigger.
ENDIF.
CALL METHOD
super->wd_destroy.
ENDMETHOD.
Item: See UI component BT140I_SRVP, View OVViewSet,
Method WD_DESTROY. Note, that we use here also a generic superclass for out
item overview pages. Do not forget to call also the method from the superclass
Sample:
METHOD wd_destroy.
DATA: lr_cn TYPE REF TO cl_bsp_wd_context_node.
DATA: lr_ent TYPE REF TO
cl_crm_bol_entity.
FIELD-SYMBOLS: <lr_cn>
TYPE ANY.
* get root object from context
ASSIGN me->context->('BTAdminI')
TO <lr_cn>.
IF <lr_cn> IS ASSIGNED.
lr_cn ?= <lr_cn>.
lr_ent ?=
lr_cn->collection_wrapper->get_current( ).
ENDIF.
IF lr_ent IS BOUND.
DO 3 TIMES.
lr_ent =
lr_ent->get_parent( ).
ENDDO.
IF cl_crm_uiu_bt_tools=>is_order_persistent(
lr_ent ) = abap_true.
* raise event for breadcrumbs
RAISE EVENT history_trigger.
ENDIF.
ENDIF.
CALL METHOD
super->wd_destroy.
ENDMETHOD.
What has to be done additionally?
Like in the
advance search you should remove existing coding where raise event
history_trigger was done e.g. during navigation or during event calls (create,
copy, follow-up).
In order to
load the proper order header or order item entity if you navigate back via
breadcrumb, it is necessary that you store your current entity in the so called
“state container” before leaving your component. If your component is then
called again, you use this information in order to restore the proper entities.
In our case we can navigate back to the header overview page but also to the
item overview page. Therefore we have to store not only the root object
(current order) but also the subobject (current item).
This is
done in the context class of our Window (see BT116H_SRVO, MainWindow) in
following methods, provided by the framework (re-definition required):
In the
following method we get the entity of
our current root object (btorder) on our current Item (btadmini) out of the
component controller and store this entities in the state container. Note that
im_name can contain any naming you like). This method is called if the component
is left.
METHOD if_bsp_wd_history_state~state_store.
DATA: lr_vc TYPE REF TO cl_bt116h_s_mainwindow_impl,
lr_cc TYPE REF TO cl_bt116h_s_bspwdcomponen,
lr_ent TYPE REF TO
cl_crm_bol_entity.
***
lr_vc ?= me->owner.
lr_cc ?= lr_vc->get_comp_controller( ).
lr_ent ?=
lr_cc->typed_context->btorder->collection_wrapper->get_current( ).
IF lr_ent IS BOUND.
state_container->add_item(
im_name = 'CurrentOrder'
im_value = lr_ent ).
ENDIF.
lr_ent ?=
lr_cc->typed_context->btadmini->collection_wrapper->get_current( ).
if lr_ent is bound.
state_container->add_item(
im_name = 'CurrentItem'
im_value = lr_ent ).
endif.
ENDMETHOD.
In the 2nd
Method we are receiving the info back which we have stored before. Therefore we
get the root object (btorder) and the subobject (btadmini) out of the state
container and then pass this entities to our component controller.
METHOD if_bsp_wd_history_state~state_restore.
DATA: lr_vc TYPE REF TO cl_bt116h_s_mainwindow_impl,
lr_cc TYPE REF TO cl_bt116h_s_bspwdcomponen,
lr_ent TYPE REF TO
cl_crm_bol_entity.
***
state_container->get_item(
EXPORTING im_name = 'CurrentOrder'
IMPORTING ex_value = lr_ent
EXCEPTIONS OTHERS = 0 ).
IF lr_ent IS BOUND.
lr_vc ?= me->owner.
lr_cc ?=
lr_vc->get_comp_controller( ).
lr_cc->typed_context->btorder->collection_wrapper->add(
iv_entity = lr_ent
iv_set_focus = abap_true ).
state_container->get_item(
EXPORTING im_name = 'CurrentItem'
IMPORTING ex_value = lr_ent
EXCEPTIONS OTHERS = 0 ).
IF lr_ent IS BOUND.
lr_cc->typed_context->btadmini->collection_wrapper->find(
iv_bo = lr_ent ).
ENDIF.
ENDIF.
ENDMETHOD.
What you should also keep in mind:
When
writing breadcrumb, there is a callback from framework to the application, we
you can control whether this breadcrumb should be written or not. This is done
via method IF_BSP_WD_HISTORY_STATE_DESCR~IS_RESTORABLE on View or Window
controller level. Via this method we make sure, that only breadcrumbs are
written for objects, which are persistent. See below sample from service order
(UI component BT116H_SRVO, Window controller)
METHOD if_bsp_wd_history_state_descr~is_restorable.
DATA: lr_comp TYPE REF TO cl_bt116h_s_bspwdcomponen_impl,
lr_current TYPE REF TO
if_bol_bo_property_access.
* only write breadcrumb entries in case the order was persisted
lr_comp ?=
me->comp_controller.
lr_current =
lr_comp->typed_context->btorder->collection_wrapper->get_current(
).
IF lr_current IS BOUND.
rv_result =
cl_crm_uiu_bt_tools=>is_order_persistent( lr_current ).
ELSE.
rv_result = abap_false.
ENDIF.
ENDMETHOD.
As the
comment in the method describes, we check , that a breadcrumb is only written,
if the current order is already on the database. As we do check this already in
the WD_DESTROY method, this is not absolutely required (we had this coding
already before the changes).
3) What has to be done in
generic components or reuse components?
Those
components must not set sync points e.g. during navigation from overview
assignment block to edit form/edit list..
Sample: UI
component BTPARTNER, View PartnerOV (Partner Assingmentblock in One-Order overview
pages – eventhandler method for navigation into edit view):
METHOD eh_onbtn_edit.
DATA:
lr_entity TYPE REF TO if_bol_bo_property_access,
lr_attributes TYPE crmst_uiu_partner_attr,
lr_parent TYPE REF TO cl_crm_bol_entity.
lr_entity ?= typed_context->relationname->collection_wrapper->get_current(
).
CALL METHOD
lr_entity->get_properties
IMPORTING
es_attributes =
lr_attributes.
lr_parent =
lr_attributes-partner_set.
IF lr_parent->is_locked( ) =
abap_false.
lr_parent->lock( ).
ENDIF.
RAISE EVENT history_trigger. REMOVE!!!
op_toedit( ).
ENDMETHOD.
4) What should not be done:
If
possible, keep the coding of your DONE/BACK button on your views as it is.
5) Additional Info:
Info from Concept Team about BACK
navigation (see slide 6 – 9): : \\dwdf029\CRM_UIU\30_UI_Concept\30_UI_Concept_final\33_Back_Navigation.ppt
Info from
Framework about state_store/state_restore methods
\\Dwdf029\crm_uiu\40_Framework\Guidelines\Compo\How
to restore a table state.doc
Post a Comment