Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

Reset EditableValueHolders which are not covered by ajax execute before ajax render #1060

Closed
glassfishrobot opened this issue Dec 9, 2011 · 15 comments

Comments

@glassfishrobot
Copy link

Background:

Problems:

  • When an EditableValueHolder component is in an invalid state or has only its local value set, and an ajax request needs to render the component while it is not included in the execute, then the original/updated model value won't be displayed, but instead the originally submitted value or the local value will be displayed. This is not intuitive.

Enhancement request:

  • When JSF needs to render an EditableValueHolder component by an ajax request, and that EditableValueHolder component is not included in the execute of the ajax request, then JSF should invoke EditableValueHolder#resetValue() on it in order to display the proper model value.

Affected Versions

[2.0]

@glassfishrobot
Copy link
Author

Reported by @BalusC

@glassfishrobot
Copy link
Author

Issue-Links:
duplicates
JAVASERVERFACES_SPEC_PUBLIC-1129
is related to
JAVASERVERFACES_SPEC_PUBLIC-1129

@glassfishrobot
Copy link
Author

wrschneider99 said:
A common usage pattern is <h:commandLink> with execute=@this.

I'm often hitting this issue when the component I want updated was actually valid, but had been submitted previously with some other invalid component using execute=@Form.

@glassfishrobot
Copy link
Author

@arjantijms said:
It would be absolutely great if the enhancement BalusC requests could be implemented. This is an often recurring source of confusion when working with AJAX and multiple dialogs.

See this for another related source: http://community.jboss.org/message/620000

@glassfishrobot
Copy link
Author

@edburns said:
I am open to changing the spec for this, but I must ask, if you want to render the component, why is it not listed in a "render" attribute?

@glassfishrobot
Copy link
Author

wrschneider99 said:
at least in my case, the component that I want updated is in a "render" attribute, and is being re-rendered as a partial update; the issue is that the value picked up during render is not refreshing from the model/backing-bean when I expected it to.

@glassfishrobot
Copy link
Author

ova2 said:
Hi. I'm not sure if we need this as standard behavior. Sometimes you want to preserve and sometimes reset values. Do you know ResetEditableValues component in PF Extensions? http://fractalsoft.net/primeext-showcase-mojarra/views/resetEditableValues.jsf Similar stuff exists in ADF Faces with af:resetListener and MyFaces Tomahawk, but pe:ResetEditableValues is much cleaner and better. It uses visitTree() to gather ResetEditableValues, by the way. I integrated this feature from pe:resetEditableValues into p:masterDetail first. As default built-in behavior. But after that I have figured out that there are use cases where we need to use JSF standard behavior and not to reset values. So, for pe:masterDetail I ended up with two attributes "preserveInputs" and "resetInputs". Here this use case (partially): http://fractalsoft.net/primeext-showcase-mojarra/sections/masterDetail/complexNavigation.jsf

"preserveInputs"
Specifies comma or blank separated list of clientIds of editable components whose inputs have to be preserved while levels get switched. @ALL is allowed and means all values within master detail have to be preserved. It makes sense e.g. if corresponding command component has "immediate"=true attribute. If nothing specified, input values gets cleared.

"resetInputs"
Specifies comma or blank separated list of clientIds of editable components whose inputs have to be cleared while levels get switched. @ALL is allowed and means all values within master detail have to be cleared. If takes precedence over clientIds in preserveInputs.

I wanted to say that this should be configurable when will be introduced into the core JSF stuff. In my opinion it's definitely better to use third-party components to achieve this behavior if it's desired. Please don't implement this feature as default behavior in JSF because we will end up then with a third-party component again. In this case with PreserveEditableValues (opposite of ResetEditableValues)

Thanks.
Oleg.

@glassfishrobot
Copy link
Author

@arjantijms said:
Related discussion on the expert mailing list: http://java.net/projects/javaserverfaces-spec-public/lists/jsr344-experts/archive/2012-03/message/51

I'm not 100% sure for a pressing need for configurability in the AJAX case.

  • If a component is explicitly or implicitly targeted to be re-rendered (via the f:ajax render attribute), then it should be reset.
  • If the user wants to preserve values for some component, then this component should simply not be targeted for a re-render.

Yet another implementation of a reset listener: ResetInputAjaxActionListener.java

With quite a few implementations of the same concept out there and a recurring number of questions on this topic at e.g. the PrimeFaces forum and StackOverflow, I hope this can be considered for standardization.

@glassfishrobot
Copy link
Author

ova2 said:
Hi Arjan,

Thanks for your reply. Saidly, but the default behavior, you described, doesn't satisfy all use cases. Imagine a component like PrimeFaces Wizard or PrimeFaces Extensions MasterDetail (you already know them). They render itself. Imagine

<h:panelGroup id="rootElement">
... // some UI mask with input fields, buttons, etc.
</h:panelGroup>

span / div element with id="rootElement" gets re-rendered while masks are switched. All UI masks are placed below the element with id="rootElement". You don't even need any wizard like components. You can just include masks dynamically via <ui:include src="#

{myBean.currentMaskPath}

"/> and re-render <h:panelGroup id="rootElement">. Now imagine you have a select box in a mask "ABC" and want to show details to any selected item by click on one small icon next to the select box. Detail infos are placed in the mask "XYZ". You have to change masks, that means re-render the root element above. Right? But you want to be able to go back from the mask "XYZ" to the "ABC" and see your last input values. Last input values in the mask "ABC" should not go lost during switching (we have e.g. templates with 100+ fields). And what now? You can not switch masks by f:ajax process="rootElement" because if validation fails you can't go to the next mask. Validation should be ignored in this case. You can't switch masks by f:ajax process="@none" because input values will not be saved as submitted values. You should use immediate="true". immediate="true" allows to skip validation and preserve last input values.

You see, we re-render and process an area and all values inside of this area should not be reseted. This was one use case. By another use case when you save the current mask, the same area gets re-rendered and processed again, but all values inside of this area should be reseted. I hope I could describe the problem understandable. Thanks.

P.S. By the way, in your ResetInputAjaxActionListener.java if you visit all components with visitTree in order to find editable value holders, reject visiting for not rendered components first. Something like

if (!target.isRendered())

{ return VisitResult.REJECT; }

I have a big experience with such kind of reseting. We figured out that if you have a DataTable with rendered="false" and you visit it, it's value gets evaluated - all DataTable rows are re-evaluated during iteration. This behavior has a big impact on performance. Not rendered components are not needed to be visited. Good luck.

@glassfishrobot
Copy link
Author

@BalusC said:
ova2: re your PS, check the value of VISIT_HINTS constant.

@glassfishrobot
Copy link
Author

ova2 said:
@BalusC: oh, cool, nice. thanks for hints (overlooked them).

@glassfishrobot
Copy link
Author

kito75 said:
I think it's definitely important that this be optional, as ova2 mentioned. There are some cases where form validation has failed, the form is being re-rendered via Ajax, and the user sees a validation error. Often in that case, you want to keep the old values. The use-case where you're more likely to want them reset is when you're only updating one or two fields in the form dynamically, or if you're performing an action that requires refreshing all of the fields (such as navigating to another record).

@glassfishrobot
Copy link
Author

@BalusC said:
@KiTo: the reset won't be performed when the input field is included in "execute" attribute which is normally the case if you explicitly need to process it. So I don't see your concern. Only when the input field is not included in "execute" but is included in "render", then a reset makes completely sense, otherwise you just wouldn't have included it in the "render".

@glassfishrobot
Copy link
Author

Marked as duplicate on Monday, November 5th 2012, 8:17:56 pm

@glassfishrobot
Copy link
Author

This issue was imported from java.net JIRA JAVASERVERFACES_SPEC_PUBLIC-1060

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants