Reputation: 333
I am using <p:accordionPanel dynamic="true">
on my page. When submitting the page the attributes of not-loaded-objects get null-values applied. I don't want this behaviour, as the values are correct in DB and on server-side. Why does not showing them in Browser results in nulling them on the server-side. I think this values shouldn't be applied, because they have not been rendered.
My xhtml (snippet):
<p:accordionPanel dynamic="true" value="#{controller.selectedObject.list}" var="listItem">
<p:selectOneMenu value="#{list.market}" disabled="#{controller.selectedObject.isDisabled}">
<f:selectItems value="#{marketSelectItems.selectItems}" />
</p:selectOneMenu>
</p:accordionPanel>
Assuming controller.selectedObject.list
contains two entries of BeanA
where both have a filled property market
.
Now when having controller.selectedObject.isDisabled
set to true my log states:
10:21:12,565 TRACE [de.bss.dm.kairos.gui.phaselistener.AnyPhaseListener:25] UPDATE_MODEL_VALUES 4 before Phase
10:21:12,577 TRACE [de.bss.dm.kairos.gui.phaselistener.AnyPhaseListener:20] UPDATE_MODEL_VALUES 4 after Phase
And everything works fine, the values stay assigned.
But when having controller.selectedObject.isDisabled
set to false my log states:
10:21:51,210 TRACE [de.bss.dm.kairos.gui.phaselistener.AnyPhaseListener:25] UPDATE_MODEL_VALUES 4 before Phase
10:21:51,228 INFO [stdout] (default task-46) setMarket(de.mypackage.Market@2ed)
10:21:51,251 INFO [stdout] (default task-46) setMarket(null)
10:21:51,265 TRACE [de.bss.dm.kairos.gui.phaselistener.AnyPhaseListener:20] UPDATE_MODEL_VALUES 4 after Phase
resulting in persisting wrong values in DB, loosing information.
When i open the second p:accordionPanel
-Tab, resulting in loading data, all is fine, the second BeanA
-Object is assigned the correct Market
-Object.
HTML when not working:
<div class="ui-accordion ui-widget ui-helper-reset ui-hidden-container" role="tablist" data-widget="widget_generalForm_instrumentDetailTabs_listingpanel">
<h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-state-active ui-corner-top" role="tab" aria-expanded="true">
headertext loremipsum
</h3>
<div id="generalForm:instrumentDetailTabs:listingpanel:0:listingtab" class="ui-accordion-content ui-helper-reset ui-widget-content" role="tabpanel" aria-hidden="false">
<div>loaded CONTENT
</div>
</div>
<h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-top" role="tab" aria-expanded="false">
headertext loremipsum
</h3>
<div id="generalForm:instrumentDetailTabs:listingpanel:1:listingtab" class="ui-accordion-content ui-helper-reset ui-widget-content ui-helper-hidden" role="tabpanel" aria-hidden="true">
</div>
<input type="hidden" id="generalForm:instrumentDetailTabs:listingpanel_active" name="generalForm:instrumentDetailTabs:listingpanel_active" value="0">
</div>
After clicking on second tab (or having dynamic="false"
)
<div class="ui-accordion ui-widget ui-helper-reset ui-hidden-container" role="tablist" data-widget="widget_generalForm_instrumentDetailTabs_listingpanel">
<h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-state-active ui-corner-top" role="tab" aria-expanded="true">
headertext loremipsum
</h3>
<div id="generalForm:instrumentDetailTabs:listingpanel:0:listingtab" class="ui-accordion-content ui-helper-reset ui-widget-content" role="tabpanel" aria-hidden="false">
<div>loaded CONTENT
</div>
</div>
<h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-top" role="tab" aria-expanded="false">
headertext loremipsum
</h3>
<div id="generalForm:instrumentDetailTabs:listingpanel:1:listingtab" class="ui-accordion-content ui-helper-reset ui-widget-content ui-helper-hidden" role="tabpanel" aria-hidden="true">
<div>loaded CONTENT OF TAB 2!!!
</div>
</div>
<input type="hidden" id="generalForm:instrumentDetailTabs:listingpanel_active" name="generalForm:instrumentDetailTabs:listingpanel_active" value="0">
</div>
Setting dynamic="false"
on p:accordionPanel
also results in correct behaviour, though I can't use it. The accordionPanels contain a lot of components, resulting in page-size of >1MB when controller.selectedObject.list contains about 15 items.
How should I deal with this Problem? Why are my values updated though they are not rendered/loaded?
Version information: Primefaces 5.0, WildFly 8.1.0.Final
Upvotes: 1
Views: 365
Reputation: 333
I found a workaround by adding process="@this @(.myfakeclass)"
to my p:commandButton
and using
<p:outputPanel styleClass="myfakeclass">
. This results in HTML <div>
elements styled by a class that doesn't exist. In non-loaded panels this class is not rendered, thus not processed.
I still think it is a bug in Primefaces.
Upvotes: 1
Reputation: 1779
This is a known bug in primefaces. I experience it in version 3.4.1 and I've been unable to upgrade from that due to other bugs. It's possible it has been fixed since then as you don't say which version you're using.
There are two workarounds I use. For small components, I set dynamic="false" and if necessary hide the component in the html until needed. For larger components, I put a null check in the setter and make sure the value can never be legitimately set to null.
Upvotes: 0