74
<Insert Picture Here> 18 Invaluable Lessons About ADF-JSF Interaction FKA: What You Need To Know About JSF To Be Succesful With ADF Steven Davelaar twitter:@stevendavelaar blogs: blogs.oracle.com/jheadstart and blogs.oracle.com/ateam_webcenter Oracle Fusion Middleware Architects Team (the “A-team”)

Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Embed Size (px)

DESCRIPTION

18 Invaluable Lessons About ADF-JSF Interaction

Citation preview

Page 1: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

<Insert Picture Here>

18 Invaluable Lessons About ADF-JSF InteractionFKA: What You Need To Know About JSF To Be Succesful With ADF

Steven Davelaar twitter:@stevendavelaarblogs: blogs.oracle.com/jheadstart and blogs.oracle.com/ateam_webcenterOracle Fusion Middleware Architects Team (the “A-team”)

Page 2: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Agenda

• Worls’s most comprehensive Hello World Demo

Page 3: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Just Say Hello – JSF Lifecycle Initial

1. Restore View

UI Component Tree

RichPanelHeader

RichPanelGroupLayout

6. Render

Response

RichPanelGroupLayout

RichPanelFormLayout

RichInputText

RichInputDate

Page 4: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

JSF Lifecycle - Postback

1. Restore View

2. Apply Request Values

richInputText.setSubmittedValue(“Steven”)

richInputDate.setSubmittedValue(“04-12-2012”)

Page 5: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

JSF Lifecycle - Postback

1. Restore View

2. Apply Request Values

3. Process Validations

•Validate and convert (if needed) name and date

•Call richInputText.setValue() with converted value if valid

•Clear submittedValue

•Queue valueChange event (if applicable)

Page 6: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

1. Restore View

2. Apply Request Values

3. Process Validations

value=“#{viewScope.HelloBean.name}

value=“#{viewScope.HelloBean.date}

JSF Lifecycle Postback

4. Update Model

•Call HelloBean.setName with component value

•Call HelloBean.setDate with component value

•Clear submitted and (local) component value

Page 7: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

JSF Lifecycle Postback

1. Restore View

2. Apply Request Values

3. Process Validations

actionListener=“#{viewScope.helloBean.sayHello}

4. Update Model

•Call HelloBean.sayHello

5. Invoke Application

Page 8: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

JSF Lifecycle - Postback

1. Restore View

2. Apply Request Values

3. Process Validations

4. Update Model

5. Invoke Application

6. Render Response

Page 9: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Current Lifecycle Phase in JDeveloper

while Debugging

Page 10: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Just Say Hello – Reset Values

• Clicking the Reset button should not fire validation,

and should clear the Name and Date fields

• We need a lifecycle shortcut that bypasses validation

(both client-side and server-side) and model update

Page 11: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

JSF Lifecycle – Postback Immediate

• Lesson 1: An immediate command executes the

action and actionListener in phase 2. Apply Request

Values and then jumps to phase 6. Render

Response, skipping validation and model update

phases.

Page 12: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

JSF Lifecycle – Postback Immediate

1. Restore View

2. Apply Request Values

• richInputText.setSubmittedValue(“Steven”)

• richInputDate.setSubmittedValue(“04-12-2012”)

•Call HelloBean.reset

Page 13: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

JSF Lifecycle – Postback Immediate

1. Restore View

2. Apply Request Values

6. Render Response

• We clicked the Reset button9.

• Name and date are cleared in HelloBean9.

• But we still see the old values in the page!

• How come??

Page 14: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

JSF Lifecycle – Postback Immediate

• Lesson 2: When executing an immediate command, the

UI components do NOT re-evaluate their underlying

value binding, possibly showing stale data

• How to force the UI components to do this?

• Three options

• Use af:resetActionListener

• Use oracle.adf.view.rich.util.ResetUtils.reset()

• UIComponent.resetValue()

• On an individual UI component, the reset action

• Clears the submittedValue

• Clears local component value so value binding is re-evaluated

• Marks the component as valid

Page 15: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Using af:resetActionListener

• Easiest option, no Java method needed

• Automatically added when dragging and dropping a

Rollback operation from Data Control Palette

• Lesson 3: af:resetActionListener does NOT reset child

regions, use ResetUtils.reset() instead.

Page 16: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Using ResetUtils.reset(UIComponent

startComponent)

• Reset method takes one

parameter: the start UI

Component to reset

• However, this is not the REAL start component

• Is used to traverse up the component tree

• until a region, form, subform, popup, carrousel or

panelCollection is found

• that component is used as the real starting point

Page 17: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Agenda

• Worls’s most comprehensive Hello World Demo

Page 18: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions

• Suggest the type of greeting based on a person’s

name

Page 19: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Will this work?

Not reallyF..

Page 20: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Will

immediate=true work?

• No, model is no longer updated, getName() will return

null (or old model value): remember lesson 1!

• AND (wrong) greeting will NOT be displayed anyway:

remember lesson 2!

Page 21: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Challenges

• We need immediate=true to prevent premature

validation of greeting field and date field

• We need to refresh the greeting field properly

• We need somehow to get hold of value entered in

name fieldname field

• We do want required validation on name field

-----------------------------------------------------------------------

• We already learned how to refresh the greeting field

with underlying model value9..

• 9 we need to call resetValue on the greeting

inputText

Page 22: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Use Binding

Property to Refresh Greeting Field

Page 23: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Greeting Field

Refreshed

• At least the suggested greeting is displayed now,

although it is still the wrong default greeting because

getName() returns null in the suggest method

Page 24: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Side Step – More About Component

Binding

• The getter/setter methods generated by JDeveloper

when using binding property are wrong

• Code is not serializable, causing errors in clustered env.

• UI Tree not released properly, more memory usage

• UI component might be reused in UI Tree of another page

(fragment)(fragment)

• This can happen EVEN with request-scoped and

backingBean-scoped beans

• Lesson 4: Always use ComponentReference in

component binding getter/setter methods

• Lesson 5: Never use component binding in session-

scoped bean, even ComponentReference won’t be

safe then.

Page 25: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Side Step – Correct Code for

Component Binding Methods

Page 26: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Side Step – More About Component

Binding

• Component binding is often overly used

• Use UIManager pattern from Duncan Mills to avoid

unnecessary component binding

• https://blogs.oracle.com/groundside/entry/the_uimanager_pattern

• You can also find a component by id programmatically

using invokeOnComponent API

• See (google for) “ADF Code Corner sample 58”

• Starting UI component should be as low as possible in UI Tree,

starting at UIViewRoot can kill performance with large, multi-tab

pages

Page 27: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Challenges

• We need immediate=true to prevent premature

validation of greeting field and date field

• We need to refresh the greeting field properly

• We need somehow to get hold of value entered in

name fieldname field

• We do want required validation on name field

• -----------------------------------------------------------------------

• May be we can use a valueChangeListener on name

field?

• May be we can use immediate=true on the name

field?

Page 28: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Using a

ValueChangeListener

• ValueChangeListener fires in phase 3. Process

Validations

• That phase is skipped with immediate command

• Now, let’s set immediate=true on name field 9

Page 29: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Using a

ValueChangeListener

• Lesson 6: When immediate=“true” on an Editable UI

Component Component

• Component validation is processed in phase 2. Apply

Request Values

• The validated and converted value is stored on the

component

• valueChangeListener is also called in this phase

• YES, now it works!

• But wait 9.

Page 30: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Using

immediate on editable component

• If we enter all fields except name, then Reset button

no longer works!

• Why? Because of Lesson 6: component validation

takes place before the command action/actionListener

is executed. Arrrrggghhh!is executed. Arrrrggghhh!

Page 31: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Using

Immediate on Editable Component

• This makes setting immediate=“true on an editable UI

component pretty useless, because then the general

rule

“Validations are skipped when setting a command

component to immediate=“true”component to immediate=“true”

is no longer true!

• Lesson 7: Never set immediate=“true” on an editable

UI component, it prevents you from

cancelling/abandoning a page.

Page 32: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Back to the

Challenges

• We need immediate=true to prevent premature

validation of greeting field and date field

• We need to refresh the greeting field properly

• We need somehow to get hold of value entered in

name field name field

• We do want required validation on name field

-----------------------------------------------------------------------

• Not a solution: valueChangeListener and

immediate=true on name field

• New solution: we need to get the value entered for

name directly from the UI component

Page 33: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Use

Component Binding to Get Name Value

• YES, this works, and the reset button still works too!

• But wait9. it works too well9

• Method should not execute when name empty, or less than 4 chars

Page 34: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Use

Component Binding to Get Name Value

• We are using the raw, possibly invalid value by calling

getSubmittedValue() on the name field

• We need to do programmatically what normally

happens automatically

in phase 33. Process Validations

in phase 3

•Validate and convert (if needed) name and date

•Call richInputText.setValue() with converted value if valid

•Clear submittedValue

•Queue valueChange event (if applicable)

Page 35: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Use

Component Binding to Get Name Value

• Lesson 8: You can programmatically execute JSF

lifecycle phases 3 and 4 on a component:

• comp.processValidations(FacesContext.getCurrentInstance())

• comp.processUpdates(FacesContext.getCurrentInstance())

Page 36: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello Suggestions – Optimizing

Using Partial Page Rendering (PPR)

• When clicking the suggest button, only the greeting

field needs to be refreshed in browser.

• Easily implemented using ADF Faces PPR

Page 37: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Agenda

• Worls’s most comprehensive Hello World Demo

Page 38: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Sub Forms of Hello Saying

• It was quite a challenge to get this greeting

suggestion implemented

• Is there really no easier way to do this?

• The af:subform tag represents an independently

submittable region of a page. The contents of a submittable region of a page. The contents of a

subform will only be validated (or otherwise

processed) if a component inside of the subform is

responsible for submitting the page.

• Sounds promising, let’s try!

Page 39: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Sub Forms of Hello Saying – Try 1

Page 40: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Sub Forms of Hello Saying – Try 1

Page 41: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Sub Forms of Hello Saying –Try 1

Findings

• Lesson 9: Items not in any sub-form are still

processed in lifecycle when submitting a sub-form.

• Fix: put all items in sub-forms

• Lesson 10: Layout messed up when using sub form

• Fix: Each subform must contain its own panelFormLayout, • Fix: Each subform must contain its own panelFormLayout,

align accross panelFormLayouts using labelWidth property

• Submitting the main form, does not submit items in

sub-form

• Solution: set property default=“true” on the subform

Page 42: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Sub Forms of Hello Saying – Try 2

Page 43: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Sub Forms of Hello Saying – Try 2

Findings

• Suggest button now works with empty date!

• Layout cleaned up!

• Pressing enter key on name shows suggested greeting!

• But wait9. what is functionally different from previous

samples?

• Greeting field is not required, what if we fix that?

Page 44: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Sub Forms of Hello Saying – Try 2

Findings

• Let’s try to move greeting field to other subform

Page 45: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Sub Forms of Hello Saying – Try 3

Page 46: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Sub Forms of Hello Saying – Try 3

Findings

• No validation error on greeting field!

• But greeting no longer shown

• Lesson 11: Partial page refresh does not work across

sub-forms

• Sub forms do not work for this use case �

Page 47: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Sub Forms of Say Hello - Conclusion

• Sub forms can be used in corner cases to avoid

premature validation

• Sub forms most useful for “default command” behavior

Page 48: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Agenda

• Worls’s most comprehensive Hello World Demo

Page 49: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Auto-Suggested Hello Saying

• Auto-suggest the type of greeting when tabbing out

the name field

Page 50: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Auto-Suggested Hello Saying – Will

this work?

• Will field validations fire prematurely?

• Will greeting field be refreshed correctly?

Page 51: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Auto-Suggested Hello Saying – ADF-

optimized lifecycle

• Using autoSubmit = true on an editable UI

Component kicks of the ADF-Optimized JSF Lifecycle

• This optimized lifecycle always:

• fires a partial submit

• By default will only process and refresh the autoSubmitted• By default will only process and refresh the autoSubmitted

component itself

• Additional UI components will be processed in this lifecycle

when partialTriggers property points to autoSubmitted item

• So, with code in previous slide no premature

validations fire but greeting field is not refreshed

• So, what will happen when we add partialTrigger

property to greeting field?

Page 52: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Auto-Suggested Hello Saying –

Refreshing Greeting Field

• Greeting field now processed as well -> validation

error when null

• Solutions:

1. make greeting optional

2. add greeting programmatically as partial target

Page 53: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Auto-Suggested Hello Saying – Making

Greeting Optional

• Making greeting optional seems to work

• But it doesn’t work always 9

• It does not work when user clears greeting first

• User clears existing greeting

• User navigates back to name field and changes the name• User navigates back to name field and changes the name

• User tabs out name field, nothing happens!

• Why??

Page 54: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

What happens when greeting is cleared

1. Restore View

2. Apply Request Values

3. Process Validations

•Calls valueChangeListener method HelloBean.nameChanged which in turn calls.setGreeting(“Hi”)

Page 55: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

1. Restore View

2. Apply Request Values

3. Process Validations

What happens when greeting is cleared

4. Update Model

•Calls HelloBean.setGreeting(null)

•Overrides the value set by valueChangeListenermethod F.

Page 56: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

How to prevent suggested greeting is

overridden again

• The JSF Model Update phase only updates

underlying model value when the local component

value differs from the model value

• We need to reset the local UI Component value in

namedChanged methodnamedChanged method

Page 57: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Auto-Suggested Hello Saying –

Refreshing Greeting Field In Code

Page 58: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Auto-Suggested Hello Saying –

Lessons Learned

12.Auto-submitted fields use ADF optimized lifecycle

preventing premature validation on other fields

13.The components that are processed by ADF optimized

lifecycle can be configured using partialTrigger

property. This is known as Cross Component Refreshproperty. This is known as Cross Component Refresh

14.Values set in value change listeners might be

overridden in model update phase if not coded

correctly

15.Use programmatic PPR instead of partialTriggers

property to prevent components to be processed by

ADF optimized lifecycle, avoiding premature validation

Page 59: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Agenda

• A bit more on the ADF optimized lifecycle

Page 60: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

ADF Optimized Lifecycle

• ADF Faces sets boundaries on the page that allow

the JSF lifecycle to run just on components within the

boundary

• As we learned before, when autosubmitting an

editable field, the boundary is the component itselfeditable field, the boundary is the component itself

• Boundaries can be changed by using partialTriggers

property

Page 61: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

ADF Optimized Lifecycle

• A number of component events always trigger the

optimized lifecycle

• Events on table, treeTable: disclosureEvent, selectionEvent,

rangeChangeEvent, columnSelectionEvent, etc

• Events on tree: disclosureEvent, selectionEvent

• Events on showDetailIHeader: disclosureEvent

• Events on panelAccordion (showDetailIItem) :

disclosureEvent

• Events on components inside panelCollection (toolbar,

context menu, etc)

• 9

Page 62: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Optimized Lifecycle of Employees –

Overflow Right

• When clicking on another row

• Overflow area should be refreshed

• Changes in overflow area should be preserved

Page 63: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Optimized Lifecycle of Employees –

Configuring optimized lifecycle

• When clicking on another row, changes in overflow

area are now preserved

Page 64: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Optimized Lifecycle of Employees –

Adding New Employee

• Clicking the New Employee button should also preserve

changes made in table overflow area

• Easy9 works out-of-the-box

• Now, let’s move that button to panelCollection toolbar

Page 65: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Optimized Lifecycle of Employees –

Adding New Employee

• Now, it will NOT work out-of-the-box

• Button inside panelCollection will trigger optimized lifecycle

• Changes in table overflow area will not be submitted

• What is the “obvious” fix?

Page 66: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Optimized Lifecycle of Employees –

Adding New Employee

• “Obvious” fix is to add button id to partialTriggers

property of panelFormLayout

• Lesson 16: To add components that should be

processed in optimized lifecycle, the partialTrigger

property must point to the boundary component

• In this use case, the boundary component of the

optimized lifecycle is the panelCollection

• So, “obvious” fix does not work, this will work:

• Note that you can use cascading partialTriggers

• If panelCollection partialTriggers property refers to table,

panelFormLayout only needs to refer to panelCollection

Page 67: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Agenda

• Worls’s most comprehensive Hello World Demo

Page 68: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello with a Song

Page 69: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello with a Song

• Choose Song checkbox will need autoSubmit = true

• Question 1: Can we use a partialTrigger property or

do we need programmatic PPR to show/hide the

Song drop-down list?

• Song selectOneChoice will need autoSubmit = true• Song selectOneChoice will need autoSubmit = true

• Question 2: Can we use a partialTrigger property or

do we need programmatic PPR to show/hide the

YouTube video frame?

Page 70: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello with a Song

• Choose Song checkbox will need autoSubmit = true

• Question 1: Can we use a partialTrigger property or

do we need programmatic PPR to show/hide the

Song drop-down list?

• Song selectOneChoice will need autoSubmit = true• Song selectOneChoice will need autoSubmit = true

• Question 2: Can we use a partialTrigger property or

do we need programmatic PPR to show/hide the

YouTube video frame?

Page 71: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello with a Song – Try 1

• Will this work?

Page 72: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello with a Song

• Lesson 17: To show/hide a component, the parent

component should be refreshed

• Answer 1: we need to refresh the enclosing

panelFormLayout to see the song selectOneChoice

• Using partialTrigger would cause premature validation errors • Using partialTrigger would cause premature validation errors

(lesson 15), so we use programmatic PPR

• Answer 2: No validation issues, we can safely use

partialTriggers property

Page 73: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Say Hello with a Song – Correct Code

Page 74: Adf Jsf Interaction 18 Lessons 121209082102 Phpapp02

Final Recommendation

• Lesson 18: write previous 17 lessons down, print

them, put them on the wall, learn them by heart, and

rehearse them every week, it will save you tons of

frustration!