Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

p:commandButton update doesn't work in ui:include

I want to update a part of a page by PPR. This is the part of page that i want to update:

 <h:panelGroup id="aggiungiAuto"
                  rendered="#{!autoBean.operazioneOk}">
        <ui:include src="../component/aggiungi_auto.xhtml"/>
 </h:panelGroup>

While this is the commandButton present in aggiungi_auto.xhtml

 <p:commandButton value="Submit"
                  update="growl aggiungiAuto aggiungiFoto"
                  actionListener="#{autoBean.insert}"/>

Any Idea?

like image 543
Roberto de Santis Avatar asked Dec 27 '10 18:12

Roberto de Santis


2 Answers

JS/Ajax works on the client side, not on the server side. JSF works on the server side, not on the client side. When you instruct JSF to not render the component to HTML, then nothing will be present in the client side, so JS/Ajax will be unable to locate the HTML element to refresh/update.

You need to wrap it in another <h:panelGroup>.

<h:panelGroup id="aggiungiAuto">
    <h:panelGroup rendered="#{!autoBean.operazioneOk}">
        <ui:include src="../component/aggiungi_auto.xhtml"/>
    </h:panelGroup>
</h:panelGroup>

This way the <span id="aggiuniAuto"> is always present in the client side, so JS/Ajax will be able to update it with the new HTML data generated by JSF.

like image 156
BalusC Avatar answered Oct 18 '22 14:10

BalusC


So I was having this kind of a problem with PrimeFaces (the above answer not being sufficient this time), and I also discovered a solution.

Part of the problem I think was that I was using ui:include recursively. For whatever reason, PrimeFaces was irrationally causing UI components to be bound to the backend data out-of-sync; e.g., when an "Add" button was clicked, a new value would be created in the UI, but then the data for it would be ripped out of the values for the section below, etc...


The explanation? "[O]n a viewscoped bean, a hidden field is added to the form to hold post-back data[;] if that field is not included with the process, then the bean will lose context." This particular problem is prevalent with ui:include recursion especially. Solution (all regarding the p:commandButton or other actionable component):

  • Ensure that update and process are pointing to a JSF component, not a regular HTML component.
  • update the next scope up if it breaks (goes out-of-sync with the binding).
  • Use styleClass's for update (not e.g. PF ID's or @this:@parent kind of stuff), so that jQuery is utilized instead of PF, e.g.: @(.fieldset-class).
  • process whatever scope is being updated. (This is needed for the post-back data so that the Bean keeps its context for the update...) process="@this" is not needed here, provided that the button is contained by the process value component.
  • For all buttons without validation wanted, set immediate="true".
  • If none of the above works (which happened with the Add buttons, probably due to ui:include recursion), set process="@this", immediate="true", and update="@none", and then oncomplete="remoteCommandName();", and have a p:remoteCommand instead with that name with the process, immediate, and update mentioned in the above points.
  • If none of the above works (which happened with some other buttons, probably due to being yet another layer deeper in the ui:include recursion)... wrap a h:panelGroup around the next c:forEach up and then update the PrimeFaces ID of that in the button itself while keeping its remoteCommand call afterwards, as specified above.
  • If none of the above works (which happened yet again to me)... Try the following code:
    • In the p:commandButton(s): oncomplete="$('.FixButtonSC').click();"
    • In the p:fieldset with a style class of FieldsetSC:
          <!-- Fix (hidden) button. -->
          <p:commandButton id="FixButton" styleClass="FixButtonSC"
            process="@this" update="@(.FieldsetSC)" style="display: none;" />

Hope that helps...

like image 39
Andrew Avatar answered Oct 18 '22 13:10

Andrew