javaserverfaces-spec-public
  1. javaserverfaces-spec-public
  2. JAVASERVERFACES_SPEC_PUBLIC-1060

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

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Duplicate
    • Affects Version/s: 2.0
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      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.

        Issue Links

          Activity

          Hide
          ova2 added a comment -

          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.

          Show
          ova2 added a comment - 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.
          Hide
          balusc added a comment -

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

          Show
          balusc added a comment - ova2: re your PS, check the value of VISIT_HINTS constant.
          Hide
          ova2 added a comment -

          @balusc: oh, cool, nice. thanks for hints (overlooked them).

          Show
          ova2 added a comment - @balusc: oh, cool, nice. thanks for hints (overlooked them).
          Hide
          kito75 added a comment -

          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).

          Show
          kito75 added a comment - 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).
          Hide
          balusc added a comment - - edited

          @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".

          Show
          balusc added a comment - - edited @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".

            People

            • Assignee:
              Ed Burns
              Reporter:
              balusc
            • Votes:
              12 Vote for this issue
              Watchers:
              12 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: