D Guidelines for Creating Task Flows to Be Used in Oracle Composer-Enabled Pages

Task flows are reusable building blocks in Oracle ADF. Oracle WebCenter provides task flows for you, or you can build your own task flows and add them to your WebCenter application pages. When you add task flows to customizable pages (that is, Oracle Composer-enabled pages), users can personalize, customize, and edit these task flows at runtime. It is imperative that you design your task flows according to the rules set forth in Oracle WebCenter publications. Failure to do so can result in problems when the task flows are consumed in WebCenter pages, such as too much white space, too many scroll bars, or slow, jerky, and unpredictable responses when displaying large data sets.

To prevent these issues and provide a consistent user experience in terms of look and feel, layout design, and interaction, follow the instructions in this document for:

This appendix contains the following topics:

D.1 Guidelines for Effective Geometry Management and Pagination

Effective geometry management results in efficient sizing and placement of task flows on the page. If the task flows are not designed properly, you end up with pages that have a slow response time or lots of unnecessary scroll bars or white spaces between components. For example, if you include a task flow containing very little data inside a container that stretches it (for example, a Show Detail Frame component), there is a lot of white space below the data in the task flow. Poor design can also cause scrolling to be slow and unpredictable in a task flow with a table displaying a large amount of data. To avoid such issues, be sure to design your task flows so that they flow and use a conventional pagination model when displaying large data sets.

Follow the guidelines in this section when designing new task flows for WebCenter applications. Also, be sure to adhere to these guidelines when you edit existing WebCenter application task flows.

D.1.1 Guideline 1: Create Task Flows that Flow

To avoid unnecessary white spaces in your task flows, you must ensure that the task flow content flows and is not stretched by the task flow container. A stretching task flow is one that is stretched to the height of the container, whereas a flowing task flow is one whose height is determined by its content, rather than by a stretching container or by itself having a fixed height. A flowing task flow with a small amount of data is shorter than one with large amounts of data, as shown in Figure D-1.

Figure D-1 Difference Between a Task Flow that Stretches and One that Flows

Description of Figure D-1 follows
Description of "Figure D-1 Difference Between a Task Flow that Stretches and One that Flows "

To design a flowing task flow, you must ensure that:

  • The child component of the task flow does not have a fixed height.

  • The Show Detail Frame component surrounding the task flow region does not have a fixed height (specified using its contentStyle attribute).

The following two examples illustrate how you might include flowing components inside task flows.

D.1.1.1 Example 1: Oracle ADF Faces Table Component with Its autoHeightRows Attribute Set to a Specific Value

Add an Oracle ADF Faces Table component within the task flow and set the autoHeightRows attribute on the Table to a specific value. By defining this attribute, the table height is adjusted according to the content (flow behavior), rather than the table having a fixed height or being stretched into a container (stretch behavior). The autoHeightRows attribute setting results in table data being displayed as follows:

  • If you provide a value H for autoHeightRows, the table grows to a maximum of H rows.

  • If the number of records returned from the data source is less than H, the table height wraps to that number.

  • If the number of records is more than H, the table displays H rows and provides a scrollbar to view the remaining rows.

  • If the autoHeightRows attribute is not used, the table displays at a fixed default height irrespective of the amount of data displayed.

Instead of specifying a fixed value for the autoHeightRows attribute, you can also provide an EL value so that the attribute is populated based on some logic you specify. You can enable customization and personalization on the task flow and provide an option for users to specify a value for this attribute. A value specified using the personalization option overrides a value specified using the customization option.

Example D-1 shows the attributes of a sample ADF Faces table component that is included inside a task flow called recent-pages-task-flow-definition. The autoHeightRows attribute is set to an EL expression that references a Java bean, recentPagesBean. This bean contains the logic to populate this attribute with a value provided by the end user (either as a personalization or a customization).

Example D-1 The autoHeightRows Attribute on a Sample ADF Faces Table

<af:table value="#{pageFlowScope.recentPagesBean.pages}" 
          var="row" rowBandingInterval="0" id="t1" 
          rowSelection="none" columnBandingInterval="0" 
          width="100%" inlineStyle="border:none;width:100%;" 
          columnStretching="last" horizontalGridVisible="true" 
          verticalGridVisible="false"
          autoHeightRows="#{pageFlowScope.recentPagesBean.number_of_items_to_show_at_a_time}"
            contentDelivery="immediate"
           fetchSize="#{pageFlowScope.recentPagesBean.number_of_items_to_query}">
      . 
      .
      .    
</af:table>

For a detailed description of the sample task flow displaying personalization and customization options for specifying the autoHeightRows value, see Section D.3, "Example of a WebCenter Application Containing a Task Flow Created By Following the Guidelines."

To learn more about the autoHeightRows attribute, including requirements such as setting the contentDelivery attribute to immediate, see the tag documentation for <af:table> in the Oracle Fusion Middleware Tag Reference for Oracle ADF Faces.

D.1.1.2 Example 2: Oracle ADF Faces Iterator Component Inside a Panel Group Layout with a Scrolling Layout

Add a Panel Group Layout component within the task flow and set its layout attribute to scroll. Then add an Iterator inside the Panel Group Layout. Add your content inside the Iterator. The content from the Iterator flows inside the Panel Group Layout.

Since the height of the Panel Group Layout depends on the content from the Iterator, specify a minimum and maximum height for the component by using min-height and max-height in the Panel Group Layout's inlineStyle attribute.

D.1.2 Guideline 2: Limit the Number of Records Displayed in a Task Flow

To avoid a slow and jerky response when scrolling large data sets in your task flow, you must limit the number of records to be fetched from the data source at a time. For example, if you have included an ADF faces Table component inside your task flow, limit the number of records to be displayed in the table. Use the fetchSize attribute on the Table to specify the number of records to be fetched from the data source in a single query. If you specify a fetch size of N, only N records are sent to the client from the data source.

The fetchSize and autoHeightRows attributes together control the number of rows displayed in the table. The relationship between these attributes is as follows:

  • If fetchSize equals autoHeightRows, all records are displayed in the table.

  • If fetchSize is less than autoHeightRows, the table is cropped at the fetchSize value.

  • If fetchSize is greater than autoHeightRows, you can decide whether to display only as many records as the autoHeightRows value or provide pagination controls to display the remaining records. For example, you might include a More link at the bottom of the task flow or include pagination using Previous and Next links. For more information, see Section D.3, "Example of a WebCenter Application Containing a Task Flow Created By Following the Guidelines."

Figure D-2 shows the difference between two task flows containing tables with equal autoHeightRows and fetchSize values of 10 and 5. The task flows wrap to the number of records displayed.

Figure D-2 Difference Between Task Flows with Different Fetch Size Values

Two task flows showing 10 and 5 records

Instead of specifying a fixed value for fetchSize, you can provide an EL value so that the attribute is populated based on some logic you specify. You can enable customization and personalization on the task flow and provide an option for users to specify a value for this attribute. A value specified using the personalization option overrides a value specified using the customization option.

The following example shows the attributes of a sample ADF Faces Table component that is included inside a task flow called recent-pages-task-flow-definition. The fetchSize attribute is set to an EL expression that references a Java bean, recentPagesBean. This bean contains the logic to populate this attribute with a customization value provided by the end user.

<af:table value="#{pageFlowScope.recentPagesBean.pages}" 
          var="row" rowBandingInterval="0" id="t1" 
          rowSelection="none" columnBandingInterval="0" 
          width="100%" inlineStyle="border:none;width:100%;" 
          columnStretching="last" horizontalGridVisible="true" 
          verticalGridVisible="false"
           autoHeightRows="#{pageFlowScope.recentPagesBean.number_of_items_to_show_at_a_time}"
          contentDelivery="immediate"
           fetchSize="#{pageFlowScope.recentPagesBean.number_of_items_to_query}">
      . 
      .
      .    
</af:table>

For a detailed description of the sample task flow displaying a customization option for specifying the fetchSize value, see Section D.3, "Example of a WebCenter Application Containing a Task Flow Created By Following the Guidelines."

To learn more about the fetchSize attribute, see the tag documentation for <af:table> in the Oracle Fusion Middleware Tag Reference for Oracle ADF Faces.

D.1.3 Guideline 3: Specify a Minimum Height for the Task Flow

You can ensure that the task flow wraps to the height of the content by adhering to the first guideline, described in Section D.1.1, "Guideline 1: Create Task Flows that Flow."

To prevent the task flow from collapsing completely when there are no records, or seeming too short when there are only one or two records, specify a minimum height for the content.

For example, if your task flow contains a table with an autoHeightRows value specified, you can specify a min-height value using the table's inlineStyle attribute.

Figure D-3 shows a task flow displayed with a reasonable height even though it has only two rows.

Figure D-3 Task Flow with a Minimum Height Specified

Task flow with minimum height

D.1.4 Guideline 4: Include UI for Accessing Data Beyond the Display Limit

If a task flow is showing ten records, but the data source contains 100 records, you can design the task flow to do one of the following depending on the nature of data in the task flow:

  • Display only ten records.

    For example, a Popular Discussion Topics task flow may use this first option if it is considered sufficient to show the ten most popular topics and not necessary to let users see even the eleventh most popular topic.

  • Show a More link at the bottom of the task flow that opens a view with the ability to show more records.

    For example, the People Connections task flow on a WebCenter Spaces page displays a More link at the bottom.

  • Show a pagination control with Previous and Next links.

    For example, a Watched Discussion Topics task flow may display pagination controls, as users typically want to see all of their watched topics. Pagination is a common choice for task flows in which the data is not inherently ranked in order of importance or can be sorted in different ways, and where it is important to be able to access any record in the data set. The pagination control can be placed either above or below the content, depending on the nature of the content.

Figure D-4 shows the Watched Topics and Popular Topics task flows containing tables having a fetchSize of 5 but both having more than five records in the data source. The Watched Topics task flow displays five records with pagination at the bottom, but the Popular Topics task flow displays only five records with no UI option to view other records.

Figure D-4 Task Flows With and Without Pagination Controls

Task flows with more than 5 records

Pagination Specifics

Here are a few simple recommendations for creating a pagination control:

  • Add a pagination message in the format 1 to N of M [prev][next].

  • Align the pagination elements to the right so that the Previous and Next links do not move as you navigate pages.

  • Ensure that the Next or Previous option is grayed out when it is not required.

For an example of how to use pagination controls, see Section D.3, "Example of a WebCenter Application Containing a Task Flow Created By Following the Guidelines."

You can customize pagination controls using the following parameters:

  • Position of Previous and Next links

  • Labels for Previous and Next links, for example, Newer and Older

  • Icons used with Previous and Next links

  • The words or symbols used to represent to and of, for example, 1-5 of 100

  • Options for permitting random access, for example, Prev 1 2 3 ... Next Last

D.2 Guidelines for Efficient Use of Task Flow Parameters and Customization and Personalization Options

While creating a task flow, you can create parameters and provide options for users to customize and personalize the task flow. You can enable privileged users to customize the task flow for all users (customization) and edit the task flow's properties and parameters in Oracle Composer. You can enable all users viewing the page to customize their view of the page (personalization). This section provides guidelines for implementing task flow parameters and the customization and personalization options.

Table D-1 provides an overview of the various task flow editing options available to users.

Table D-1 Options Used to Define Task Flow Appearance and Behavior

Option Description When to Use Who can See It

Parameters

A small set of ideally scalar values, used to program a task flow or set its context.Each parameter must have a good display name and description (which must include possible values and examples).

Use for a context like the city or pin code so that you can add multiple instances of the task flow, each showing different information or programmed to show information based on receiving a value from the page, programmatically or using the URL.

In WebCenter Spaces, you can use a parameter for a context like group space name.

Precedence: 3

This value overrides built-in values in the task flow.

Power users (or users with Edit or Customize permission) can see parameters in Oracle Composer's Component Properties dialog while editing a page.

In WebCenter Spaces, moderators can see and edit task flow parameters.

When a WebCenter task flow is exposed as a portlet in Oracle Portal, page designers can see these parameters while setting up the portlet.

Customization/Preferences

These two are synonymous.Customizations are typically considered changes a business user makes to the task flow. These changes are available to all viewers of the page and are used to specify values for options defined in the task flow. For example, users can decide whether to display the author name or revision date for a document.

Preferences are referred to as a definition of the content in the task. For example, a query definition in the Document Viewer task flow, or a query in OmniPortlet.

Use these when the task flow must provide a user interface that assists the user in defining the task flow behavior. That is, when Lists of Values or specific UI components such as images or radio buttons guide the user better, or when the task flow setup is a multiple step wizard-style interface.

Such assistance cannot be provided through parameters because they are strictly scalar values, with no assistance other than a description.

Precedence: 2

If there is an identical parameter value (for example, group space name), customization overrides that value.

Business users (or users with Edit or Customize permission) editing a page in Oracle Composer can see the customization or preferences options.

Typically, customization or preferences options are available on the chrome surrounding the task flow in Edit mode. However, users with Edit or Customize permission can also see these options on the chrome in View mode of the page.

When a WebCenter task flow is exposed as a portlet in Oracle Portal, the page designer sees these as Edit Defaults options while setting up the portlet.

Personalization

A subset of the customization and preferences options. You cannot have personalization options that are not also customization options.

Use these to allow all viewers of the page to tweak and tune the visual aspects of the task flow or the amount of data shown to them. For example, to set the number of items to display.

Precedence: 1

If there is an identical customization value (for example, number of items), personalization overrides that value.

All end users with View permission can see these options.

Personalization options are available on the chrome surrounding the task flow. When WebCenter task flows are exposed as portlets in Oracle Portal, the Personalization options allow end users to tweak the same visual aspects.

Implicit Personalization

Options that are persisted for end users from session to session. Implicit personalization options are not available on the chrome surrounding the task flow, but are actions that can be performed directly in the body of the task flow. For example, sorting and column resizing are implicit personalization options.

Use these options sparingly and only for options that are frequently changing. Options like column resizing and sorting are available for free from Oracle ADF.

All end users with View permission on the page can perform personalizations.


To improve application performance, follow the guidelines in this section while implementing parameters and customization and personalization options in task flows.

D.2.1 Guidelines for Implementing Task Flow Parameters

At design time (in JDeveloper), you can create parameters by defining them in the task flow definition XML file. At runtime, users with Edit or Customize permission can edit task flow parameters in the Component Properties dialog in Oracle Composer. To provide a good user experience, you must adhere to the following guidelines when creating parameters:

  • Provide a display name that is meaningful.

  • Provide a description for each parameter, along with examples and the possible values it can take.

The following example shows the code to define a parameter called layoutStyle in the task flow definition file:

<input-parameter-definition>
  <name>layoutStyle</name>
  <description> Used to control whether the documents must display as a list, with icons, or with document details.  
Allowed values are list, icon, and detail.</description>
  <display-name>Layout Style</display-name>
</input-parameter-definition>

D.2.2 Guidelines for Implementing Customization

Users with Edit or Customize permission can access customization options from the chrome surrounding the task flow.

You must adhere to the following guidelines while implementing customization in your task flow:

  • Customization options must be a subset of the task flow's parameters.

  • Implement a view fragment within the task flow and expose an outcome to open this view in a separate dialog. For example, the control flow rule to invoke a view called advancedEditPopupView in a dialog is as follows:

    <control-flow-case>
      <from-outcome>dialog:advancedEditPopup</from-outcome>
      <to-activity-id>advancedEditPopupView</to-activity-id>
    </control-flow-case>
    

    Adhering to this guideline is mandatory for new task flows.

  • Implement a view fragment within the task flow and expose an outcome to transition inline to this view. For example, the control flow rule to invoke a view called advancedEditView within the same screen is as follows:

    <control-flow-case>
      <from-outcome>advancedEdit</from-outcome>
      <to-activity-id>advancedEditView</to-activity-id>
    </control-flow-case>
    

    Although you can implement a task flow in this way, it is recommended that you expose an outcome to open the view in a dialog.

  • Ensure that customizations are saved in the MDS level set up by the application. Unlike task flow parameters, which are stored in the task flow definition itself, customizations are saved in the Metadata Storage (MDS). If you do not explicitly specify the MDS layer to be used to save task flow customizations, customization metadata and the consuming application metadata may get stored in different layers.

    To ensure that customizations are saved to the same layer as application metadata, you must clone the application's MDS session in the task flow's preference file and reference that while configuring customization. For an example of how this is implemented, see Section D.3, "Example of a WebCenter Application Containing a Task Flow Created By Following the Guidelines."

D.2.3 Guidelines for Implementing Personalization

All users viewing the page can access personalization options from the chrome surrounding the task flow in View mode of the page.

You must adhere to the following guidelines while implementing personalization in your task flow:

  • Ensure that personalization options are a subset of the customization options you define on the task flow.

  • If a key aspect of the task flow is to show objects—for example, documents, users, or requests—then you must include a personalization option for users to set the maximum number of objects to display.

  • Implement a view fragment within the task flow, and expose an outcome to open this view in a dialog. For example, the control flow rule to invoke a view called simpleEditPopupView in a dialog is as follows:

    <control-flow-case>
      <from-outcome>dialog:simpleEditPopup</from-outcome>
      <to-activity-id>simpleEditPopupView</to-activity-id>
    </control-flow-case>
    

    Adhering to this guideline is mandatory for new task flows.

  • Implement a view fragment within the task flow and expose an outcome to transition inline to the view. For example, the control flow rule to invoke a view called simpleEditView within the same screen is as follows:

    <control-flow-case>
      <from-outcome>simpleEdit</from-outcome>
      <to-activity-id>simpleEditView</to-activity-id>
    </control-flow-case>
    

    Although you can implement a task flow in this way, it is recommended that you make a transition to bring this view up as a dialog.

  • Ensure that personalizations are written to the MDS level set up by the application. Unlike task flow parameters, which are stored in the task flow definition itself, personalizations are saved in MDS. If you do not explicitly specify the MDS layer to be used to save personalizations, personalization metadata and application metadata may get stored in different layers.

    To ensure that personalizations are saved to the same layer as application metadata, you must clone the application's MDS session in the task flow's preference file and reference that while configuring personalization. For an example of how this is implemented, see "Example of a WebCenter Application Containing a Task Flow Created By Following the Guidelines"

D.2.4 Guidelines for Implementing Implicit Personalization

Users perform implicit personalizations while using the task flow itself, by way of resizing, sorting table columns, and so on. Personalization options in this case are not invoked using dialogs and users may not even be aware that they are actually personalizing a page.

Adhere to the following guidelines while implementing implicit personalization:

  • Do not overload the task flow with implicit personalization attributes. Select a few key, frequently used attributes to expose as implicit. Infrequently used or complex attributes can be handled with explicit personalization.

  • Do not implement implicit personalization such that a dialog is invoked. Implicit personalization must be performed in the body of the task flow itself.

D.3 Example of a WebCenter Application Containing a Task Flow Created By Following the Guidelines

As a companion to this document, a sample application was developed using Oracle WebCenter Framework. This sample application, called RecentPages, is used as an example to illustrate how you can build a near-perfect task flow by adhering to the guidelines in this document. The RecentPages application contains a customizable page, Welcome.jspx, which contains a task flow named recent-pages-taskflow-definition created by following all the required guidelines.

This section only provides a high-level description of how the task flow was implemented. For detailed information about using task flows and Oracle Composer, see the following guides:

The RecentPages sample application is available for download from the Oracle WebCenter Suite 11g Demonstrations and Samples page on OTN at:

http://webcenter.oracle.com

The RecentPages WebCenter application contains the following projects:

  • A Model project

  • A ViewController project named RecentPagesTaskFlow that contains the recent-pages-task-flow-definition task flow

  • Another ViewController project named WebPages that contains the JSPX page in which the task flow is consumed

D.3.1 The RecentPagesTaskFlow Project

This project contains the task flow created by following the guidelines. The files of significance in this project are as follows:

  • The recent-pages-task-flow-definition.xml file

  • The mainView.jsff fragment

  • The simpleEditPopupView.jspx page

  • The advancedEditPopupView.jspx page

  • The recentPagesBean Java bean

  • The Preference Java bean

D.3.1.1 The recent-pages-task-flow-definition.xml File

This is an Oracle ADF task flow definition containing three views: mainView, simpleEditPopupView, and advancedEditPopupView. The task flow is designed such that mainView displays a list of recently created pages in the application, simpleEditPopupView displays a personalization option to all users, and advancedEditPopupView displays customization options to users with Edit or Customize permission.

The following table breaks down the code in recent-pages-task-flow-definition.xml and explains each snippet.

The outcomes from mainView to simpleEditPopupView and advancedEditPopupView are called dialog:simpleEditPopupview and dialog:advancedEditPopupView respectively. This is to ensure that the views open in separate dialogs, not inline. In addition, this task flow provides Refresh, Previous, and Next outcomes on mainView. The simpleEditPopupView and advancedEditPopupView views provide Save and Cancel outcomes.

The following table describes significant sections of code in the recent-pages-task-flow-definition.xml file.

Table D-2 Sections Of Code in the Task Flow Definition File

Code Description
<default-activity>mainView</default-activity>

Defining the default view for the task flow: mainView

<managed-bean>
  <managed-bean-name>recentPagesBean</managed-bean-name>
  <managed-bean-class>view.RecentPangesBean</managed-bean-class>
  <managed-bean-scope>pageFlow</managed-bean-scope>
</managed-bean>

Referencing the recentPagesBean Java bean that is associated with the task flow definition. This bean was created as part of the view package.

<view id="mainView">
  <page>/mainView.jsff</page>
</view>  
  <view id="simpleEditPopupView">  
  <page>/simpleEditPopupView.jspx</page>
</view>
  <view id="advancedEditPopupView">  
  <page>/advancedEditPopupView.jspx</page>
</view>

Mapping task flow views to pages or page fragments. For example, mainView is associated with mainView.jsff.

<control-flow-rule>
   <from-activity-id>mainView</from-activity-id>
   <control-flow-case>
       <from-outcome>refresh</from-outcome>
       <to-activity-id>mainView</to-activity-id>
   </control-flow-case>
   <control-flow-case>
       <from-outcome>dialog:simpleEditPoup</from-outcome> 
       <to-activity-id>simpleEditPopupView</to-activity-id>  
   </control-flow-case>  
   <control-flow-case>    
       <from-outcome>next</from-outcome>  
        <to-activity-id>mainView</to-activity-id>  
   </control-flow-case>
   <control-flow-case>    
        <from-outcome>previous</from-outcome>   
        <to-activity-id>mainView</to-activity-id>  
   </control-flow-case> 
   <control-flow-case>    
         <from-outcome>dialog:advancedEditPopup</from-outcome> 
         <to-activity-id>advancedEditPopupView</to-activity-id>  
   </control-flow-case>
</control-flow-rule>

Control flow rules from mainView. Each control flow case defines an outcome and a corresponding target view.

<control-flow-rule>
  <from-activity-id>simpleEditPopupView</from-activity-id>
   <control-flow-case>
        <from-outcome>save</from-outcome>
        <to-activity-id>mainView</to-activity-id>
   </control-flow-case>  
   <control-flow-case>  
         <from-outcome>cancel</from-outcome>
         <to-activity-id>mainView</to-activity-id>  
   </control-flow-case>
</control-flow-rule>

Control flow rules from simpleEditPopupView. Each control flow case defines an outcome and a corresponding target view.

<control-flow-rule> 
 <from-activity-id>advancedEditPopupView</from-activity-id>  
 <control-flow-case>  
   <from-outcome>save</from-outcome>    
   <to-activity-id>mainView</to-activity-id> 
 </control-flow-case>
 <control-flow-case>   
    <from-outcome>cancel</from-outcome> 
    <to-activity-id>mainView</to-activity-id>  
 </control-flow-case>
</control-flow-rule>

Control flow rules from advancedEditPopupView. Each control flow case defines an outcome and a corresponding target view.


D.3.1.2 The mainView.jsff Fragment

Figure D-5 displays a list of recently created pages in the application. At runtime, the list looks like this:

Figure D-5 The mainView Fragment in the Task Flow

Task Flow Main View

The design features of this view fragment are as follows:

  • The autoHeightRows attribute is defined on the table to control the number of items displayed in the table. The task flow then wraps to the height of the items displayed.

  • The fetchSize attribute is defined to control the number of items to be fetched from the data source and displayed in the table.

  • Pagination controls are included to display a message in the format "Items 1-4 of 25" along with previous and next icons.

Table D-3 describes significant sections of code in the mainView.jsff fragment.

Table D-3 The mainView Fragment Code

Code Description
<af:panelGroupLayout id="pgl1" layout="vertical">
    <af:outputText value="Shows recent pages in the application" id="ot1"/>

A single top-level component-Panel Group Layout.This component is designed to ensure that the task flow content flows vertically and always stretches horizontally. This allows geometry management.

<af:table value="#{pageFlowScope.recentPagesBean.pages}" var="row"              
    rowBandingInterval="0" id="t1" rowSelection="none"     
    columnBandingInterval="0" width="100%"              
    inlineStyle="border:none;width:100%;" columnStretching="last"              
    horizontalGridVisible="true" verticalGridVisible="false"
autoHeightRows="#{pageFlowScope.recentPagesBean.number_of_items_to_show_at_a_time}"
    contentDelivery="immediate"              
fetchSize="#{pageFlowScope.recentPagesBean.number_of_items_to_query}">

A table component that is a child of the Panel Group Layout.

Table attributes:

  • autoHeightRows (N): The number of items to display in the table at one time. An EL value is specified here such that a Java bean, recentPagesBean, populates this attribute with a value specified by the user at runtime.

    If there are more than N items to display, a scrollbar appears on the task flow.

  • fetchSize (M): The maximum number of items to be fetched from the data source. An EL value is specified here such that a Java bean, recentPagesBean, populates this attribute with a value specified by the user at runtime.

    If M is greater than N, pagination controls appear on the task flow to enable users to view the remaining items.

<af:column sortable="false" headerText="#{null}" align="start" id="c1">  
  <af:panelGroupLayout id="pgl11" styleClass="nowrap"
inlineStyle="padding-top:2px; font-weight:bold;">     
    <af:outputText value="#{row.title}" id="ot4"/> 
    <af:goLink destination="/faces#{row.contentMRef}"
               text=">>" targetFrame="_blank" id="gl1"/>  
   </af:panelGroupLayout>  
   <af:panelGroupLayout id="pgl10" styleClass="AFFieldTextDisabled nowrap"
                        inlineStyle="padding-top:2px">    
    <af:outputText value="Created on " id="ot7"/>    
    <af:outputText value="#{row.createDate}" id="ot8"/>    
    <af:outputText value=" by #{row.createdBy}" id="ot9"/>  
  </af:panelGroupLayout>
</af:column>

The table contains a single column that displays a list of pages in the application along with the creation date and author for each page.

Implicit personalization capability to sort the table column is turned off.

<af:panelGroupLayout id="pgl2" halign="end" layout="vertical" 
              inlineStyle="margin:1px"                                 
              rendered="#{pageFlowScope.recentPagesBean.showPageControl}">  
   <af:panelGroupLayout id="pgl3">    
     <af:outputText value="#{pageFlowScope.recentPagesBean.footerText}"  
               id="ot2"/>    
     <af:commandLink id="cl1"
               actionListener="#{pageFlowScope.recentPagesBean.previous}"   
               disabled="#{not pageFlowScope.recentPagesBean.showPrevious}"  
               action="previous">     
     <af:image source="#{pageFlowScope.recentPagesBean.showPrevious ? 
'/adf/webcenter/shuttleleft_ena.png' : '/adf/webcenter/shuttleleft_dis.png'}"              
                     id="i1" shortDesc="previous"/>   
     </af:commandLink>  
     <af:commandLink id="cl2"  
               actionListener="#{pageFlowScope.recentPagesBean.next}"  
               disabled="#{not pageFlowScope.recentPagesBean.showNext}"                   
               action="next">     
     <af:image source="#{pageFlowScope.recentPagesBean.showNext ? 
'/adf/webcenter/shuttleright_ena.png' : '/adf/webcenter/shuttleright_dis.png'}"                
                id="i2" shortDesc="next"/>    
      </af:commandLink>  
    </af:panelGroupLayout>
</af:panelGroupLayout>

Pagination controls to display records beyond those that are displayed in the table.

The recentPagesBean code defines what is displayed to users at runtime.


D.3.1.3 The simpleEditPopupView.jspx Page

Figure D-6 displays an option to select the number of items to be displayed in the task flow. All users viewing the page can personalize the task flow using this option. The value specified by a user is applicable only for that user's view of the page.

Figure D-6 The simpleEditPopupView Page

Simple Edit dialog

The following table describes significant sections of code in the simpleEditPopupView.jspx page.

Table D-4 Code in the Personalization Page

Code Description
<af:panelStretchLayout id="psl1">
  <f:facet name="center">
    <af:group id="group1">
      <af:panelFormLayout id="pfl1">
        <af:inputText label="Number of Items to show at a time"
                      id="it1"
     value="#{pageFlowScope.recentPagesBean.number_of_items_to_show_at_a_time}"
                      columns="3"/>
      </af:panelFormLayout>
      <af:panelGroupLayout id="pgl2"
                           layout="horizontal"
                           halign="right"
                        inlineStyle="width:500px;">
        <af:commandButton text="Save" id="cb1"
        action="#{pageFlowScope.recentPagesBean.saveSettings}"/>
        <af:commandButton text="Cancel" id="cb2"
                          action="cancel"
                actionListener="#{pageFlowScope.recentPagesBean.cancel}"/>
      </af:panelGroupLayout>
    </af:group>
  </f:facet>
</af:panelStretchLayout>

A single top-level Panel Stretch Layout component with a Group component in its center facet. Within this group are a Panel Form Layout and a Panel Group Layout.

The Panel Form Layout contains an Input Text component, which is populated with a value returned by recentPagesBean.

The Panel Group Layout contains two Command Button components called Save and Close, which are wired to events defined in recentPagesBean.


D.3.1.4 The advancedEditPopupView.jspx Page

This page displays customization options to users with Edit or Customize permission. At runtime, this page opens in a separate dialog and displays options to select the number of items to be displayed and number of items to be queried, and a check box to show or hide pagination controls.

Advanced Edit dialog

The following table describes significant sections of code in the advancedPopupView.jspx page.

Table D-5 Code in the Customization Page

Code Description
<af:panelStretchLayout id="psl1">
  <f:facet name="center">
    <af:group id="group1">
      <af:panelFormLayout id="pfl1">
        <af:inputText label="Number of Items to show at a time"
                      id="it1"
            value="#{pageFlowScope.recentPagesBean.number_of_items_to_show_at_a_time}" 
                     columns="3"/>
        <af:inputText label="Number of Items to Query" id="it2"
                       value="#{pageFlowScope.recentPagesBean.number_of_items_to_query}"
                      columns="3"/>
         <af:selectBooleanCheckbox label="Show Page Control"
                                    id="sbc1"
               value="#{pageFlowScope.recentPagesBean.showPageControl}"/>
      </af:panelFormLayout>
      <af:panelGroupLayout id="pgl2"
                           layout="horizontal"
                           halign="right"
                          inlineStyle="width:500px;">
        <af:commandButton text="Save" id="cb1"
                  action="#{pageFlowScope.recentPagesBean.saveSettings}"/>
        <af:commandButton text="Cancel" id="cb2"
                          action="cancel"
                actionListener="#{pageFlowScope.recentPagesBean.cancel}"/>
      </af:panelGroupLayout>
    </af:group>
  </f:facet>
</af:panelStretchLayout>

A single top-level Panel Stretch Layout component with a group component in its center facet. Within this group are a Panel Form Layout and a Panel Group Layout.

The Panel Form Layout contains two Input Text components and a Select Boolean Checkbox. These components are populated with values returned by recentPagesBean.

The Panel Group Layout contains two Command Button components called Save and Close, which are wired to events defined in recentPagesBean.


D.3.1.5 The recentPagesBean Java Bean

This Java bean contains the logic for the following:

  • Displaying a specific number of items in the table based on user input.

  • Handling the Save and Cancel events triggered from the simpleEditPopupView and advancedEditPopupView pages.

  • Rendering Previous and Next icons while implementing pagination.

  • Displaying the pagination message after retrieving the total number of pages.

  • Referencing the Preference bean that defines where customizations and personalizations must be saved.

You can find the code for this bean in the RecentPages application that is available for download from the Oracle WebCenter Suite 11g Demonstrations and Samples page on OTN at:

http://webcenter.oracle.com

The following table describes significant sections of code in the recentPagesBean.java file.

Table D-6 The recentPagesBean Java Bean Code

Code Description
private String _getPreferenceFileName()
  {
    String taskflowId = 
     ControllerContextFwk.getInstanceFwk().getCurrentViewPortFwk().getClientId();
    if (taskflowId == null)
    {
      taskflowId = 
         ControllerContextFwk.getInstanceFwk().getCurrentViewPortFwk().getParentViewPort().getClientId();
    }
    String preferenceFileName = 
     PREFERENCE_BASE + taskflowId.replace(".", "_") + ".xml";
    return preferenceFileName;
  }
  private static PageServiceBean getPageServiceBean()
  {
    String beanName = "pageServiceBean";
    Object bean = null;
    FacesContext ftx = FacesContext.getCurrentInstance();
    bean =  ftx.getExternalContext().getRequestMap().get(beanName);
     if (bean == null)
    {
      ELContext elContext = ftx.getELContext();
      ExpressionFactory exFactory = 
       ftx.getApplication().getExpressionFactory();
      ValueExpression expr = 
       exFactory.createValueExpression(elContext, "#{" + beanName + "}",PageServiceBean.class);
      bean = expr.getValue(elContext);
    }
    return (PageServiceBean) bean;
  }

Logic for identifying the task flow and retrieving the instance-level preference file for the currently running task flow.

public String saveSettings()  throws Exception
  {
    if (number_of_items_to_query != null &&
        !number_of_items_to_query.isEmpty())
    {
      Preference.setNumberOfItemsToQuery(_getPreferenceFileName(),
                                         Integer.parseInt(number_of_items_to_query));
    }
    if (this.number_of_items_to_show_at_a_time != null &&
        !this.number_of_items_to_show_at_a_time.isEmpty())
    {
      Preference.setNumberOfItemsToShow(_getPreferenceFileName(),
                                        Integer.parseInt(number_of_items_to_show_at_a_time));
    }
    if (_showPageControl != null)
    {
      Preference.setShowPageControl(_getPreferenceFileName(),_showPageControl);
    }
    AdfFacesContext.getCurrentInstance().returnFromDialog(null, null);
    return "save";
  }

Logic to define behavior of Save button in the personalization or customization dialog. Settings are saved in the task flow preference file.

public void setNumber_of_items_to_show_at_a_time(String number_of_items_to_show_at_a_time)
 {
    this.number_of_items_to_show_at_a_time = 
       number_of_items_to_show_at_a_time;
  }
  public String getNumber_of_items_to_show_at_a_time()
  {
    String query = 
     Integer.toString(Preference.getNumberOfItemsToShow(_getPreferenceFileName()));
    return query;
  }

Logic to populate the Number of Items to show at a time field in the personalization or customization dialog.

public void setNumber_of_items_to_query(String number_of_items_to_query)
  {
    this.number_of_items_to_query = number_of_items_to_query;
  }
  public String getNumber_of_items_to_query()
  {
    String query =
      Integer.toString(Preference.getNumberOfItemsToQuery(_getPreferenceFileName()));
    return query;
  }

Logic to populate the Number of Items to Query field in the customization dialog.

public boolean getShowPageControl()
  {
    boolean showPageControl =
      Preference.getShowPageControl(_getPreferenceFileName());
    return showPageControl;
  }
  public void setShowPageControl(boolean showPageControl)
  {
    _showPageControl = showPageControl;
  }

Logic to set the Show Page Control check box in the customization dialog.

public List<PageDef> getPages()
{
  PageServiceBean psb = getPageServiceBean();
   List<PageDef> pages = psb.getPages();
   int start = getStart();
   int end = getEnd();
  if (start < 0 || start > pages.size())
  {
   start = 0;
  }
  if (end < 0 || end > pages.size())
  {
    end = pages.size();
  }
  List<PageDef> tempPages = pages.subList(start, end);
  return tempPages;
}
public int getEnd()
{
  String items_to_query = this.getNumber_of_items_to_query();
  int offset = Integer.parseInt(items_to_query);
  int end = getStart() + offset;
  if (end > this.getTableSize())
  {
    end = getTableSize();
  }
  return end;
}

Logic to retrieve the list of pages to display in the current view of the table.

public int getTableSize()
{
  int tableSize = -1;
   try
  {
    PageServiceBean psb = getPageServiceBean();
     List<PageDef> pages = psb.getPages();
     tableSize = pages.size();
   }
  catch (Exception e)
  {
    System.out.println(e.toString());
  }
   return tableSize;
}

Logic to set the table size to the number of records retrieved.

public int getStart()
{
  String items_to_query =
 this.getNumber_of_items_to_query();
  int offset = Integer.parseInt(items_to_query);
  return (getPageNumber() - 1) * offset;
}
public int getPageNumber()
{
  Object page_num =
  RequestContext.getCurrentInstance().getPageFlowScope().get("page_num");
  int local_page_num = 1;
  if (page_num == null || (Integer) page_num <= 0)
    {
      local_page_num = 1;
    }
    else
    {
      local_page_num = (Integer) page_num;
    }
    return local_page_num;
  }
 
public void cancel(ActionEvent actionEvent)
  {
    AdfFacesContext.getCurrentInstance().returnFromDialog(null, null);
  }

Logic to define behavior of Cancel button in the personalization or customization dialog.

public void previous(ActionEvent actionEvent)
  {
    int page_num = getPageNumber();
    page_num--;
    if (page_num <= 0)
    {
      page_num = 1;
    }
    RequestContext.getCurrentInstance().getPageFlowScope().put("page_num", page_num);
  }

Logic to define behavior of Previous action in the task flow's pagination control.

public void next(ActionEvent actionEvent)
{
  int page_num = getPageNumber();
  page_num++;
  String items_to_query =
 this.getNumber_of_items_to_query();
  int offset = Integer.parseInt(items_to_query);
  int total_page_num = getTotalPageNumber();
  if (page_num > total_page_num)
  {
    page_num = this.getTableSize()
 / offset;
  }
   RequestContext.getCurrentInstance().getPageFlowScope().put("page_num",  page_num);
  }

Logic to define behavior of Next action in the task flow's pagination control.

public boolean isShowPrevious()
  {
    int page_num = getPageNumber();
    if (page_num <= 1)
    {
      return false;
    }
    else
    {
      return true;
    }
  }

Logic to render Previous icon

public boolean isShowNext()
  {
    int page_num = getPageNumber();
    if (page_num >= getTotalPageNumber())
    {
      return false;
    }
    else
    {
      return true;
    }
  }

Logic to render Next icon.

public int getTotalPageNumber()
  {
    String items_to_query =
     this.getNumber_of_items_to_query();
    int offset = Integer.parseInt(items_to_query);
    int total_page_num = this.getTableSize()
    / offset;
    if (getTableSize() % offset > 0)
    {
      total_page_num++;
    }
    return total_page_num;
  }

Logic to return the total number of pages.

public String getFooterText()
  {
    return "Items " + (this.getStart() + 1) + "-" + this.getEnd() + 
" of " + " " + this.getTableSize() + " ";
  }

Logic for returning pagination text in the format Items 1-4 of 25.


D.3.1.6 The Preference Bean

This Java bean is a wrapper that provides APIs to get and set attributes in the task flow preference file. It contains the logic for saving personalizations and customizations on this task flow instance in the same MDS layer as that used by the application. In this sample application, site-level customizations are stored in the mds/mdssys/cust/site/site directory. Therefore, the code in the Preference bean ensures that the application's MDS session is cloned and the task flow personalizations and customizations are stored in the same directory.

You can find the code for this bean in the RecentPages application that is available for download from the Oracle WebCenter Suite 11g Demonstrations and Samples page on OTN at:

http://webcenter.oracle.com

The following table describes significant sections of code in the Preference.java file.

Table D-7 The Preference Java Bean Code

Code Description
private static MDSSession _getClonedMDSSession()
  {
    MDSInstance instance = (MDSInstance) ADFContext.getCurrent().getMDSInstanceAsObject();
    MDSSession mdsSession = (MDSSession) ADFContext.getCurrent().getMDSSessionAsObject();
     mdsSession =
 instance.createSession(mdsSession.getSessionOptions(), mdsSession.getUserStateHandler());
    return mdsSession;
  }

Logic to clone the application's MDS session.

private static MetadataObject _readPreference(MDSSession mdsSession, String preferenceFileName)
  {
    MetadataObject mo = null;
    try
    {
      mo =
 mdsSession.getMutableMO(MOReference.create(preferenceFileName));
    }
    catch (MetadataNotFoundException mnfe)
    {
      _LOG.warning("Creating a new preference file " + preferenceFileName);
    }
    catch (ReferenceException re)
    {
      _LOG.warning("Creating a new preference file " + preferenceFileName);
    }
    catch (Exception e)
    {
      throw new RuntimeException(e);
    }
   // preference file is not available create a new one
    if (mo == null)
    {
      try
      {
        DocumentBuilderFactory builderFactory =
          DocumentBuilderFactory.newInstance();
        builderFactory.setNamespaceAware(true);
        builderFactory.setValidating(false); 
       DocumentBuilder builder =
 builderFactory.newDocumentBuilder();
        Document document =
          builder.parse(new ByteArrayInputStream(CONTENTS.getBytes()));
        mo =
 mdsSession.createMetadataObject(preferenceFileName, document);
        mdsSession.flushChanges();
        mo =
 mdsSession.getMutableMO(MOReference.create(preferenceFileName));
      }
      catch (Exception e)
      {
        throw new RuntimeException(e);
      }
    }
    return mo;
  }

Logic to read the preference file in the MDS session or create one, if required.

public static void setNumberOfItemsToShow(String preferenceFileName,
int numberOfItemsToShow)
  {
    MDSSession session = _getClonedMDSSession();
    MetadataObject mo = _readPreference(session, preferenceFileName);
    mo.getDocument().getDocumentElement().setAttribute("numberOfItemsToShow",
Integer.toString(numberOfItemsToShow));
   _flushChanges(session);
  }
  public static int getNumberOfItemsToShow(String preferenceFileName)
  {
    MDSSession session = _getClonedMDSSession(); 
    MetadataObject mo = _readPreference(session, preferenceFileName);
    String show =
      mo.getDocument().getDocumentElement().getAttribute("numberOfItemsToShow");
    return Integer.parseInt(show);
  }  

Logic to get and set the number of items to show in the table at a time.

public static void setNumberOfItemsToQuery(String preferenceFileName, 
int _numberOfItemsToQuery)
  {
    MDSSession session = _getClonedMDSSession();
    MetadataObject mo = _readPreference(session, preferenceFileName);
    mo.getDocument().getDocumentElement().setAttribute("numberOfItemsToQuery",
Integer.toString(_numberOfItemsToQuery));
    _flushChanges(session);
  }
  public static int getNumberOfItemsToQuery(String preferenceFileName)
  {
    MDSSession session = _getClonedMDSSession(); 
   MetadataObject mo = _readPreference(session, preferenceFileName);
    String query =
      mo.getDocument().getDocumentElement().getAttribute("numberOfItemsToQuery");
    return Integer.parseInt(query);
  }

Logic to get and set the number of items to query from the data source.

public static void setShowPageControl(String preferenceFileName, 
boolean showPageControl)
  {
    MDSSession session = _getClonedMDSSession();
    MetadataObject mo = _readPreference(session, preferenceFileName);
 mo.getDocument().getDocumentElement().setAttribute("showPageControl", 
Boolean.toString(showPageControl));
    _flushChanges(session);
  }
public static boolean getShowPageControl(String preferenceFileName)
  {
    MDSSession session = _getClonedMDSSession();
    MetadataObject mo = _readPreference(session, preferenceFileName);
    String pageControl =
      mo.getDocument().getDocumentElement().getAttribute("showPageControl");
    return Boolean.parseBoolean(pageControl);
  }

Logic to get and set whether to show page control on the task flow.

private static void _flushChanges(MDSSession session)
  {
    try
    {
      session.flushChanges();
    }
    catch (Exception e)
    {
      throw new RuntimeException(e);
    }
  }

Logic to save changes made to the task flow into the MDS session.If a sand box is set up in the MDS session, the changes are saved to the sand box. Else, they are permanently written to MDS.

private static final String CONTENTS =
 "<preference numberOfItemsToShow='5'
              numberOfItemsToQuery='10'
              showPageControl='true'
   xmlns='http://xmlns.oracle.com/apps/preference'/>";
}

Logic to display defaults in the Number of Items to show at a time and Number of Items to query fields and the Show Page Control check box. When a user first accesses an instance of the RecentPages task flow, a new preference file is created with this content.


The RecentPages project containing all these files is deployed to Oracle ADF and the task flow is then consumed in the customizable Welcome.jspx page in the WebPages project.

D.3.2 The WebPages Project

This project contains the Welcome.jspx page in which the recent-pages-task-flow-definition task flow is consumed.

D.3.2.1 The Welcome.jspx File

Welcome.jspx is a customizable page containing a Panel Stretch Layout component. The top facet of the Panel Stretch Layout contains a Change Mode Link and a Page Create task flow. The center facet contains a Page Customizable with a child Panel Customizable, which in turn contains a Show Detail Frame component with the recent-pages-task-flow-definition task flow.

The stretchContent and showResizer attributes on the Show Detail Frame are set to false and never respectively to ensure that this component does not stretch its child task flow.

Also, the refresh attribute is set to ifNeeded in the task flow binding. This is to ensure that customizations made to the page at runtime are reflected when users perform a refresh.

The Welcome.jspx page contains the following code:

<?xml version='1.0' encoding='US-ASCII'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
          xmlns:pe="http://xmlns.oracle.com/adf/pageeditor"
          xmlns:cust="http://xmlns.oracle.com/adf/faces/customizable">
  <jsp:directive.page contentType="text/html;charset=US-ASCII"/>
  <f:view>
    <af:document id="d1">
      <af:form id="f1">
        <af:panelStretchLayout id="psl1">
          <f:facet name="top">
            <af:panelGroupLayout layout="horizontal"
      xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
                                 id="pgl2">
              <pe:changeModeLink id="cml1"/>
              <af:spacer width="10" height="10" id="s2"/>
              <af:region value="#{bindings.pagecreatepage1.regionModel}"
                         id="r1"/>
              <af:panelGroupLayout id="pgl1"/>
            </af:panelGroupLayout>
          </f:facet>
          <f:facet name="center">
            <pe:pageCustomizable id="pageCustomizable1">
              <cust:panelCustomizable id="panelCustomizable1" layout="scroll">
                <cust:showDetailFrame text="Recent Pages" id="sdf1"
                 stretchContent= "never" showResizer="never">
                  <af:region value="#{bindings.recentpagestaskflowdefinition1.regionModel}"
                             id="r2"/>
                </cust:showDetailFrame>
              </cust:panelCustomizable>
              <f:facet name="editor">
                <pe:pageEditorPanel id="pep1"/>
              </f:facet>
            </pe:pageCustomizable>
          </f:facet>
          <f:facet name="start"/>
          <f:facet name="end"/>
        </af:panelStretchLayout>
      </af:form>
    </af:document>
  </f:view>
</jsp:root>

At runtime, the page appears as shown in Figure D-7.

Figure D-7 The Welcome.jspx Page

Welcome.jspx page at runtime

D.3.2.2 The adf-config.xml File

You can add a task flow inside a Show Detail Frame component and display the task flow's outcomes as actions on the chrome of the parent Show Detail Frame component. This is possible by defining custom actions on the parent Show Detail Frame component. You can define custom actions at the instance level where Custom Action components are added as child components of the Show Detail Frame, or at the global level where Custom Action elements are defined in the application's adf-config.xml file. Global custom actions are enabled on all Show Detail Frame instances in the application, but are displayed only when a Show Detail Frame instance contains the task flow as its child.

In this application, custom actions corresponding to the task flow's outcomes, dialog:simpleEditPopupView and dialog:advancedEditPopupView, are defined globally in the adf-config.xml file as follows:

<customizableComponentsSecurity xmlns="http://xmlns.oracle.com/adf/faces/customizable/config">
    <enableSecurity value="true"/>
    <customActions>
      <customAction action="refresh" text="Refresh" 
                    shortDesc="Refresh"
                    location="menu" rendered="true"
                    icon="/adf/pe/images/refresh_ena.png"/>
      <customAction action="dialog:simpleEditPoup" 
                    text="Simple Edit" 
                    shortDesc="Simple Edit" 
                    location="menu" 
                    rendered="#{!changeModeBean.inEditMode}"
                icon="/adf/pe/images/editproperties_ena.png"/>
      <customAction action="dialog:advancedEditPopup" 
                    text="Advanced Edit" 
                    shortDesc="Advanced Edit" location="menu" 
                    rendered="#{changeModeBean.inEditMode}"
                icon="/adf/pe/images/editproperties_ena.png"/>
    </customActions>
  </customizableComponentsSecurity>

D.3.3 Runtime Behavior

This configuration results in the following behavior at runtime:

  • All users see a Simple Edit action on the chrome surrounding the task flow while viewing the page.

    Simple Edit action on the Actions menu

    Clicking this action displays the personalization option in a separate dialog.

    figure
  • Users with Edit or Customize permission see an Advanced Edit action on the chrome surrounding the task flow while editing the page.

    Advanced Edit action

    Clicking this action displays customization options in a separate dialog.

    Advanced Edit Dialog

D.4 Conclusion

In WebCenter application pages containing task flows, task flow design can have a significant impact on application performance. Also, slow response time and inconsistent UI can lead to an unpleasant experience for application users. To ensure better performance and a good user experience for WebCenter application users, follow the guidelines in this document while implementing task flows to be consumed in the application.